Spring Cloud Ribbon:负载均衡
# 5.Spring Cloud Ribbon:负载均衡
在微服务架构中,一个服务通常会部署多个实例以提高系统的可靠性和可用性。然而,传统方式调用一个服务却需要先获取服务实例列表,再选择一个实例进行调用,这个过程既繁琐又复杂,尤其是在选择合适的实例时。为了简化这一过程,Spring Cloud 提供了Ribbon 组件。
# 1. Ribbon的简介
Ribbon是Netflix开源的项目,后被整合到了Spring Cloud中。它提供了客户端负载均衡的功能,可以将面向服务的REST请求转换为负载均衡的服务调用,无需显式导入 spring-cloud-starter-netflix-ribbon
。Ribbon基于HTTP和TCP,并几乎存在于每个Spring Cloud构建的微服务和基础设施中。微服务间的调用和API网关的请求转发等都是通过Ribbon实现的。Feign也是基于Ribbon实现的工具。因此,了解和使用Spring Cloud Ribbon对于构建微服务至关重要。Ribbon客户端提供了丰富的配置选项,如连接超时、重试等。可以通过在配置文件中列出所有机器的方式来配置Ribbon,它会根据规则(如简单轮询、随机等)自动连接这些机器。同时,我们也可以轻松地实现自定义的负载均衡算法。
# 2. 负载均衡的介绍
负载均衡(Load Balancer)是一种用来平衡服务器负载的技术。在一个服务被大量请求访问时,负载均衡器可以将这些请求分发到多台服务器上,以确保每台服务器的负载相对均衡,避免某台服务器负载过高而影响整体性能。这样可以提高系统的可用性、稳定性和性能。
负载均衡器可以分为两种类型:
集中式负载均衡器(Centralized Load Balancer):在服务的消费方和提供方之间有独立的负载均衡设施,负载均衡器负责将请求通过某种策略分发给服务提供方。常见的集中式负载均衡器有硬件负载均衡器(如F5)和软件负载均衡器(如Nginx)。
进程内负载均衡器(Process-Embedded Load Balancer):负载均衡逻辑集成在服务消费方,消费方从注册中心获取可用的服务地址列表,然后自行选择合适的服务器。Spring Cloud Ribbon 就属于进程内负载均衡器,它是一个类库,集成在服务消费方的进程中,用于根据一定的规则选择服务提供方。
Nginx是服务器的负载均衡,客户端所有的请求都会交给Nginx,然后由Nginx实现转发请求,即负载均衡是由服务端实现的。而Ribbon本地负载均衡是在调用服务接口时,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。
# 3.代码实现
# 3.1 修改服务提供者接口
为了更好地模拟负载均衡,我们修改服务提供者 cloud-service1
的接口,使其返回当前服务的IP地址和端口号:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.net.InetAddress;
import java.net.UnknownHostException;
@RestController
public class HelloController {
@Value("${server.port}")
private int port;
@RequestMapping(value = "/service1/hello", method = RequestMethod.GET)
public String hello() throws UnknownHostException {
// 获取当前服务的IP地址
String ip = InetAddress.getLocalHost().getHostAddress();
// 将IP地址和端口号组合成返回字符串
return "Hello Spring Cloud, from IP: " + ip + ", port: " + port;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 3.2启动多个服务实例
为了模拟负载均衡的效果,我们启动 cloud-service
服务的多个实例,具体操作可以参考https://www.jianshu.com/p/7df01a8036ca。可以在控制台看到不同的端口号,也可以在 Eureka 注册中心看到多个实例。
# 3.3 修改消费者RestTemplate配置
为了启用负载均衡功能,我们需要为消费者创建一个 ApplicationContextConfig
类,在其中使用 @LoadBalanced
注解为 RestTemplate
bean 启用负载均衡功能:
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
2
3
4
5
6
7
8
# 3.4 修改消费者的服务调用
修改消费者的服务调用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/service2/hello")
public String helloController() {
return restTemplate.getForObject("http://cloud-service1/service1/hello", String.class);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3.5 重启消费者服务
启动服务并访问接口,多请求几次你会发现端口不同,每次调用服务时,RestTemplate
会根据负载均衡策略选择一个合适的服务实例进行调用,从而实现了负载均衡的效果。
Hello Spring Cloud, from IP: 192.168.137.1, port: 8082
Hello Spring Cloud, from IP: 192.168.137.1, port: 8081
Hello Spring Cloud, from IP: 192.168.137.1, port: 8080
2
3
# 4. 总结
Spring Cloud Ribbon是一个强大的负载均衡工具,可以帮助我们简化微服务架构中的服务调用过程,提高系统的可靠性和可用性。通过Ribbon,我们可以轻松实现基于客户端的负载均衡,从而更好地管理服务间的通信,保证系统的稳定运行。至于关于ribbon的一些其他知识自行查阅。