先看client端,如何使用service discovery,範例是Samples\Discovery\src\AspDotNetCore\Fortune-Teller-UI , 先在專案安裝Steeltoe.Discovery.Client或Pivotal.Discovery.Client套件,在專案底下appsettings.json加入給Eureka Servcer的設定
"eureka": {
"client": {
"serviceUrl": "http://localhost:8761/eureka/",
"shouldRegisterWithEureka": false
}
}
"serviceUrl" 代表Eureka Server的位址,
"shouldRegisterWithEureka": false 代表著這個服務不會註冊到Eureka只會使用servicer discovery,
接著在AspDotNetCore\Fortune-Teller-UI\StartUp.cs的ConfigureServices方法裡調用相關的方法
public void ConfigureServices(IServiceCollection services)
{
services.AddLogging();
services.AddDiscoveryClient(Configuration);
services.AddSingleton<IFortuneService, FortuneService>();
// Add framework services.
services.AddMvc();
}
services.AddDiscoveryClient(Configuration): 會將Configuration裡面相關的資料註冊到Eureka
services.AddSingleton<IFortuneService, FortuneService>(): 並非是Service Discovery相關的方法,而是.Net core本身提供的DI。FortuneService.cs類似遠端服務在本地端的proxy, 當遇到IFortuneService會自動注入唯一的FortuneService實例
來看一下FortuneService.cs
using Pivotal.Discovery.Client;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace Fortune_Teller_UI.Services
{
public class FortuneService : IFortuneService
{
DiscoveryHttpClientHandler _handler;
ILogger<FortuneService> _logger;
private const string RANDOM_FORTUNE_URL = "http://fortuneService/api/fortunes/random";
public FortuneService(IDiscoveryClient client, ILoggerFactory logFactory)
{
_handler = new DiscoveryHttpClientHandler(client, logFactory.CreateLogger<DiscoveryHttpClientHandler>());
_logger = logFactory.CreateLogger<FortuneService>();
}
public async Task<string> RandomFortuneAsync()
{
var client = GetClient();
var result = await client.GetStringAsync(RANDOM_FORTUNE_URL);
_logger.LogInformation("RandomFortuneAsync: {0}", result);
return result;
}
private HttpClient GetClient()
{
var client = new HttpClient(_handler, false);
return client;
}
}
}
注意一下這個RANDOM_FORTUNE_URL = "http://fortuneService/api/fortunes/random";
中間的"fortunesService" 是在Eureka註冊服務的名字, 對應到的是在Fortune-Teller-Service\appsettings.json裡面的
"spring": {
"application": {
"name": "fortuneService"
}
我猜測是藉由DiscoveryHttpClientHandler解析字串來尋找eureka上相對地的服務,細節要找source code看了
範例是Samples\Discovery\src\AspDotNetCore\Fortune-Teller-Service
一樣先在appsettings.json進行設定
"spring": {
"application": {
"name": "fortuneService"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:8761/eureka/",
"shouldFetchRegistry": false
},
"instance": {
"port": 5000
}
}
跟使用service discovery有所不同
"name": "fortuneService" 是會註冊在eureka裡面的服務名,
"shouldFetchRegistry": false 不會從Eureka Server取得已註冊的服務資訊,因為這個服務只做服務註冊
另外需要加上port的資訊
"instance": {
"port": 5000
}
這邊是給Eureka的註冊資訊,所以啟用這個服務的時候指定port也要是跟註冊資訊一樣,否則當要調用這個服務的時候是找不到(這是寫死的,應該有機會自動取得port...)
然後在Startup.cs的ConfigureService方法調用services.AddDiscovery(Configuration)就完成了
Steeltoe在appsettings.json裡面可以對service discovery和registry設定許多選項,有興趣的朋友可以看一下
http://steeltoe.io/docs/steeltoe-discovery/#1-1-3-run-fortune-teller-service