5.Ribbon

通过上面的学习,我们知道eureka可以实现多服务之间的相互注册调用但是多个"相同服务"之间又该怎么管理呢?

经过以上的学习,已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过HTTP的形式
将信息注册到注册中心,并且可以通过SpringCloud提供的工具获取注册中心的服务列表。但是服务之
间的调用还存在很多的问题,如何更加方便的调用微服务,多个微服务的提供者如何选择,如何负载均
衡等。

 Ribbon概述

什么是Ribbon

是 Netflflixfa 发布的一个负载均衡器,有助于控制 HTTP 和 TCP客户端行为。在 SpringCloud 中,
Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读
取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。
在SpringCloud中可以将注册中心和Ribbon配合使用,Ribbon自动的从注册中心中获取服务提供者的
列表信息,并基于内置的负载均衡算法,请求服务

Ribbon的主要作用

(1)服务调用
基于Ribbon实现服务调用, 是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。借助
RestTemplate 最终进行调用
(2)负载均衡
当有多个服务提供者时,Ribbon可以根据负载均衡的算法自动的选择需要调用的服务地址

基于Ribbon实现订单调用商品服务

不论是基于Eureka的注册中心还是基于Consul的注册中心,SpringCloudRibbon统一进行了封装,所
以对于服务调用,两者的方式是一样的。

 坐标依赖

在springcloud提供的服务发现(eureka)的jar中以及包含了Ribbon的依赖。所以这里不需要导入任何额外的坐标

 工程改造

(1) 服务消费者
修改服务消费者 order_service模块中的启动类OrderApplication ,在创建RestTemplate方法
上添加 @LoadBalanced 注解 :

 

 修改controller代码:

    /**
     * 基于Ribbon的形式调用远程微服务
     * 1.在启动类里面使用@LoadBalanced声明RestTemplate
     * 2.使用服务名替换IP地址
     */
    @RequestMapping(value = "/buybuybuy/{id}", method = RequestMethod.GET)
    public Product findById3(@PathVariable Long id) {
//        Product product = restTemplate.getForObject("http://127.0.0.1:9001/product/findById/1", Product.class);
        Product product = restTemplate.getForObject("http://service-product/product/findById/1", Product.class);
        return product;
    }

服务调用Ribbon高级 

负载均衡概述

在搭建网站时,如果单节点的 web服务性能和可靠性都无法达到要求;或者是在使用外网服务时,经常
担心被人攻破,一不小心就会有打开外网端口的情况,通常这个时候加入负载均衡就能有效解决服务问
题。
负载均衡是一种基础的网络服务,其原理是通过运行在前面的负载均衡服务,按照指定的负载均衡算
法,将流量分配到后端服务集群上,从而为系统提供并行扩展的能力。
负载均衡的应用场景包括流量包、转发规则以及后端服务,由于该服务有内外网个例、健康检查等功
能,能够有效提供系统的安全性和可用性

 

客户端负载均衡与服务端负载均衡

服务端负载均衡
先发送请求到负载均衡服务器或者软件,然后通过负载均衡算法,在多个服务器之间选择一个进行访
问;即在服务器端再进行负载均衡算法分配
客户端负载均衡
客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这
是客户端负载均衡;即在客户端就进行负载均衡算法分配

基于Ribbon实现负载均衡(客户端负载均衡)

Ribbon是一个典型的客户端负载均衡器,Ribbon会获取服务的所有地址,根据内部的负载均衡算法,获取本次请求的有效地址

搭建多服务实例:

1.建立两个商品服务9001,9011;

2.在订单服务中以负载均衡的方式调用商品服务

    @RequestMapping(value = "/buybuybuy/{id}", method = RequestMethod.GET)
    public Product findById3(@PathVariable Long id) {
//        Product product = restTemplate.getForObject("http://127.0.0.1:9001/product/findById/1", Product.class);
        Product product = restTemplate.getForObject("http://service-product/product/findById/1", Product.class);//ribbon已经默认开启负载均衡访问
        return product;
    }

3.通过订单服务访问商品服务:

 

 

 通过上面我们可以发现,ribbon默认会对多个服务进行轮询访问

ribbon负载均衡策略

Ribbon内置了多种负载均衡策略,内部负责复杂均衡的顶级接口为
com.netflix.loadbalancer.IRule ,实现方式如下

com.netflix.loadbalancer.RoundRobinRule :以轮询的方式进行负载均衡。(默认)
com.netflix.loadbalancer.RandomRule :随机策略
com.netflix.loadbalancer.RetryRule :重试策略。
com.netflix.loadbalancer.WeightedResponseTimeRule :权重策略。会计算每个服务的权
重,越高的被调用的可能性越大。
com.netflix.loadbalancer.BestAvailableRule :最佳策略。遍历所有的服务实例,过滤掉
故障实例,并返回请求数最小的实例返回。
com.netflix.loadbalancer.AvailabilityFilteringRule :可用过滤策略。过滤掉故障和请
求数超过阈值的服务实例,再从剩下的实力中轮询调用。
服务消费者的application.yml配置文件中修改负载均衡策略 :
##需要调用的微服务名称
service-product:
 ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
策略选择:
1、如果每个机器配置一样,则建议不修改策略 (推荐)
2、如果部分机器配置强部分配置低,则可以改为 WeightedResponseTimeRule

ribbon请求重试

在负载均衡的时候访问某个服务,如果在指定时间内没有获得响应,那么ribbon会立即重试访问其他节点:

 

 重试配置:

1.消费者引入spring重试依赖

2.在消费者yml文件里对ribbon进行重试配置

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
#ribbon重试机制配置
service-product:
  ribbon:
    ConnectTimeout: 250 # Ribbon的连接超时时间(毫秒)
    ReadTimeout: 1000 # Ribbon的数据读取超时时间(毫秒)
    OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
    MaxAutoRetries: 1 # 对当前(失败)实例的重试次数

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-08-28 00:46  指尖下的世界  阅读(252)  评论(0编辑  收藏  举报
/* 看板娘 */ /*炸泡*/
/* 鼠标点击求赞文字特效 */