上篇SpringCloud系列(四)——Ribbon负载均衡介绍了Ribbon负载均衡,都是理论性的东西,接下来用代码实现一下。
- 新建一个简单的Springboot项目——ribbon-service,然后编写一个方法,开启两个端口启动项目。
@RequestMapping(value = "/person", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public Person getPerson(HttpServletRequest request){
Person p = new Person();
p.setId(1);
p.setName("小米");
p.setMessage(request.getRequestURL().toString());
return p;
}
- 新建一个简单的maven项目,通过简单的main方法访问ribbon-service:
public static void main(String[] args) throws Exception {
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.listOfServers", "localhost:8080,localhost:8081");
RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
HttpRequest request = HttpRequest.newBuilder().uri(("/person")).build();
for(int i = 0;i<10;i++){
HttpResponse response = client.executeWithLoadBalancer(request);
String json = response.getEntity(String.class);
System.out.println(json);
}
}
- 输出,可以看到Ribbon的默认策略就是RoundRobinRule(轮换):
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
- 接下来自定义策略,新建一个类,实现IRule,重写choose():
public class MyRule implements IRule {
private ILoadBalancer lb;
public Server choose(Object key) {
Random r= new Random();
int num = r.nextInt(10);
List<Server> servers = lb.getAllServers();
if(num > 7){
return getServerByPost(servers,8081);
}else{
return getServerByPost(servers,8080);
}
}
private Server getServerByPost(List<Server> servers,int port){
for(Server s:servers){
if(s.getPort() == port){
return s;
}
}
return null;
}
public void setLoadBalancer(ILoadBalancer lb) {
this.lb=lb;
}
public ILoadBalancer getLoadBalancer() {
return this.lb;
}
}
- main方法使用MyRule策略:
ConfigurationManager.getConfigInstance().setProperty(
"my-client.ribbon.NFLoadBalancerRuleClassName", MyRule.class.getName());
- 测试,可以看到,调用8080端口比8081端口的多:
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8080/person"}
{"id":1,"name":"小米","message":"http://localhost:8081/person"}