ribbon负载均衡工具

一、Ribbon介绍及原理

1.1 Ribbon介绍

Ribbon是由Netflix公司推出的开源软件,是基于HTTP和TCP协议的,其主要功能是实现客户端软件的负载均衡算法。
Spring Cloud中Ribbon就是基于Netflix公司的Ribbon实现的。它不需要单独部署,但是却存在于整个微服务中。前面学习的Eureka里面有Ribbon,后面学习的OpenFeign也是基于Ribbon实现的。

1.2 Ribbon原理

内部基于ILoadBalancer实现的(代码层面)。
的继承关系如下:
在这里插入图片描述

使用Ribbon工作原理:
所有的项目都会注册到Eureka中,Eureka允许不同项目的spring.application.name是相同。当相同时会认为这些项目一个集群。所以同一个项目部署多次时都是设置应用程序名相同。

Application Client会从Eureka中根据spring.application.name加载Application Service的列表。根据设定的负载均衡算法,从列表中取出一个URL,到此Ribbon的事情结束了。剩下的事情由程序员自己进行技术选型,选择一个HTTP协议工具,通过这个URL调用Application Service。

注意:以下事情和Ribbon没有关系的
Application Service注册到Eureka过程。这是Eureka的功能。
Application Client从Eureka取出注册列表。这是Eureka的功能。
Application Client 通过URL访问Application Service。具体实现可以自己进行选择使用哪个HTTP工具。

只有Application Client从Eureka中取出列表后进行负载均衡算法的过程和Ribbon有关系。

二、负载均衡解决方案分类及特征

业界主流的负载均衡解决方案有:集中式负载均衡和线程内负载均衡。

2.1集中式负载均衡

即在客户端和服务端之间使用独立的负载均衡设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务端。
也叫做:服务器端负载均衡。
在这里插入图片描述

2.2进程内负载均衡

将负载均衡逻辑集成到客户端组件中,客户端组件从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务端发起请求。Ribbon就是一个进程内的负载均衡实现。
也叫做:客户端负载均衡。
在这里插入图片描述

三、微服务架构中Ribbon

在Application Client中配置Ribbon。
微服务架构既然把项目拆分成多个项目,一定会出现项目调用另外一个项目的情况。
在加上Eureka支持多项目同项目名(spring.application.name)所以这个时候就可以使用Ribbon。
项目B和项目C和项目D实际上是一个项目。项目A调用项目B和项目C和项目D,那么Ribbon应该配置在项目A中(Application Client中)
在这里插入图片描述

四、搭建Application Service集群

4.1 搭建eureka单服务(客户端和服务端)及集群可参考该链接:

链接:https://blog.csdn.net/weixin_56219549/article/details/122332342.
启动eureka服务端如下图
在这里插入图片描述

4.2 准备eureka客户端(可参考以上链接)

@RestController
public class DemoController {
    @RequestMapping("/demo")
    public String demo(){
        System.out.println("执行了demo");
        return "testRibbon";
    }
}

启动eureka客户端如下图(这里通过idea配置端口启动三个服务如下图)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启用三个Application为了验证Ribbon的负载均衡效果,在Application Client中通过Ribbon算法调用三个Application中一个。
由于Ribbon是通过服务名称获取Application Service的,所以这三个Application Service的名称一定要相同。
观察Eureka管理页面会发现已经注册了三个eureka-client

五、新建项目基于Ribbon测试负载均衡

5.1 配置pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
</project>

这里可以发现eureka自动集成了ribbon
在这里插入图片描述

5.2 配置yml

spring:
  application:
    name: ribbon-client
server:
  port: 8083

5.3 配置service接口和实现类

public interface ClientService {

    /**
     * @return 返回值类型不是必须和调用的控制器方法返回值一样,需要看页面要什么。
     */
    String client();
}
@Service("ClientServiceImpl")
public class ClientServiceImpl implements ClientService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Override
    public String client() {
        ServiceInstance si = loadBalancerClient.choose("eureka-client");
        // 获取Application Service IP。192.168.1.1
        System.out.println(si.getHost());
        // 获取Ip及端口。192.168.1.1:8081
        System.out.println(si.getInstanceId());
        // 获取额外声明信息.{management.port=8081}
        System.out.println(si.getMetadata());
        // 端口 8081
        System.out.println(si.getPort());
        // 模式 null
        System.out.println(si.getScheme());
        // 应用程序名 eureka-client
        System.out.println(si.getServiceId());
        // URI http://192.168.1.1:8081
        System.out.println(si.getUri().toString());
        return null;
    }
}

