一、简介
Ribbon是netflix公司的一个负载均衡框架,负载均衡就是分发请求,缓解单台服务器压力。
二、Ribbon hello world
这篇文章主要通过写一个简单Ribbon程序,来了解一下Ribbon的原理。
第一个Ribbon程序包括以下内容:
- 2个简单的服务,端口分别为1001和1002
- 1个client程序用来向服务器发送请求,测试负载均衡的效果
1.首先,新建项目Ribbon-service
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>
2.配置文件(这一步是为了启动两个不同端口的服务)
application.properties
spring.profiles.active=dev
#spring.profiles.active=pro
application-dev.properties:
server.port=1001
application-pro.properties:
server.port=1002
3.服务实现(这里返回RequestURL是为了区分请求的服务器):RibbonServiceControl.java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class RibbonServiceControl {
@RequestMapping("hello")
public String helloWorld(HttpServletRequest request){
return "Hello World Ribbon--"+request.getRequestURL();
}
}
4.最后是sprongBoot启动程序:Application.java
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
5.新建项目:Ribbon-client
直接写一个测试类:
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.niws.client.http.RestClient;
public class test {
public static void main(String[] args) throws Exception {
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.listOfServers", "localhost:1001,localhost:1002"); //设置服务列表
RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
HttpRequest request = HttpRequest.newBuilder().uri("/hello").build();
for(int i = 0; i < 10; i++) {
HttpResponse response = client.executeWithLoadBalancer(request);
String json = response.getEntity(String.class);
System.out.println(json);
}
};
}
6.最后,先启动2个服务,再执行测试类,可以看到如下效果,说明默认的负载均衡规则就是轮询。
7.当然,我们也可以修改负载均衡的规则
可选的策略如下:
策略类型 | 描述 |
---|---|
RoundRobinRule | 这条规则简单地通过循环法选择服务器。它通常用作默认规则 |
BestAvailableRule | 选择一个最小的并发请求的server |
AvailabilityFilteringRule | 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) |
WeightedResponseTimeRule | 根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。 |
RetryRule | 对选定的负载均衡策略机上重试机制。 |
RandomRule | 随机选择一个server |
ZoneAvoidanceRule | 复合判断server所在区域的性能和server的可用性选择server |
那么,我们如何修改策略呢?
只需要修改5的测试代码即可:
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.niws.client.http.RestClient;
public class test {
public static void main(String[] args) throws Exception {
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.listOfServers", "localhost:1001,localhost:1002"); //设置服务列表
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.NFLoadBalancerRuleClassName", AvailabilityFilteringRule.class.getName()); //设置负载均衡规则
RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
HttpRequest request = HttpRequest.newBuilder().uri("/hello").build();
for(int i = 0; i < 10; i++) {
HttpResponse response = client.executeWithLoadBalancer(request);
String json = response.getEntity(String.class);
System.out.println(json);
}
};
}
8.当然,我们也可以自定义负载均衡规则,只需要实现IRule 接口即可:
import java.util.Random;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
public class Myrule implements IRule {
private ILoadBalancer lb;
public Server choose(Object key) { //自定义规则
Random rm = new Random();
int number = rm.nextInt(10);
if(number < 2) {
return lb.getAllServers().get(0);
}else {
return lb.getAllServers().get(1);
}
}
public void setLoadBalancer(ILoadBalancer lb) {
this.lb=lb;
}
public ILoadBalancer getLoadBalancer() {
// TODO Auto-generated method stub
return this.lb;
}
}
然后测试类修改如下:
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.niws.client.http.RestClient;
/**
* @author:
* @description:
* @program: ribbon_service
* @create: 2018-06-22 11:39
**/
public class test {
public static void main(String[] args) throws Exception {
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.listOfServers", "localhost:1001,localhost:1002"); //设置服务列表
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.NFLoadBalancerRuleClassName", Myrule.class.getName()); //自定义负载均衡规则
RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
HttpRequest request = HttpRequest.newBuilder().uri("/hello").build();
for(int i = 0; i < 10; i++) {
HttpResponse response = client.executeWithLoadBalancer(request);
String json = response.getEntity(String.class);
System.out.println(json);
}
};
}