客户端负载均衡:客户端会有一个服务器地址列表,在发送请求前经过负载均衡算法选择一个服务器,而后进行访问。html
ribbon客户端需配合zuul使用。git
# zuul 配置 zuul: routes: custom: # route key, 随意,不重复便可 path: /target/page/** # 路由表达式 serviceId: customId # 客户端id stripPrefix: false # 路由时保留 表达式前缀 # ribbon ribbon: eureka: enabled: false #不使用注册中心
ribbon生成服务列表时,只会保留服务器地址+端口的信息,会忽略掉后面的路径,故zuul配置stripPrefix=true
保留前缀以便路由到正确的地址。github
# ribbon 客户端,名字与zuul里serverId保持一致 customId: ribbon: # 服务端列表 listOfServers: http://localhost:8081,http://localhost:8081
优势:经过简单的配置,无需多余的代码便可生成客户端,适合于客户端服务列表稳定,且负载均衡不需特别定制的状况。算法
缺点:客户端负载使用ribbon默认的实现方式,不能知足特定的场景。spring
spring cloud 容许咱们经过注解配置来定制化客户端,需去掉配置文件中关于ribbon客户端的配置。服务器
@Configuration @RibbonClient(name = "customId", configuration = CustomConfiguration.class) public class TestConfiguration { }
一个名为 customId 的客户端将被生成,此配置不能被主运用程序上下文扫描到,需放到单独的包中(笔者猜想配置多个客户端的状况下可能形成配置数据共享问题)。负载均衡
class CustomConfiguration{ @Bean public IRule ribbonRule() { return new BestAvailableRule(); } @Bean public IPing ribbonPing() { return new PingUrl(); } @Bean public ServerList<Server> ribbonServerList(){ //配置服务列表 Server[] serveArray = new Server[3]; serveArray[0] = (new Server("localhost", 9999)); ServerList<Server> serverServerList = new StaticServerList<>(serveArray); return serverServerList; } @Bean public ServerListSubsetFilter serverListFilter() { ServerListSubsetFilter filter = new ServerListSubsetFilter(); return filter; } }
优势:经过少量的代码,解决了负载均衡中特殊需求的定制化问题。ide
缺点:解决不了动态改变客户端服务列表难题。源码分析
ribbon在负载均衡中选择服务须要读取客户端的服务列表信息,可经过clientId获取负载均衡器并改变相关的配置信息,但ribbon的刷新机制默认是从配置中读取数据,服务列表中的数据会被快速的替换掉。若咱们实现按需改变listOfServers
的配置,便可达到动态刷新客户端服务列表的目的。spa
archius 的做用即为动态改变配置。
public static void createRibbonClient(){ //设置:配置项 (ribbon 会读取此配置) //根据 archaius 动态配置的特性 , 服务列表更新时只需从新赋值便可 ConfigurationManager.getConfigInstance().setProperty(CLIENT_ID + ".ribbon.listOfServers", LIST_SERVERS); // 获取客户端, 若不存在则建立 ClientFactory.getNamedClient(CLIENT_ID); // 负载均衡服务 DynamicServerListLoadBalancer serverListLoadBalancer = (DynamicServerListLoadBalancer) ClientFactory.getNamedLoadBalancer(CLIENT_ID); //根据需求定制化负载属性: //轮询方式、 Rule、 Ping 等 //serverListLoadBalancer.setPing(new PingUrl()); }
Client Side Load Balancer: Ribbon
Spring Cloud源码分析(二)Ribbon
Archaius