SpringCloud之Ribbon的基础使用

发布于:2022-12-25 ⋅ 阅读:(190) ⋅ 点赞:(0)

功能:

​ 将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,从而协同完成工作任务;同时提供客户端负载均衡算法和服务调用

​ Ribbon作为消费者服务的负载均衡器,有两种使用方式,一种是和RestTemplate相结合,另一种是和OpenFeign相结合,OpenFeign已经默认集成了Ribbon

注意:

  1. Ribbon使用位置,处于各个服务之间的调用方来配置Ribbon
  2. 被调用的服务集群,主机名不能带有"_"符号

使用:

pom文件:

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

第一种:

​ 使用LoadBalancerClient对象来调用其他服务;LoadBalancerClient对象底层集成了DiscoveryClient对象,底层通过轮询算法来获取对应的连接实例对象

package com.mmy.controller;

@RestController
public class FindController {

    //注入LoadBalancerClient,其持有ribbon提供的负载均衡算法
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    /*
      处理/find2的请求并传参serverName -- 值给服务(应用)名称service-a;
      然后响应字符串文本给客户端;
     */
    @RequestMapping("/find2")
    public String find2(String serverName){

        //调用ribbon提供的负载均衡算法拿到服务实例
        ServiceInstance instance = loadBalancerClient.choose(serverName);

        //拿到服务实例的IP和端口
        String ip = instance.getHost();
        int port = instance.getPort();

        //拼接出请求url -- service-a服务的/info请求的url
        String url = "http://"+ip+":"+port+"/info";

        //发出请求,并接收service-a服务的/info请求响应的字符串文本
        String result = restTemplate.getForObject(url, String.class);

        //将接收的service-a服务的/info请求响应的字符串文本再响应给客户端
        return result;
    }
}

第二种:

​ 借助ribbon来实现调用服务

//第一步:给将RestTemplate注入IOC容器的方法上添加注解@LoadBalanced
//配置RestTemplate的bean对象到容器,使用其可以发送请求
    @Bean
    //标注@LoadBalanced注解,表示让ribbon来管理RestTemplate
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
//第二步:
@RestController
public class FindController {

    //注入RestTemplate,用其发送请求
    @Autowired
    private RestTemplate restTemplate;


    /*
      处理/find3的请求并传参serverName -- 值给服务(应用)名称service-a;
      然后响应字符串文本给客户端;
     */
    @RequestMapping("/find3")
    public String find3(String serverName){
        //组装url -- 协议之后不需要ip和端口,直接拼接服务名,ribbon会通过负载均衡算法处理
        String url = "http://"+serverName+"/info";

        //发出请求,并接收service-a服务的/info请求响应的字符串文本
        String result = restTemplate.getForObject(url, String.class);

        //将接收的service-a服务的/info请求响应的字符串文本再响应给客户端
        return result;
    }
}
遇到的bug:
java.lang.IllegalStateException: Request URI does not contain a valid hostname
原因:spring.application.name=ribbon_client;被调用方的主机名中不能带有下划线(”_”)负号

实现机制:

1)拦截请求

2)获取请求的url地址:http://服务名/info

3)截取url地址中的服务名

4)从服务列表中找到该名称的服务的实例集合(服务发现)

5)根据负载均衡算法选出一个实例(默认也是轮询算法)

6)拿到该实例的ip和port,替换原来url中的服务名

7)发送真正的请求:restTemplate.getForObject(“url”, String.class)

Ribbon提供的负载均衡算法:

  1. RoundRobinRule:轮询,请求次数%机器数量。
  2. RandomRule:随机。
  3. AvailabilityFilteringRule:会先过滤掉由于多次访问故障处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对于剩余的服务列表按照轮询的策略进行访问。
  4. WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越大。刚启动时如果同统计信息不足,则使用轮询的策略,等统计信息足够会切换到自身规则。
  5. RetryRule:先按照轮询的策略获取服务,如果获取服务失败则在指定的时间内会进行重试,获取可用的服务
  6. BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量小的服务。
  7. ZoneAvoidanceRule:默认算法,区间内轮询;复合判断服务所在地理区域的性能和服务的可用性来选择服务。

Ribbon负载均衡算法的修改方式:

第一种:修改访问指定服务使用的算法

#service-a被访问的服务名称;值负载均衡算法实现类的完整类路径
服务名.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

第二种:修改访问所有服务使用的算法

	//配置IRule接口的具体的实现类的bean对象到容器
    @Bean
    public IRule myRule() {
        //指定访问所有服务都使用此算法
        return new RandomRule();
    }

通过将IRule的实现类注入IOC中,覆盖默认的轮询算法,达到更换负载均衡算法的目的


网站公告

今日签到

点亮在社区的每一天
去签到