Ribbon 負(fù)載均衡機(jī)制分析
這一小結(jié)分析Ribbon的機(jī)制
默認(rèn)規(guī)則獲取服務(wù)器
- 定義Ribbon負(fù)載均衡器對(duì)象 ILoadBalancer
//負(fù)載均衡器對(duì)象
ILoadBalancer loadBalancer = new BaseLoadBalancer();
- 定義服務(wù)器列表,是要將哪些服務(wù)器交與Ribbon以實(shí)現(xiàn)負(fù)載均衡
//準(zhǔn)備服務(wù)器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
- 將服務(wù)器列表交與Ribbon
//將服務(wù)器列表加載到負(fù)載均衡器
loadBalancer.addServers(serverList);
- 從Ribbon負(fù)載均衡器中獲取服務(wù)器對(duì)象
for (int i = 0; i < 10; i++) {
Server server = loadBalancer.chooseServer(null);
System.out.println(server);
}
- 完整代碼如下:
package person.jack.ribbon.client;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerBuilder;
import com.netflix.loadbalancer.Server;
import java.util.ArrayList;
import java.util.List;
public class LBTest {
@Test
public void testBalancer() {
//負(fù)載均衡器對(duì)象
ILoadBalancer loadBalancer = new BaseLoadBalancer();
//準(zhǔn)備服務(wù)器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
//將服務(wù)器列表加載到負(fù)載均衡器
loadBalancer.addServers(serverList);
for (int i = 0; i < 10; i++) {
Server server = loadBalancer.chooseServer(null);
System.out.println(server);
}
}
}
- 運(yùn)行main 函數(shù),控制臺(tái)打印如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
localhost:8081
localhost:8080
可知,負(fù)載均衡器選擇服務(wù)器是以輪詢的方式!
自定義規(guī)則獲取服務(wù)器
- 定義類實(shí)現(xiàn) com.netflix.loadbalancer.IRule 接口,讓8080調(diào)用的概率只有10%,完整代碼如下:
package person.jack.ribbon.rule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.Random;
public class MyRule implements IRule {
private ILoadBalancer lb;
//負(fù)載均衡器選擇服務(wù)器
@Override
public Server choose(Object key) {
int n = new Random().nextInt(10) + 1;
if(n<2){
return getServerByPort(8080);
}
return getServerByPort(8081);
}
//工具方法,根據(jù)端口獲取服務(wù)器
private Server getServerByPort(int port){
List<Server> serverList = lb.getAllServers();
for (Server server : serverList) {
if(server.getPort()==port){
return server;
}
}
return null;
}
//設(shè)置負(fù)載均衡器
@Override
public void setLoadBalancer(ILoadBalancer lb) {
this.lb=lb;
}
//獲取負(fù)載均衡器
@Override
public ILoadBalancer getLoadBalancer() {
return this.lb;
}
}
- 測(cè)試方法
Rule對(duì)象要運(yùn)行需要 ILoadBalancer 對(duì)象以獲取服務(wù)器:
MyRule rule=new MyRule();
rule.setLoadBalancer(lb);
將rule對(duì)象交與ILoadBalancer:
lb.setRule(rule);
方法完整代碼如下:
@Test
public void testRule() {
//負(fù)載均衡器對(duì)象
BaseLoadBalancer lb = new BaseLoadBalancer();
MyRule rule=new MyRule();
rule.setLoadBalancer(lb);
lb.setRule(rule);
//準(zhǔn)備服務(wù)器列表
List<Server> serverList = new ArrayList<Server>();
serverList.add(new Server("localhost", 8080));
serverList.add(new Server("localhost", 8081));
//將服務(wù)器列表加載到負(fù)載均衡器
lb.addServers(serverList);
for (int i = 0; i < 10; i++) {
Server server = lb.chooseServer("key");
System.out.println(server);
}
}
- 運(yùn)行測(cè)試方法,控制臺(tái)運(yùn)行如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
localhost:8080
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
localhost:8081
# 8080 被調(diào)用的概率明顯降低,測(cè)試成功
以上就是對(duì)負(fù)載均衡器的使用與測(cè)試
使用自定義規(guī)則
- 了解了負(fù)載均衡器的調(diào)用邏輯,接下來就是如何將自定義的規(guī)則應(yīng)用到Ribbon客戶端調(diào)用,需配置:NFLoadBalancerRuleClassName,指定規(guī)則的類名實(shí)現(xiàn):
ConfigurationManager.getConfigInstance().setProperty("myClient.ribbon.NFLoadBalancerRuleClassName",MyRule==.class.getName());
完整代碼如下:
@Test
public void testMyRuleBalancer() throws Exception {
ConfigurationManager.getConfigInstance().setProperty(
"myClient.ribbon.listOfServers", "localhost:8080,localhost:8081");
ConfigurationManager.getConfigInstance().setProperty(
"myClient.ribbon.NFLoadBalancerRuleClassName",
MyRule.class.getName());
RestClient client = (RestClient) ClientFactory.getNamedClient("myClient");
HttpRequest request = HttpRequest.newBuilder().uri("/info").build();
for (int i = 0; i < 10; i++) {
HttpResponse response = client.executeWithLoadBalancer(request);
String json = response.getEntity(String.class);
System.out.println(json);
}
}
- 運(yùn)行以上測(cè)試方法,控制臺(tái)打印如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8080/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
springBoot 是javaWEB開發(fā)最優(yōu)美的姿勢(shì)!http://localhost:8081/info
# 已經(jīng)未采用輪詢規(guī)則來調(diào)用服務(wù)器,使用的是我們自定義的規(guī)則
Ribbon 內(nèi)置的幾種規(guī)則 Common rules:
- RoundRobinRule(默認(rèn))
輪詢
- AvailabilityFilteringRule
過濾掉那些因?yàn)橐恢边B接失敗的被標(biāo)記為circuit tripped的后端server,并過濾掉那些高并發(fā)的的后端server(active connections 超過配置的閾值)
- WeightedResponseTimeRule
根據(jù)相應(yīng)時(shí)間分配一個(gè)weight,相應(yīng)時(shí)間越長,weight越小,被選中的可能性越低。
- ZoneAvoidanceRule
復(fù)合判斷server所在區(qū)域的性能和server的可用性選擇server
- BestAvailableRule
選擇一個(gè)最小的并發(fā)請(qǐng)求的server
- RandomRule
隨機(jī)選擇一個(gè)server
- RetryRule
對(duì)選定的負(fù)載均衡策略機(jī)上重試機(jī)制。