SpringCloud学习之二:客户端负载均衡Spring Cloud Ribbon
一、什么是Spring Cloud Ribbon
Spring CLoud Bibbon是基于HTTP和TCP的客户端负载均衡工具,基于NetFlix Ribbon实现,通过Spring Cloud的封装,将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。虽然只是一个工具类框架,不像服务注册中心、配置中心、网关等需要单独部署,但是他几乎存在于每一个Spring Cloud构建的微服务和基础设施中。
二、客户端负载均衡
负载均衡是对系统高可用、网络压力的缓解和处理能力扩容的重要手段之一。通常所说的负载均衡是服务端的负载均衡,分为硬件负载均衡和软件负载均衡,硬件比如F5,软件比如nginx等。
服务端负载均衡可用图表示:
服务端硬件负载均衡设备或者软件负载均衡软件都会维护一个下挂可用的服务端清单,通过心跳检测剔除故障节点,客户端发起请求时,按照某种规则(线性轮询、权重负载、流量负载等)从维护的可用服务端清单选取一个进行请求转发。
客户端负载均衡与服务端负载均衡最大的不同点在于服务清单的存储位置,在客户端负载均衡中,所有客户端节点维护着自己要访问的服务端清单,而这些清单来自服务注册中心。
三、Ribbon实例
- 服务提供者
上一节的eureka-provider添加controller:
@RestController
public class ProviderSvc {
@Value("${version}")
private String version;
@GetMapping("/sendMsg")
public String sendMsg(String msg) throws UnknownHostException {
InetAddress inet = InetAddress.getLocalHost();
String address = inet.getHostAddress();
if (StringUtils.isNotBlank(msg)) {
return version + " : " + msg;
}
return version + " : no msg : " + address;
}
}
启动eureka-server,在启动eureka-provider。
然后在idea添加两个server,通过-Dserver.port=9101 -Dversion=2
来更改端口号和序号
- 服务消费者
新建ribbon-demo工程,添加依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ribbon-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ribbon-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml:
server:
port: 9300
spring:
application:
name: ribbon-demo
eurekaserver:
host: localhost
port: 9100
eureka:
client:
serviceUrl:
defaultZone: http://${eurekaserver.host}:${eurekaserver.port}/eureka/
启动类:
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonDemoApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonDemoApplication.class, args);
}
}
controller:
@RestController
public class RibbonSvc {
@Resource
RestTemplate restTemplate;
@GetMapping("/send")
public String sendMsg(String msg){
return restTemplate.getForObject("http://EUREKA-PROVIDER/sendMsg?msg="+msg,String.class);
// return "send";
}
}
运行ribbon-demo工程,访问eureka-server注册中心,可以看到服务都已注册
浏览器访问http://localhost:9300/send?msg=f,多点几次可以看到返回不同序号的信息
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
