Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。
代码下载:SpringCloud-Ribbon
一. Ribbon默认算法
- 修改vlluviaCloud-provider-dept-8001 的 application.yml
server:
port: 8001
spring:
application:
name: vlluviacloud-perosn
eureka:
client: #客户端注册进eureka服务列表内
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka1:7001/eureka/,http://eureka2:7002/eureka/,http://eureka3:7003/eureka/
instance:
instance-id: vlluiaecloud-dept8001
prefer-ip-address: true #访问路径可以显示IP地址
- 修改 vlluviaCloud-provider-dept-8002 的 application.yml
server:
port: 8002
spring:
application:
name: vlluviacloud-person
eureka:
client: #客户端注册进eureka服务列表内
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka1:7001/eureka/,http://eureka2:7002/eureka/,http://eureka3:7003/eureka/
instance:
instance-id: vlluiaecloud-dept8002
prefer-ip-address: true #访问路径可以显示IP地址
- 修改 vlluviaCloud-provider-dept-8003 的 application.yml
server:
port: 8003
spring:
application:
name: vlluviacloud-person
eureka:
client: #客户端注册进eureka服务列表内
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka1:7001/eureka/,http://eureka2:7002/eureka/,http://eureka3:7003/eureka/
instance:
instance-id: vlluiaecloud-dept8003
prefer-ip-address: true #访问路径可以显示IP地址
- 修改 vlluviaCloud-consumer-dept-80 的 pom.xml ,添加如下代码
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
-
修改 vlluviaCloud-consumer-dept-80 的 ConfigBean 类 ,添加如下代码
-
修改vlluviaCloud-consumer-dept-80 的PersonController类 ,添加如下代码
-
按顺序运行项目,然后访问 http://localhost:7001/
vlluviaCloud-eureka-7001
vlluviaCloud-eureka-7002
vlluviaCloud-eureka-7003
vlluviaCloud-provider-dept-8001
vlluviaCloud-provider-dept-8002
vlluviaCloud-provider-dept-8003
-
运行项目vlluviaCloud-consumer-dept-80,然后访问http://localhost/consumer/person/gets
第一次访问(效果可能不一):
第二次访问:
第三次访问:
二. 更改算法与自定义算法
-
更改算法
a) 修改vlluviaCloud-consumer-dept-80 的ConfigBean 类
-
自定义算法
a)于vlluviaCloud-consumer-dept-80 创建包 com.vlluvia.myrulea
原因:ConsumerApplication 类里@SpringBootApplication 默认扫描当前默认路径下的所有包
b) com.vlluvia.myrule 创建MySelfRule 类
c) com.vlluvia.myrule 创建MyRandomRule类
public class MyRandomRule extends AbstractLoadBalancerRule
{
// total = 0 // 当total==5以后,我们指针才能往下走,
// index = 0 // 当前对外提供服务的服务器地址,
// total需要重新置为零,但是已经达到过一个5次,我们的index = 1
//
private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
private int currentIndex = 0; // 当前提供服务的机器号
public Server choose(ILoadBalancer lb, Object key)
{
if (lb == null) {
return null;
}
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) {
/*
* No servers. End regardless of pass, because subsequent passes only get more
* restrictive.
*/
return null;
}
// int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
// server = upList.get(index);
// private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
// private int currentIndex = 0; // 当前提供服务的机器号
if(total < 5)
{
server = upList.get(currentIndex);
total++;
}else {
total = 0;
currentIndex++;
if(currentIndex >= upList.size())
{
currentIndex = 0;
}
}
if (server == null) {
/*
* The only time this should happen is if the server list were somehow trimmed.
* This is a transient condition. Retry after yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key)
{
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig)
{
// TODO Auto-generated method stub
}
}
d) 修改ConsumerApplication 类