前言
上篇文章實際上只講了服務治理中的服務注冊,服務與服務之間如何調用呢?傳統的方式,服務A調用服務B,那么服務A訪問的是服務B的負載均衡地址,通過負載均衡來指向到服務B的真實地址,上篇文章已經說了這種方式的缺點。那么下面講如何在spring cloud+dotnet core的應用下進行服務調用。
代碼實現
假設一種場景,有一個訂單服務,有一個產品服務,其中產品服務是由兩個服務節點組成一個集群。需求是訂單服務訪問產品服務的一個API接口。根據上一章文章的內容創建3個應用程序ServiceOne(端口8010),ServiceTwo(端口8011),ServiceThree(8012)。其中ServiceOne設置應用程序名稱為order。ServiceTwo和ServiceThree的應用程序名稱為product,做成集群。
ServiceOne.appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"spring": {
"application": {
"name": "order"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:5000/eureka/"
},
"instance": {
"port": 8010
}
}
}
ServiceOne.Controllers.ValuesController.CS
private readonly DiscoveryHttpClientHandler _handler;
private const string ProductUrl = "http://product/api/values";
public ValuesController(IDiscoveryClient client, ILoggerFactory logFactory)
{
_handler = new DiscoveryHttpClientHandler(client);
}
[HttpGet("product")]
public async Task<string> GoProductAsync()
{
var client = new HttpClient(_handler, false);
return await client.GetStringAsync(ProductUrl);
}
ServiceTwo.appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"spring": {
"application": {
"name": "product"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:5000/eureka/"
},
"instance": {
"port": 8011
}
}
}
ServiceTwo.appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"spring": {
"application": {
"name": "product"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:5000/eureka/"
},
"instance": {
"port": 8012
}
}
}
為了展現訪問的差異,設置不同的返回值。
ServiceTwo.Controllers.ValuesController.cs
[HttpGet]
public string Get()
{
return "ServiceTwo";
}
ServiceThree.Controllers.ValuesController.cs
[HttpGet]
public string Get()
{
return "ServiceThree";
}
同時啟動這3個項目,先看看服務中心http://localhost:5000/
這個3個應用程序都已經注冊到了服務中心。ServiceOne被注冊到ORDER,ServiceTwo和ServiceThree注冊到了PRODUCT。
分別訪問
http://localhost:8011/api/values 返回ServiceTwo
http://localhost:8012/api/values 返回ServiceThree
證明這兩個服務是沒有問題的。
再訪問http://localhost:8010/api/values/product,
如圖所示,分別返回了“ServiceTwo”和“ServiceThree”,多刷新幾次,發現結果是來回變動的,這說明服務中心幫我們實現了負載均衡。
我們再做一個測試,斷開ServiceTwo這個應該程序。我們繼續訪問http://localhost:8010/api/values/product,發現一次錯誤,一次正常返回ServiceThree。30秒以后(可配置)再訪問正常返回ServiceThree,同時發現服務中心已經踢掉了端口為8011的應用程序(ServiceTwo)。
后記
通過上面3個實例我們模擬了分布式的調用場景,其中Order訪問Product集群的時候,並沒有指定具體的地址,而是指定了服務名稱(product),服務中心自動分配了地址,並實現了負載均衡。聯系實際應用場景,配合docker,我們可以快速的對某個服務進行添加,不再需要維護服務節點。同時某個服務節點掛掉以后,服務中心也會踢出這個服務節點(會有短暫的不可用)。結合CAP理論來說,服務中心滿足了AP。
這篇文章講解了服務之間的調用,我們實際的應用場景,還有各種客戶端(IOS,Andriod,Web...)來訪問,而服務一般是內網不對外暴露的,所以客戶端訪問服務的時候就需要有一個專門對外暴露的入口,那么就引入了下篇文章的API網關。
示例代碼
所有代碼均上傳github。代碼按照章節的順序上傳,例如第一章demo1,第二章demo2以此類推。
求推薦,你們的支持是我寫作最大的動力,我的QQ群:328438252,交流微服務。
傳送門
- spring cloud+dotnet core搭建微服務架構:服務注冊(一)
- spring cloud+dotnet core搭建微服務架構:服務發現(二)
- spring cloud+dotnet core搭建微服務架構: Api網關(三)
- spring cloud+dotnet core搭建微服務架構:配置中心(四)
參考資料
java部分
.net部分