Spring Cloud Ribbon是基于Netflix Ribbon實(shí)現(xiàn)的一套客戶端負(fù)載均衡的工具讶泰。它是一個(gè)基于HTTP和TCP的客戶端負(fù)載均衡器。它可以通過(guò)在客戶端中配置ribbonServerList來(lái)設(shè)置服務(wù)端列表去輪詢?cè)L問(wèn)以達(dá)到均衡負(fù)載的作用痪署。
當(dāng)Ribbon與Eureka聯(lián)合使用時(shí),ribbonServerList會(huì)被DiscoveryEnabledNIWSServerList重寫狼犯,擴(kuò)展成從Eureka注冊(cè)中心中獲取服務(wù)實(shí)例列表领铐。同時(shí)它也會(huì)用NIWSDiscoveryPing來(lái)取代IPing宋舷,它將職責(zé)委托給Eureka來(lái)確定服務(wù)端是否已經(jīng)啟動(dòng)。
而當(dāng)Ribbon與Consul聯(lián)合使用時(shí)音诈,ribbonServerList會(huì)被ConsulServerList來(lái)擴(kuò)展成從Consul獲取服務(wù)實(shí)例列表绎狭。同時(shí)由ConsulPing來(lái)作為IPing接口的實(shí)現(xiàn)。
Ribbon作為后端負(fù)載均衡器儡嘶,比Nginx更注重的是承擔(dān)并發(fā)而不是請(qǐng)求分發(fā),可以直接感知后臺(tái)動(dòng)態(tài)變化來(lái)指定分發(fā)策略誓篱。它一共提供了7種負(fù)載均衡策略:
策略名 | 策略聲明 | 策略描述 | 實(shí)現(xiàn)說(shuō)明 |
---|---|---|---|
BestAvailableRule | public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule | 選擇一個(gè)最小的并發(fā)請(qǐng)求的server | 逐個(gè)考察Server鸥咖,如果Server被tripped了兄世,則忽略,在選擇其中ActiveRequestsCount最小的server |
AvailabilityFilteringRule | public class AvailabilityFilteringRule extends PredicateBasedRule | 過(guò)濾掉那些因?yàn)橐恢边B接失敗的被標(biāo)記為circuit tripped的后端server御滩,并過(guò)濾掉那些高并發(fā)的的后端server(active connections 超過(guò)配置的閾值) | 使用一個(gè)AvailabilityPredicate來(lái)包含過(guò)濾server的邏輯,其實(shí)就就是檢查status里記錄的各個(gè)server的運(yùn)行狀態(tài) |
WeightedResponseTimeRule | public class WeightedResponseTimeRule extends RoundRobinRule | 根據(jù)響應(yīng)時(shí)間分配一個(gè)weight富弦,響應(yīng)時(shí)間越長(zhǎng)氛驮,weight越小,被選中的可能性越低盏缤。 | 一個(gè)后臺(tái)線程定期的從status里面讀取評(píng)價(jià)響應(yīng)時(shí)間蓖扑,為每個(gè)server計(jì)算一個(gè)weight唉铜。Weight的計(jì)算也比較簡(jiǎn)單responsetime 減去每個(gè)server自己平均的responsetime是server的權(quán)重律杠。當(dāng)剛開(kāi)始運(yùn)行竞惋,沒(méi)有形成status時(shí)灰嫉,使用roubine策略選擇server。 |
RetryRule | public class RetryRule extends AbstractLoadBalancerRule | 對(duì)選定的負(fù)載均衡策略機(jī)上重試機(jī)制胰挑。 | 在一個(gè)配置時(shí)間段內(nèi)當(dāng)選擇server不成功椿肩,則一直嘗試使用subRule的方式選擇一個(gè)可用的server |
RoundRobinRule | public class RoundRobinRule extends AbstractLoadBalancerRule | roundRobin方式輪詢選擇server | 輪詢index,選擇index對(duì)應(yīng)位置的server |
RandomRule | public class RandomRule extends AbstractLoadBalancerRule | 隨機(jī)選擇一個(gè)server | 在index上隨機(jī)郑象,選擇index對(duì)應(yīng)位置的server |
ZoneAvoidanceRule | public class ZoneAvoidanceRule extends PredicateBasedRule | 復(fù)合判斷server所在區(qū)域的性能和server的可用性選擇server | 使用ZoneAvoidancePredicate和AvailabilityPredicate來(lái)判斷是否選擇某個(gè)server厂榛,前一個(gè)判斷判定一個(gè)zone的運(yùn)行性能是否可用,剔除不可用的zone(的所有server)击奶,AvailabilityPredicate用于過(guò)濾掉連接數(shù)過(guò)多的Server。 |
Ribbon中支持的負(fù)載均衡策略
驗(yàn)證實(shí)現(xiàn):
1湃望、自定義負(fù)載均衡策略
# 自定義負(fù)載均衡策略
springboot-h2.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule // 自定義使用隨機(jī)策略,springboot-h2是服務(wù)應(yīng)用名
2痰驱、修改調(diào)用代碼
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.chhliu.springboot.restful.vo.User;
@RestController
public class RestTemplateController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/template/{id}")
public User findById(@PathVariable Long id) {
ServiceInstance serviceInstance = this.loadBalancerClient.choose("springboot-h2");
System.out.println("===" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":"
+ serviceInstance.getPort());// 打印當(dāng)前調(diào)用服務(wù)的信息
User u = this.restTemplate.getForObject("http://springboot-h2/user/" + id, User.class);
System.out.println(u);
return u;
}
}