简介
ribbon是一种客户端的负载均衡,客户端会维护一个服务清单,在请求发送之前,在本地通过负载均衡算法选择一个服务进行访问。
nginx是一种服务器端的负载均衡,即请求发送到服务器端,由服务器端进行转发,例如nginx转发到两个tomcat上。
在创建ribbon模块之前先修改一下前面讲到的eureka-client-8003,eureka-client-8004两个模块,分别添加一个方法,供我们后续调用访问。
@RestController
public class EurekaClient8003Controller {
@RequestMapping("/sayHello")
public String sayHello(){
return "Hello,这里是EurekaClient8003客户端";
}
}
--------------------------------------------------------------
@RestController
public class EurekaClient8004Controller {
@RequestMapping("/sayHello")
public String sayHello(){
return "Hello,这里是EurekaClient8004客户端";
}
}
创建Ribbon模块
创建一个ribbon-client-8005模块,添加pom依赖:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.top</groupId>
<artifactId>spring-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ribbon-client-8005</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ribbon-client-8005</name>
<description>Ribbon客户端8005</description>
<packaging>jar</packaging>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加配置,ribbon同样需要向服务中心注册服务
server:
port: 8005
spring:
application:
name: ribbon-client
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/
在启动类上添加@EnableEurekaClient注解,标明这是一个eureka客户端
RestTemplate是用来发送请求的,@LoadBalanced表明这个RestTemplate开启负载均衡功能,默认使用轮训算法
@EnableEurekaClient
@SpringBootApplication
public class RibbonClient8005Application {
public static void main(String[] args) {
SpringApplication.run(RibbonClient8005Application.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
接着创建一个方法去调用我们上面添加的sayHello方法,这里可能你已经发现了,我们是通过服务名eureka-client去访问,不是传统的ip:port的方式去访问。ribbon模块会从注册中心拉取服务清单,通过服务名去对应IP地址,然后通过指定的负载均衡算法去选择一个IP访问。
@RestController
public class RibbonClient8005Controller {
//用于发起请求
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getString")
public void getString(){
//通过服务名去调用
System.out.println(restTemplate.getForEntity("http://eureka-client/sayHello/", String.class).getBody());
}
}
我们启动ribbon,访问这个方法 http://localhost:8005/getString,可以看到请求被发到两个客户端,这里ribbon使用的是默认的轮训负载均衡算法
那么如何来修改ribbon使用的负载均衡算法呢?
直接在启动类中注入一个bean ,IRule ,然后创建你想使用的轮训策略的实例就可以了,这里使用的是RandomRule,随机策略
@EnableEurekaClient
@SpringBootApplication
public class RibbonClient8005Application {
public static void main(String[] args) {
SpringApplication.run(RibbonClient8005Application.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public IRule iRule(){
return new RandomRule();
}
}
接着重新访问方法 http://localhost:8005/getString,会看到现在使用的是随机策略
看一下我们的注册中心 http://localhost:8001/
最后简单介绍几种负载均衡算法
1.轮询(Round Robin):一个替一个访问,使用synchronized,这将会导致该段轮询代码的并发吞吐量发生明显的下降。
2.随机算法:通过一定范围的随机数来分发请求给相应的tomcat.当请求量很大时,其实就很接近轮询了
3.源地址哈希:通过请求来源的IP计算相应的hashCode和服务器数量进行取模,最终来分发给相应的Tomcat,只要IP不发生变动请求分发的Tomcat也就固定了
源地址哈希法的优点在于:保证了相同客户端IP地址将会被哈希到同一台后端服务器。根据此特性可以在服务消费者与服务提供者之间建立有状态的session会话,一旦有服务器上线、下线那么服务器数量改变,所有的都会映射失败。
4.加权轮询:在轮询的基础上增加权重,权重假如说是1:2,那么发送1号机子上1次,发送2号机子上就是2次
5.加权随机法(Weight Random):跟加权轮询类似一样的做法 ,那么tomcat随机分发的时候分发的几率就增大
6.最小连接数法:根据后端服务器当前的连接情况,动态的选取当前积压连接数最少的一台服务器来处理当前请求。
相关阅读
项目代码
SpringCloud 汇总【Greenwich 版】
SpringCloud(一):Eureka注册中心【Greenwich 版】
SpringCloud(二):Ribbon负载均衡【Greenwich 版】
SpringCloud(三):Feign声明式服务调用【Greenwich 版】
SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】
SpringCloud(五):Hystrix的请求熔断与服务降级【Greenwich 版】
SpringCloud(六):Hystrix的请求合并【Greenwich 版】
SpringCloud(七):Hystrix仪表盘与Turbine集群监控【Greenwich 版】
SpringCloud(八):Zuul网关【Greenwich 版】
SpringCloud(九):Config配置中心【Greenwich 版】
SpringCloud(十):Bus消息总线【Greenwich 版】
SpringCloud(十一):Stream消息驱动 + RabbitMQ【Greenwich 版】
SpringCloud(十二):Sleuth链路跟踪【Greenwich 版】