ribbon实现负载均衡和自定义算法
Posted Roam-G
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ribbon实现负载均衡和自定义算法相关的知识,希望对你有一定的参考价值。
Ribbon是什么?
-
Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具(80是客户端)
-
简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 的客户端组件提供一系列完整的配置项,如:连接超时、重试等。简单的说,就是在配置文件中列出 LoadBalancer (简称LB:负载均衡) 后面所有的及其,Ribbon 会自动的帮助你基于某种规则 (如简单轮询,随机连接等等) 去连接这些机器。我们也容易使用 Ribbon 实现自定义的负载均衡算法!
Ribbon能干嘛?
-
LB,即负载均衡 (LoadBalancer) ,在微服务或分布式集群中经常用的一种应用。
-
负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高用)。
-
常见的负载均衡软件有 nginx、Lvs 等等。
-
Dubbo、SpringCloud 中均给我们提供了负载均衡,SpringCloud 的负载均衡算法可以自定义。
-
负载均衡简单分类:
-
集中式LB
-
即在服务的提供方和消费方之间使用独立的LB设施,如Nginx(反向代理服务器),由该设施负责把访问请求通过某种策略转发至服务的提供方!
-
-
进程式 LB
-
将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
-
Ribbon 就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址!
-
-
ribbon实现负载均衡
1-配置pom
<!-- ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<!-- eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2-配置 客户端
··
server:
port: 80
# eureka配置
eureka:
client:
register-with-eureka: false #不向Eureka注册自己,
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3- 启动类文件配置类 实现负载均衡
package springcloud;
import MyRule.AndyRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
/**Ribbon and eureka 整合以后,
*客户端可以直接调用,不用关心ip地址和端口号--
* */
@SpringBootApplication
@EnableEurekaClient
//在微服务启动的时候就能去加载 我们自定义的ribbon类
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = AndyRule.class)
public class DeptConsumer_80
public static void main(String[] args)
SpringApplication.run(DeptConsumer_80.class,args);
4-把固定地址 修改为 动态地址
package springcloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import pojo.Dept;
import java.util.List;
@RestController
public class DeptConsumerController
// 消费者不应该有service层
// Restful RestTemplate --提供我们调用,注册到spring就可以了
// 重要的三个参数 (url,实体:map,Class<T> responseType)
@Autowired
private RestTemplate restTemplate;
// 提供多种便捷访问远程http服务的方法,简单的restful服务模板
// Ribbon,这里的地址应该是一个变量,通过服务名【SPRINGCLOUD-PROVIDER-DEPT】来访问
// private static final String REST_URL_PREFIX="http://localhost:8001";
private static final String REST_URL_PREFIX="http://SPRINGCLOUD-PROVIDER-DEPT";
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept)
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,boolean.class);
@RequestMapping("/consumer/dept/get/id")
public Dept get(@PathVariable("id") Long id)
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
@RequestMapping("/consumer/dept/list")
public List<Dept> list()
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
运行获取数据
自定义算法
Intellij IDEA的Search Everwhere
查找资料非常方便,默认的快捷键是双击Shift键
搜索Java内部类 快捷键:shift+shift 搜索 IRule 类
重写随机实现类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package MyRule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
//import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class AndyRandomRule extends AbstractLoadBalancerRule
private int total;//某服务运行的总次数
private int currentIndex;//当前从哪一个服务获取数据
public AndyRandomRule()
@SuppressWarnings("RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
public Server choose(ILoadBalancer lb, Object key)
if (lb == null)
return null;
else
Server server = null;
while (server == null)
if (Thread.interrupted())
return null;
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0)
return null;
// int index = this.chooseRandomInt(serverCount);//生成随机数
// server = (Server)upList.get(index);
// 自定义,每个服务执行5次, 共有3个服务。 *************
if (total<5)
server = upList.get(currentIndex);
total++;
else
total =1;
currentIndex++;
if (currentIndex >= upList.size())
currentIndex=0;
server = upList.get(currentIndex);
// **********
if (server == null)
Thread.yield();
else
if (server.isAlive())
return server;
server = null;
Thread.yield();
return server;
protected int chooseRandomInt(int serverCount)
return ThreadLocalRandom.current().nextInt(serverCount);
public Server choose(Object key)
return this.choose(this.getLoadBalancer(), key);
public void initWithNiwsConfig(IClientConfig clientConfig)
使用自己定义的策略
package MyRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AndyRule
@Bean
public IRule myRule()
// return new AndyRandomRule();
return new AndyRandomRule();//使用自定义的策略
以上是关于ribbon实现负载均衡和自定义算法的主要内容,如果未能解决你的问题,请参考以下文章
springCloud:Ribbon实现客户端侧负载均衡-消费者整合Ribbon