一、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
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
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控制器中输出结果。
会发现访问是轮询访问的。