erueka+nacos注册管理中心

erueka和nacos的出现起源于微服务

认识微服务:服务架构从单体架构变为微服务架构

单体架构:业务功能全部集中在一个项目中开发

优点:结构简单,易于维护;

部署容易且成本低

缺点:耦合度高,不易拓展

微服务架构:

优点:耦合度低;

升级和服务拓展容易;

缺点:服务调用关系复杂,部署难度高

架构特征:

单一职责:每一个服务对应唯一的业务功能

自治:可分团队开发 各个团队开发不同的业务 不同的数据库 并独立部署交付自己的服务

面向服务:服务提供同一接口,语言和技术可以不相同

隔离性强:暂未理解

这里一个问题引出注册中心:服务与服务之间如何调用,调用关系如何管理

1直接调用:也可以,但实际业务不可能这样实现,耦合度太高,不容易拓展

eg:修改order-service中的根据id查询订单业务,要求在查询订单的同时,根据订单中包含的userId查询出用户信息,一起返回。

因此,我们需要在order-service中 向user-service发起一个http的请求,调用http://localhost:8081/user/{userId}这个接口。

大概的步骤是这样的:

1注册一个RestTemplate的实例到Spring容器
2修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User,

3将查询的User填充到Order对象,一起返回。

在服务调用关系中,会有两个不同的角色

服务提供者:被其他微服务调用的服务。

服务消费者:调用其他微服务的服务。

2引出由某个东西可以统一管理,注册中心的诞生:

Eureka注册中心

引出:orderservice调用userservice时,若纯在多个userservice服务,如何选择ip地址和端口

eg:直接调用变化

启动时:

userservice服务启动后,把自己注册到eureka的server端,orderservice启动后根据服务名称从eureka拉取实例地址列表。

调用多个userservice时:

利用eureka的负载均衡算法选中一个实例地址,发起远程调用

rder-service如何得知某个user-service实例是否依然健康,是不是已经宕机:

user-service会每隔一段时间(默认30秒)向eureka-server发起请求,报告自己状态,称为心跳

当超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除

order-servi拉取服务时,就能将故障实例排除了

注意:一个微服务,可以是提供者,也可以是消费者

搭建eureka注册中心:

1搭建eureka-server微服务(它也是一个微服务)

2cloud-demo导入eureka-server

3导入eureka依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

4编写启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
package cn.itcast.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}

5编写配置文件–》启动微服务,访问:http://127.0.0.1:10086

服务注册:

1在要注册的服务中pom文件中。导eureka-client依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2写配置文件

1
2
3
4
5
6
7
8
9
10
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true #以IP地址注册到服务中心,相互注册使用IP地址,如果不配置就是机器的主机名
instance-id: 127.0.0.1:${server.port} # instanceID默认值为主机名+服务名+端口
演示启动多个user-service实例:可以复制原user-service,改端口(-Dserver.port=8082),即可新增服务启动项

服务发现:

也就是服务拉取

1导依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2配置文件

1
2
3
4
5
6
7
8
9
10
spring:
application:
name: orderservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
instance-id: 127.0.0.1:${server.port}

3添加注解

注解的作用:让server端拉取实例列表,并且实现负载均衡

@LoadBalanced

修改orderservice中的queryOrderById方法:用注册服务名代替ip(spring会自动帮助我们从eureka-server端,根据userservice这个服务名称,获取实例列表,而后完成负载均衡。

Ribbon负载均衡:

Cloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能

底层无非就是一个拦截器,拦截ResTemplate请求

img

饥饿加载:

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

1
2
3
4
5
6
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients:
- userservice # 指定饥饿加载的服务名称
- xxxxservice # 如果需要指定多个,需要这么写

nacos注册中心

国内比较推崇阿里巴巴的技术/dog(华为手机、比亚迪汽车、阿里nacos(国外网都不好访问,不用阿里用谁/dog))

nacos由springcloudalibaba推出饿注册中心

github主页:https://github.com/alibaba/nacos

默认端口:8848钛合金手机

启动方式:在bin目录下用windows窗口运行startup.cmd -m standalone

默认账号密码:nacos

服务注册:

nacos属于cloudalibaba组件,而cloudalibaba遵循cloud定义的服务规范,所以大差不差,就是导入依赖和服务注册地址不同。

1导入父工程依赖:

1
2
3
4
5
6
7
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>

2导入服务依赖:

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3配置文件添加nacos地址:

1
2
3
4
spring:
cloud:
nacos:
server-addr: localhost:8848
服务集群:

就是同一个服务可能有很多的实例,分布不同的位置,不同的位置有不同的实例。

eg:同一个服务在同一个地区(如上海某地一个机房布置了3个相同的服务),即可划分为一个集群。

访问规则:

服务与服务之间相互访问时,尽可能访问同一集群下的服务(注意:默认情况下不能实现相同集群优先,需要配置

配置集群:

1配置文件配置(配置的是提供者的yml,相当于修改的是user-service的)

1
2
3
4
5
6
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ # 集群名称

2启动时配置

-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH

3设置同集群优先负载均衡规则

修改负载均衡规则(修改的是消费者的yml文件,相当于修改的是order-service的)

1
2
3
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
权重配置:

(权重更灵活,也可以实现同集群优先访问)

引出:实际部署多服务实例时会出现:硬件设备性能有差异,性能好的设备应承担更多的请求。

默认情况下,nacoirule是同集群内随机挑选,利用nacos权重配置即可控制访问频率,权重越大的被访问频率越高。

namespace:

不同namespace之间相互隔离,不同namespace的服务互相不可见。

默认一个public空间

给微服务配置namespace:

1点击+新增namespace

2修改服务的yml文件:

1
2
3
4
5
6
7
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ
namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID

重启服务后,访问控制台,即可看到新增namespace

nacos两种实例:
  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。
  • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

配置一个服务实例为永久实例:

1
2
3
4
5
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
nacos与eureka的共同点:

都支持服务注册和服务拉取

都支持服务提供者心跳方式检测

nacos与eureka的区别

nacos支持服务端主动检测状态,临时实例采用心跳模式,非临时采用主动检测模式

nacos临时实例不正常会被剔除,但非临时实例不会被剔除

nacos支持服务列表变更推送,即服务增加时nacos立马被注册上

nacos配置管理:

注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好

Nacos除了可以做注册中心,同样可以做配置管理来使用。当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。还有一个好处就是naocs配置服务可以实现热更新。

这块较为复杂,暂时没研究。