5.4 配置controller

@RestController
public class ClientController {
    @Autowired
    @Qualifier(value="ClientServiceImpl")
    private ClientService clientService;

    @RequestMapping("/client")
    public String client(){
        return clientService.client();
    }
}

5.5 配置启动类

@SpringBootApplication
@EnableDiscoveryClient
//@EnableEurekaClient 配置EnableDiscoveryClient和@EnableEurekaClient或者都不配也会默认会注册服务
public class RibbonApplication {

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

}

5.6 运行

运行程序,通过浏览器多次访问项目ApplicationClientDemo中/client控制器,观察IDEA控制器中输出结果。
会发现访问是轮询访问的。
在这里插入图片描述
在这里插入图片描述

六、实现Application Client调用Application Service

上面的例子中是LoadBalance调用Provider的测试。现在实现调用Provider的控制器接口方法。
在Java代码中调用另一个控制器接口,可以使用之前学习的HttpClient实现,在今天的课程中换一种技术实现,基于RestTemplate完成的。

6.1新建配置类

新建RibbonConfig。
注意方法上面要有@LoadBalanced注解。否则Ribbon不生效。

@Configuration
public class RibbonConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getTemplate(){
        return  new RestTemplate();
    }
}

6.2 修改service实现类和controller

注意:
无论使用RestTemplate的哪个方法,方法中URL参数必须使用spring.application.name应用程序名(ServerID)替换原来URL中host(主机)和port(端口)。因为底层Ribbon是根据应用程序名获取注册列表的。

@Service("ClientServiceImpl2")
public class ClientServiceImpl2 implements ClientService {
    @Autowired
    private RestTemplate restTemplate;
    @Override
    public String client() {
        return restTemplate.getForObject("http://eureka-client/demo", String.class);
    }
}
@RestController
public class ClientController {


    @Autowired
    @Qualifier(value="ClientServiceImpl2")
    private ClientService clientService;
//	这里也可以使用@Resource来注入
//    @Resource(name="ClientServiceImpl2")
//    private ClientService clientService;

    @RequestMapping("/client")
    public String client(){
        return clientService.client();
    }
}

6.3运行

运行项目,访问/client控制器,观察IDEA控制台打印的内容。

七、Ribbon支持的负载均衡算法

ribbon的负载均衡策略是通过不同的类型来实现的,下表详细介绍一些常用负载均衡策略及对应的Ribbon策略类。

id策略名称策略对应的类名实现原理
1轮询策略(默认)RoundRobinRule轮询策略表示每次都按照顺序取下一个application service,比如一共有5个application service,第1次取第1个,第2次取第2个,第3次取第3个,以此类推
2权重轮询策略(常用,中小型项目使用)WeightedResponseTimeRule1.根据每个application service的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性越低。2.原理:一开始为轮询策略,并开启一个计时器,每30秒收集一次每个application service的平均响应时间,当信息足够时,给每个application service附上一个权重,并按权重随机选择application service,权重越高的application service会被高概率选中。
3随机策略(不推荐,测试使用,开发一般不使用)RandomRule从application service列表中随机选择一个
4最少并发数策略(应用在硬件软件环境一致的情况下,中小型项目使用)BestAvailableRule选择正在请求中的并发数最小的application service,除非这个application service在熔断中。
5重试策略。在“选定的负载均衡策略”基础上进行重试机制RetryRule1.“选定的负载均衡策略”这个策略是轮询策略RoundRobinRule2.该重试策略先设定一个阈值时间段,如果在这个阈值时间段内当选择application service不成功,则一直尝试采用“选定的负载均衡策略:轮询策略”最后选择一个可用的application service
6可用性敏感策略(一般在同区域内服务集群环境中使用)AvailabilityFilteringRule过滤性能差的application service,有2种:第一种:过滤掉在eureka中处于一直连接失败application service第二种:过滤掉高并发的application service
7区域敏感性策略(应用在大型的,物理隔离分布式环境中)ZoneAvoidanceRule1.以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的application service 2.如果这个ip区域内有一个或多个实例不可达或响应变慢,都会降低该ip区域内其他ip被选中的权重。

八、指定负载均衡策略

8.1 添加bean

在RibbonConfig的配置类中添加。配置类中指定哪个负载均衡策略默认使用哪种策略。不允许配置多个负载均衡策略的实例。

    @Bean
    public RandomRule getRandomRule(){
        return new RandomRule();
    }

8.2 在ApplicationService观察输出语句

测试是否随机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jsxllht

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值