SpringCloud Eureka 服务注册中心3:Ribbon服务消费者

原创
2021/07/03 14:04
阅读数 318

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于 Http Restful 的。Spring Cloud 有两种服务调用方式,一种是Ribbon + RestTemplate消费服务,另一种是 Feign消费服务。这篇我们主要讲解 Ribbon 消费服务。

官网地址:https://docs.spring.io/spring-cloud-netflix/docs/2.2.8.RELEASE/reference/html/#spring-cloud-ribbon

Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡器,它可以在通过客户端中配置的 RibbonServerList 服务端列表去轮询访问以达到均衡负载的作用。当 Ribbon 与 Eureka 联合使用时,Ribbon 的服务实例清单 RibbonServerList 会被 DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务端列表。同时它也会用 NIWSDiscoveryPing 来取代 IPing,它将职责委托给 Eureka 来确定服务端是否已经启动。

高版本中没有找到Ribbon的文档。

 

一、准备工作

1.1、创建启动一个注册中心,二个服务提供者

 请参考:Spring Cloud Eureka 服务注册中心组建1:搭建注册中心

  • piao-server:注册中心服务端,端口2000。
  • piao-client:客户端服务提供者,端口2010。
  • piao-client2:客户端服务提供者,端口2011。

如果不想创建多个项目,可以请考这篇文章:IDEA 启动多个SpringBoot项目不同端口

启动成功如下:

 

二、创建服务消费者

2.1、创建 piao-ribbon 项目。

我们这里使用IDEA创建,文件-》新建-》项目-》下一步到如下的页面:

然后在点下一步,直到完成。

 

2.2、修改依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.piao</groupId>
    <artifactId>piao-ribbon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>piao-ribbon</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

2.3、添加配置

编辑项目的 application.properites 文件,添加如下相关配置:

#服务注册中心端口号
server.port=2005

#指定服务名称
spring.application.name=piao-ribbon
#指定服务注册中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:2000/eureka/

在启动类上添加 @EnableDiscoveryClient 注解。使用@LoadBalanced注解赋予RestTemplate负载均衡的能力。

@EnableDiscoveryClient
@SpringBootApplication
public class PiaoRibbonApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(PiaoRibbonApplication.class, args);
    }

}

Spring Cloud Ribbon 中实现客户端负载均衡的原理简单来说:就是通过 LoadBalancerInterceptor 拦截器对 RestTemplate 的请求进行拦截,并利用 Spring Cloud 的负载均衡器 LoadBalancerClient 将一服务名为 host 的 URI 转换成具体的服务实例地址的过程。

 

2.4、编写一个消费者的请求类

在该接口中,通过前面定义的 RestTemplate 来实现对 PIAO-CLIENT  服务提供的 /client 接口进行负载均衡的调用。

@RestController
public class ConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String helloConsumer() {
        // 通过服务名调用服务提供者的接口
        return restTemplate.getForEntity("http://PIAO-CLIENT/client", String.class).getBody();
    }

}

 

2.5、启动服务并访问

我们访问注册中心地址:http://127.0.0.1:2000/

访问地址:http://127.0.0.1:2005/consumer

第一次访问:

第二次访问:

我们看到了请求分别调用了我们之前准备的 PIAO-CLIENT 接口。实现负载均衡的效果。

Ribbon 输出了当前客户端维护的 IAO-CLIENT 的服务列表情况。其中包含了各个实例的位置,Ribbon 就是按照此信息进行轮训访问,以实现基于客户端的负载均衡。除此之外还输出了一些其他非常有用的信息,如对各个实例的请求总数量、第一次连接信息、上一次连接信息、总的请求失败数量等。

 

三、Ribbon 重试机制

Spring Cloud Eureka 实现的服务治理机制强调了 CAP 原理中的 AP,即可用性与可靠性,牺牲了一定的一致性(在极端情况下它宁愿接受故障实例也不要丢掉"健康"实例)。但不论是由于触发了保护机制还是服务剔除的延迟,引起服务调用到故障实例的时候,我们还是希望能够增强对这类问题的容错。所以,我们在实现服务调用的时候通常会加入一些重试机制。

从 Camden SR2 版本开始,Spring Cloud 就整合了 Spring Retry 来增强 RestTemplate 的重试能力,对于开发者来说只需通过简单的配置,原来那些通过 RestTemplate 实现的服务访问就会自动根据配置来实现重试策略。

3.1、添加依赖

<!-- 重试机制-->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

 

3.2、修改配置

编辑项目的 application.properites 文件,对 ribbon 重试相关参数进行设置。

spring.cloud.loadbalancer.retry.enabled 参数用来开启重试机制,因为默认是 true(开启)。因此只要引入 spring-retry 依赖就可以自动实现重试功能。如果要将其关闭,只要将其设为 false 即可。

全局配置:

#断路器的超时时长需要大于Ribbon的超时时间,不然不会触发重试
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

#请求连接超时时间(毫秒)
ribbon.ConnectTimeout=1000
#请求处理的超时时间(毫秒)
ribbon.ReadTimeout=3000
#对所有请求都进行重试(是否所有操作都重试,若false则仅get请求重试)
ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数
ribbon.MaxAutoRetries=1

指定服务配置:

#断路器的超时时长需要大于Ribbon的超时时间,不然不会触发重试
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

#请求连接超时时间(毫秒)
piao-client.ribbon.ConnectTimeout=1000
#请求处理的超时时间(毫秒)
piao-client.ribbon.ReadTimeout=3000
#对所有请求都进行重试(是否所有操作都重试,若false则仅get请求重试)
piao-client.ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
piao-client.ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数
piao-client.ribbon.MaxAutoRetries=1

配置说明:当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由 MaxAutoRetries 配置),如果不行,就换一个实例进行访问,如果还不行,再换一次实例访问(更换次数由 MaxAutoRetriesNextServer 配置),如果依然不行,返回失败信息。

 

四、配置负载均衡策略

全局配置:

#修改负载均衡算法
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

指定服务配置:

#修改负载均衡算法
piao-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

Ribbon的负载均衡策略:

  • com.netflix.loadbalancer.RandomRule:从提供服务的实例中以随机的方式;
  • com.netflix.loadbalancer.RoundRobinRule:以线性轮询的方式,就是维护一个计数器,从提供服务的实例中按顺序选取,第一次选第一个,第二次选第二个,以此类推,到最后一个以后再从头来过;
  • com.netflix.loadbalancer.RetryRule:在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内,反复使用线性轮询策略来选择可用实例;
  • com.netflix.loadbalancer.WeightedResponseTimeRule:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
  • com.netflix.loadbalancer.BestAvailableRule:选择并发较小的实例;
  • com.netflix.loadbalancer.AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例;
  • com.netflix.loadbalancer.ZoneAwareLoadBalancer:采用双重过滤,同时过滤不是同一区域的实例和故障实例,选择并发较小的实例。
     
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部