一、運(yùn)行流程
服務(wù)注冊(cè)與發(fā)現(xiàn): 在Spring Cloud微服務(wù)架構(gòu)中,服務(wù)實(shí)例通常會(huì)注冊(cè)到服務(wù)注冊(cè)中心(如Eureka, Consul, Zookeeper等)。這些服務(wù)實(shí)例的信息包括服務(wù)名、主機(jī)名、端口號(hào)等脖岛。
集成Ribbon: Spring Cloud內(nèi)部集成了Netflix Ribbon來(lái)實(shí)現(xiàn)客戶端負(fù)載均衡。Ribbon是一個(gè)客戶端負(fù)載均衡工具颊亮,它可以根據(jù)某種負(fù)載均衡策略(如輪詢柴梆、隨機(jī)等)從一系列服務(wù)實(shí)例中選擇一個(gè)來(lái)發(fā)起調(diào)用。
RestTemplate的定制: 當(dāng)你在RestTemplate上使用@LoadBalanced注解時(shí)终惑,Spring Cloud會(huì)創(chuàng)建一個(gè)特殊的RestTemplate實(shí)例绍在。這個(gè)實(shí)例被自定義為攔截請(qǐng)求,并利用Ribbon來(lái)選擇服務(wù)實(shí)例雹有。
請(qǐng)求攔截: 當(dāng)你使用這個(gè)定制的RestTemplate發(fā)起請(qǐng)求時(shí)偿渡,請(qǐng)求會(huì)被攔截。如果請(qǐng)求的URL使用了服務(wù)名(如http://service-name/path)霸奕,Ribbon會(huì)從服務(wù)注冊(cè)中心獲取該服務(wù)名下的所有可用實(shí)例溜宽。
選擇服務(wù)實(shí)例: Ribbon根據(jù)配置的負(fù)載均衡策略從這些實(shí)例中選擇一個(gè),并將服務(wù)名替換為實(shí)際的主機(jī)名和端口號(hào)质帅,完成服務(wù)實(shí)例的選擇适揉。
發(fā)起實(shí)際調(diào)用: 替換后的URL(現(xiàn)在包含具體的主機(jī)名和端口號(hào))用于實(shí)際的HTTP調(diào)用留攒。
二、注解原理
原理:RestTemplate嫉嘀、WebClient炼邀、Feign等HTTP客戶端會(huì)被容器注入一個(gè)LoadBalancerInterceptor攔截器,從而使它們具有負(fù)載均衡的能力吃沪。攔截器在請(qǐng)求之前根據(jù)具體的負(fù)載策略對(duì)請(qǐng)求的地址進(jìn)行替換汤善,然后再去調(diào)用。
三票彪、源碼分析
攔截器的代碼是在 LoadBalancerInterceptor類的intercept方法中,執(zhí)行交給了LoadBalanceClient摇零,通過(guò)LoadBalancerRequestFactory來(lái)構(gòu)建一個(gè)LoadBalancerRequest對(duì)象推掸。this.requestFactory.createRequest方法通過(guò)ServiceRequestWrapper來(lái)執(zhí)行替換URL的邏輯。ServiceRequestWrapper中將URL的獲取交給了LoadBalancerClient的reconstructURI方法驻仅。