初識Spring Cloud Eureka(三)(Eureka客戶端之間 服務的相互呼叫)
接著上一篇部落格,客戶端的建立 我們知道了服務的註冊與發現,那麼,服務之間是怎麼進行互相呼叫的呢?
我們先看一下服務列表,然後通過例項,來看一下怎麼進行服務之間的呼叫,再稍微看一下原始碼,看看呼叫是怎麼實現的。
首先,我們按照上一篇部落格的方法,建立了三個服務,一個server端,兩個client,通過訪問server,如下所示:
使用eureka_client-2呼叫eureka_client-1的服務,首先在eureka_client-1中定義controller,返回傳送過來的值,如下所示:
@RestController
@RequestMapping("test")
public class TestController {
@GetMapping("getSendStr")
public String getSendStr(String string) {
return "收到的訊息是:" + string;
}
}
然後,在 eureka_client-2中定義一個controller,用來獲取客戶端的請求,然後呼叫eureka_client-1服務中剛剛定義的方法。
我們先使用RestTemplate的api去進行呼叫。
使用方法很簡單,在啟動類配置RestTemplate的Bean,把他交由spring進行管理,然後引入Ribbon的jar包,用來進行負載均衡。首先引入jar,如下所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
然後,新增bean:
@Bean
//實現負載均衡的註解
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
接著,就可以實現controller了,如下所示:
@RestController
@RequestMapping("test")
public class GetController {
//注入剛才交由spring託管的bean
@Autowired
RestTemplate restTemplate;
@GetMapping("sendStr")
public String sendStr(String string) {
Map map = new HashMap();
map.put("string", string);
//這裡的url不用直接寫成ip,使用服務名稱代替即可,切記,RestTemplate的bean實現是必須新增@LoadBalanced註解,後續會解釋為什麼
return restTemplate.getForEntity("http://eureka-client-1/test/getSendStr?string="+string, String.class).getBody();
}
}
好了,一切就緒了,為了除錯方便,這裡直接使用的get方法,在瀏覽器上訪問eureka_client-2,然後呼叫eureka_client-1,接著返回資訊到瀏覽器,如下:
這樣就完了一次服務之間的呼叫了,是不是很簡單呢。
那麼,這一切究竟是怎麼實現的呢?
我們追蹤restTemplate.getForEntity,如下圖,最終呼叫了execute方法,此時的url值為:
http://eureka-client-1/test/getSendStr?string=我是訊息 ,顯然,這樣是無法訪問到相關服務的,接著向下看。
@Override
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));
}
後續呼叫了DefaultUriBuilderFactory的expand()方法,得到一個UriBuilder,此時我們看,UriBuilder實際上就是把請求連線給拆分開了,其中host部分,就是我們想要呼叫的服務的名稱。如下圖:
然後,我們回到RestTemplate,來跟蹤執行doExecute方法,先看一下結果,IDEA,alt+滑鼠左鍵即可,可以發現,返回了服務呼叫的結果:
那裡邊究竟發生了什麼呢?接著,我們追蹤到了InterceptingClientHttpRequest的executeInternal()方法,直到此時,我們的url還沒有發生變化,那麼,祕密肯定就在其中,我們接著追蹤:看我們發現了什麼?
LoadBalanceInterceptor攔截器!祕密肯定在他身上,我們先去看他一眼,他在spring-cloud-commons包下,實現了ClientHttpRequestInterceptor介面。知道他之後,我們接著往後走,執行他的intercept方法,拿到了前邊準備的host,即此處的serviceName,如下圖:
看來到了這裡,也是時候施展變換魔法了,首先是執行loadBalancer的execute方法,這個loadBalancer也是大有來頭,我們可以看到,它來自ribbon,繼承了LoadBalancerClient,作為bean註冊到了這裡:
在RibbonLoadBalancerClient中, 執行的execute方法,
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
throws IOException {
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
Server server = getServer(loadBalancer, hint);
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonServer ribbonServer = new RibbonServer(serviceId, server,
isSecure(server, serviceId),
serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
}
獲得一個IloadBalancer ,這是通過ribbon的負載均衡策略,再根據傳入的serviceid,從spring的context裡拿到的,具體的拿法現在先不細說,當然裡邊的請求的url,已經被變換為真是的請求路徑。
後續因為工作上需要使用Nacos,也就是springcloud-alibaba來作為微服務基礎,所有後續的內容,會重點在說一下Nacos的使用。
相關文章
- Spring Cloud系列(三):Eureka原始碼解析之服務端SpringCloud原始碼服務端
- eureka踩過的坑之註冊服務相互之間呼叫
- Spring Cloud系列(四):Eureka原始碼解析之客戶端SpringCloud原始碼客戶端
- eureka實現服務之間的呼叫
- 服務治理: Spring Cloud EurekaSpringCloud
- Eureka的微服務之間呼叫微服務
- Spring Cloud Eureka原理分析(三):註冊資訊讀取(服務端)SpringCloud服務端
- Eureka高可用叢集服務端和客戶端配置服務端客戶端
- Spring Cloud服務發現元件EurekaSpringCloud元件
- 【Spring Cloud】之 EurekaSpringCloud
- Eureka微服務之間呼叫-feign微服務
- springboot整合eureka,服務相互呼叫簡單示例Spring Boot
- Spring Cloud 之 Eureka.SpringCloud
- 【SpringCloud】(三):客戶端發現方式 EurekaSpringGCCloud客戶端
- Spring Cloud Eureka原理分析(一):註冊過程-服務端SpringCloud服務端
- Spring cloud(2)-服務發現(Eureka,Consul)SpringCloud
- Spring Cloud微服務-基於Eureka的feign呼叫(1)SpringCloud微服務
- 二、Spring Cloud 之旅 -- Eureka 微服務的釋出與呼叫SpringCloud微服務
- 【Spring Cloud】Eureka實現微服務釋出與呼叫SpringCloud微服務
- Spring Cloud(三) 服務提供者 Eureka + 服務消費者(rest + Ribbon)SpringCloudREST
- Spring Cloud(一) 服務的註冊與發現(Eureka)SpringCloud
- 微服務~Eureka實現的服務註冊與發現及服務之間的呼叫微服務
- 整合spring cloud雲服務架構 - eureka 基礎SpringCloud架構
- 4、Spring Cloud EurekaSpringCloud
- eureka客戶端依賴引入爆紅客戶端
- Spring Cloud Eureka 實現服務註冊與發現SpringCloud
- Spring Cloud 系列(一)Eureka 服務註冊與發現SpringCloud
- Spring Cloud(四)服務提供者 Eureka + 服務消費者 FeignSpringCloud
- 微服務之Eureka服務發現微服務
- Spring Cloud原始碼分析之Eureka篇第五章:更新服務列表SpringCloud原始碼
- 關於Spring Cloud EurekaSpringCloud
- Spring Cloud 入門教程 – Eureka服務註冊與發現SpringCloud
- Spring Cloud Netflix—服務發現:Eureka伺服器SpringCloud伺服器
- Spring Cloud 入門教程 - Eureka服務註冊與發現SpringCloud
- Spring-cloud學習筆記--- Eureka原始碼剖析之服務註冊介面SpringCloud筆記原始碼
- Spring Cloud原始碼分析之Eureka篇第六章:服務註冊SpringCloud原始碼
- Spring Cloud之微服務之間相互呼叫、如何讓一個微服務呼叫另外一個微服務SpringCloud微服務
- Spring Cloud Eureka 實現高可用服務發現註冊中心SpringCloud