- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Spring Cloud調用Ribbon的步驟
Ribbon集成在spring-cloud-starter-netflix-eureka-client中,可以參考。在此基礎上簡(jiǎn)單修改一下,就可以完成服務(wù)調用及負載均衡
首先,將其加入到IOC容器中。@LoadBalanced表示開(kāi)啟負載均衡。
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
@Slf4j @RestController @RequestMapping("/order") public class OrderController { @Autowired RestTemplate restTemplate; // 在ioc容器中獲取 @Value("${payment.url}") String paymentUrl; // 遠程調用的URL,保存在配置文件中,解耦 @GetMapping("/payment/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) { CommonResult<Payment> result = restTemplate.getForObject(paymentUrl + "/payment/get/" + id, CommonResult.class); // get方法調用,并且返回封裝成 CommonResult 類(lèi)型 log.info("Order 查詢(xún) Payment,id:" + id); return result; } }
也可以使用getForEntity()方法,獲取整個(gè)響應,自己在響應中獲取想要的內容。
@GetMapping("/payment/getEntity/{id}") public CommonResult<Payment> getPaymentEntityById(@PathVariable("id") Long id) { ResponseEntity<CommonResult> entity = restTemplate.getForEntity(paymentUrl + "/payment/get/" + id, CommonResult.class); log.info("獲取到的信息是:" + entity.toString()); log.info("獲取到的StatusCode是:" + entity.getStatusCode()); log.info("獲取到的StatusCodeValue是:" + entity.getStatusCodeValue()); log.info("獲取到的Headers是:" + entity.getHeaders()); if (entity.getStatusCode().is2xxSuccessful()) { log.info("查詢(xún)成功:" + id); return entity.getBody(); } else { log.info("查詢(xún)失?。? + id); return new CommonResult<>(CommonResult.FAIlURE, "查詢(xún)失敗"); } }
如果使用post方法,就將get改成post就好了。
url,可以寫(xiě)具體的地址,表示直接調用該地址;也可以寫(xiě)在eureka的服務(wù)名,首先在eureka中獲取該服務(wù)的所有地址,再通過(guò)LB選擇一個(gè)。
payment: url: "http://CLOUD-PAYMENT-SERVICE"
上面通過(guò)@LoadBalanced開(kāi)啟了負載均衡。默認使用輪詢(xún)算法,也可以修改成其他算法。
如果想讓該算法只針對某個(gè)服務(wù),則不能將其放在ComponentScan夠得到的地方,否則會(huì )修改所有服務(wù)的負載均衡算法。因此,最好在外面再新建一個(gè)package,用來(lái)放這個(gè)LB
@Configuration public class MyRule { @Bean public IRule rule() { return new RandomRule(); } }
在主啟動(dòng)類(lèi)上,標識一下服務(wù)與算法直接的映射關(guān)系
@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MyRule.class) public class OrderApplication80 { public static void main(String[] args) { SpringApplication.run(OrderApplication80.class, args); } }
如果嫌這種方法麻煩,也可以使用配置文件的方法
CLOUD-PAYMENT-SERVICE: # 服務(wù)名稱(chēng) ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 算法選擇
以默認的RoundRobinRule作為閱讀的源碼,其他的源碼基本上很類(lèi)似,只是修改的選擇服務(wù)器的代碼。
public interface IRule { Server choose(Object var1); // 選擇服務(wù)器,最重要的方法 void setLoadBalancer(ILoadBalancer var1); ILoadBalancer getLoadBalancer(); }
基本沒(méi)什么作用,只是將公共的部分提取了出來(lái)進(jìn)行實(shí)現。
public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware { private ILoadBalancer lb; // ILoadBalancer接口,主要的功能就是獲取當前服務(wù)器的狀態(tài)、數量等,為負載均衡算法提供計算的參數 public AbstractLoadBalancerRule() { } public void setLoadBalancer(ILoadBalancer lb) { this.lb = lb; } public ILoadBalancer getLoadBalancer() { return this.lb; } }
簡(jiǎn)單來(lái)說(shuō),就是通過(guò)一個(gè)計數器,實(shí)現了輪詢(xún)
public class RoundRobinRule extends AbstractLoadBalancerRule { private AtomicInteger nextServerCyclicCounter; // 原子類(lèi),用來(lái)保存一個(gè)計數,記錄現在輪詢(xún)到哪了 private static final boolean AVAILABLE_ONLY_SERVERS = true; private static final boolean ALL_SERVERS = false; private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class); public RoundRobinRule() { this.nextServerCyclicCounter = new AtomicInteger(0); // 初始化 } public RoundRobinRule(ILoadBalancer lb) { // 設置LoadBalancer this(); this.setLoadBalancer(lb); } public Server choose(ILoadBalancer lb, Object key) { // 最重要的方法,選擇服務(wù)器并返回 // 下面貼出來(lái) } private int incrementAndGetModulo(int modulo) { // 對計數器進(jìn)行修改,并返回一個(gè)選擇值,是輪詢(xún)算法的實(shí)現 // 下面貼出來(lái) } public Server choose(Object key) { // 接口的方法,在該類(lèi)中調用了另一個(gè)方法實(shí)現 return this.choose(this.getLoadBalancer(), key); } public void initWithNiwsConfig(IClientConfig clientConfig) {} }
簡(jiǎn)單來(lái)說(shuō),該方法就是根據目前的狀態(tài),選擇一個(gè)服務(wù)器返回。
public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { // 如果沒(méi)有LoadBalancer,那就不白費功夫了 log.warn("no load balancer"); return null; } else { Server server = null; int count = 0; while(true) { if (server == null && count++ < 10) { // 嘗試十次,如果還找不到server就放棄了 List<Server> reachableServers = lb.getReachableServers(); // 通過(guò)LB獲取目前所有可獲取的服務(wù)器 List<Server> allServers = lb.getAllServers(); // 獲取實(shí)際上的所有服務(wù)器 int upCount = reachableServers.size(); // 獲取目前可獲得的服務(wù)器數量 int serverCount = allServers.size(); // 所有服務(wù)器的數量,這是取余的除數 if (upCount != 0 && serverCount != 0) { // 如果目前有服務(wù)器且服務(wù)器可用 int nextServerIndex = this.incrementAndGetModulo(serverCount); // 最關(guān)鍵的選擇算法,將目前的的服務(wù)器數量放進(jìn)去,返回一個(gè)選擇的號碼 server = (Server)allServers.get(nextServerIndex); // 根據下標將服務(wù)器取出來(lái) if (server == null) { // 如果取出來(lái)為空,表示目前不可用,則進(jìn)入下一個(gè)循環(huán) Thread.yield(); } else { if (server.isAlive() && server.isReadyToServe()) { // 如果該服務(wù)器活著(zhù)且可以被使用,則直接將其返回 return server; } server = null; } continue; } log.warn("No up servers available from load balancer: " + lb); return null; } if (count >= 10) { log.warn("No available alive servers after 10 tries from load balancer: " + lb); } return server; } } }
簡(jiǎn)單來(lái)說(shuō),就是將目前的計數器+1取余,獲取一個(gè)下標,并返回。為了避免高并發(fā)的危險,采用CAS的方法進(jìn)行設置。
private int incrementAndGetModulo(int modulo) { int current; int next; do { current = this.nextServerCyclicCounter.get(); // 獲取當前值 next = (current + 1) % modulo; // +1取余 } while(!this.nextServerCyclicCounter.compareAndSet(current, next)); // CAS,如果成功就返回,失敗就再來(lái) return next; }
以上就是Spring Cloud調用Ribbon的步驟的詳細內容,更多關(guān)于Spring Cloud調用Ribbon的資料請關(guān)注腳本之家其它相關(guān)文章!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站