3.1Eureka

image-20210713220104956.png
微服务如何得知提供者地址?

  1. 提供者启动,必须立即注册自己的信息到eureka
  2. eureka会保存服务名称及实例ip和端口的映射关系
  3. 消费者去eureka根据服务名称拉取服务实例列表

消费者如何在多个服务中选择一个?
利用组件做负载均衡,挑选一个,Ribbon组件

如何感知服务故障?

  1. 提供者会与eureka维持一个心跳,默认30秒一次
  2. 超时未心跳,就认为服务宕机,就会被剔除

3.1.1搭建Eurekaserver

1)引入eureka-server依赖

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

2)加注解,@EnableEurekaServer

  1. @SpringBootApplication
  2. @EnableEurekaServer
  3. public class EurekaApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(EurekaApplication.class, args);
  6. }
  7. }

3)编写配置,eureka地址、服务名称

  1. server:
  2. port: 10086
  3. spring:
  4. application:
  5. name: eureka-server
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://127.0.0.1:10086/eureka

3.1.2服务注册

1)引入eureka-client依赖

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

2)编写配置,eureka地址、服务名称

  1. spring:
  2. application:
  3. name: userservice
  4. eureka:
  5. client:
  6. service-url:
  7. defaultZone: http://127.0.0.1:10086/eureka

3.1.3服务发现

1)引入eureka-client依赖
2)编写配置,eureka地址、服务名称
3)给RestTemplate加@LoadBalanced注解
image-20210713224049419.png
4)http请求时,用服务名称代替ip和端口

  1. public Order queryOrderById(Long orderId) {
  2. // 1.查询订单
  3. Order order = orderMapper.findById(orderId);
  4. //2.远程查询客户信息
  5. // User user = restTemplate.getForObject("http://localhost:8082/user/" + order.getUserId(), User.class);
  6. User user = restTemplate.getForObject("http://userservice/user/" + order.getUserId(), User.class);
  7. //3.封装客户信息
  8. order.setUser(user);
  9. // 4.返回
  10. return order;
  11. }

3.2Ribbon

3.2.1负载均衡的原理

1)请求被LoadBalancerInterceptor拦截
2)获取uri中的host,也就是服务名称
3)交给RibbonLoadBalanceClient的对象,根据服务名称获取服务列表,保存到DynamicServerListLoadBalancer
4)交给IRule,利用负载均衡规则选择一各实例
5)利用真实实例的ip和端口替换url的服务名称,发起请求
image-20210713224517686.png
SpringCloudRibbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求,对地址做了修改。用一幅图来总结一下:
image-20210713224724673.png

3.2.2负载均衡策略

负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类:
image-20210713225653000.png
不同规则的含义如下:

内置负载均衡规则类 规则描述
RoundRobinRule 简单轮询服务列表来选择服务器。
AvailabilityFilteringRule 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。
WeightedResponseTimeRule 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
ZoneAvoidanceRule 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。
BestAvailableRule 忽略那些短路的服务器,并选择并发数较低的服务器。
RandomRule 随机选择一个可用的服务器。
RetryRule 重试机制的选择逻辑

3.2.3负载均衡策略IRule

默认的实现是ZoneAvoidanceRule,是轮询机制
两种配置IRule方式
1)Bean

 @Bean
 public IRule random(){
        return new RandomRule();
    }

2)yml配置

userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

3.2.4饥饿加载

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

ribbon:
  eager-load:
    enabled: true
    clients: userservice

3.3Nacos

3.3.1服务注册

1)引入nacos-discovery依赖
在cloud-demo父工程的pom文件中的<dependencyManagement>中引入SpringCloudAlibaba的依赖:

<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>

然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2)编写配置,nacos地址、服务名称

spring:
  cloud:
    nacos:
      server-addr: localhost:8848

3.3.2服务发现

1)引入nacos-discovery依赖
2)编写配置,nacos地址、服务名称
3)给RestTemplate加@LoadBalanced注解
4)http请求时,用服务名称代替ip和端口

3.3.3服务分级管理模型

一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例,形成分级模型,如图:
image-20210713232522531.png
NacosRule 路由时就近原则

  • 优先从本集群负载均衡
  • 本集群没有,再去访问其它集群
  • 本集群内部采用随机负载均衡

3.3.4权重配置

本集群内部采用随机负载均衡
值的范围是0~1,权重越大,被访问的频率越高
作用:

  • 针对不同性能的服务器,分配不同的权重
  • 把权重置为0,服务就不会被访问,无缝升级切换

3.3.5环境隔离

Nacos提供了namespace来实现环境隔离功能。

  • nacos中可以有多个namespace
  • namespace下可以有group、service等
  • 不同namespace之间相互隔离,例如不同namespace的服务互相不可见

image-20210714000101516.png

3.3.6nacos和eureka的区别和联系

1)联系

  • 注册发现的整体流程一样,都实现SpringCloudCommon的接口
  • 都基于心跳机制监测提供者的整体
  • 都可以采用服务拉取来获取实例列表

2)区别

  • nacos针对永久实例是采用主动访问机制,临时实例才是心跳机制
  • nacos消费者可以定时拉取服务;nacos还会在服务变更时主动推送服务列表
  • nacos可以是CP,也可以是AP,默认是AP
  • eureka是AP模式,可用性优先