1. ダウンロードとインストール
公式サイトからダウンロードしてください:https://www.consul.io/downloads.html
ダウンロードしたファイルを解凍し、そのフォルダでコマンドプロンプトを開きます。以下のコマンドを実行して開発モードでConsulを起動します。
consul agent -dev
以下のようなメッセージが表示されれば起動成功です。UIは http://localhost:8500/ からアクセスできます。
環境変数を設定すれば、次回からコマンドプロンプトを開くだけでConsulを起動できます。
2. サービス登録と発見
2.1 サービス登録クラスの実装
まず、サービスをConsulに登録するためのクラスを作成します。このクラスは、アプリケーションの起動時にサービス情報を登録し、停止時に登録を解除します。
public class ServiceRegistrar
{
private readonly IConfiguration _config;
private readonly IHostApplicationLifetime _appLifetime;
public ServiceRegistrar(IConfiguration configuration, IHostApplicationLifetime lifetime)
{
_config = configuration;
_appLifetime = lifetime;
}
public void RegisterService()
{
var serviceIp = _config["ServiceIp"];
var servicePort = int.Parse(_config["ServicePort"]);
Console.WriteLine($"サービスヘルスチェックURL: http://{serviceIp}:{servicePort}/api/health/check");
var consulClient = new ConsulClient(ConfigureConsulClient);
var uniqueServiceId = $"ProductService-{Guid.NewGuid()}";
var registration = new AgentServiceRegistration
{
ID = uniqueServiceId,
Name = "ProductService",
Address = serviceIp,
Port = servicePort,
Check = new AgentServiceCheck
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
Interval = TimeSpan.FromSeconds(10),
HTTP = $"http://{serviceIp}:{servicePort}/api/health/check",
Timeout = TimeSpan.FromSeconds(5)
}
};
consulClient.Agent.ServiceRegister(registration).Wait();
// アプリケーションが停止する際に、サービス登録を解除する
_appLifetime.ApplicationStopping.Register(() =>
{
Console.WriteLine($"サービス停止: {serviceIp}:{servicePort}");
consulClient.Agent.ServiceDeregister(uniqueServiceId).Wait();
});
}
private static void ConfigureConsulClient(ConsulClientConfiguration clientConfig)
{
clientConfig.Address = new Uri("http://127.0.0.1:8500");
clientConfig.Datacenter = "dc1";
}
}
2.2 アプリケーション起動時に登録処理を呼び出す
次に、ASP.NET Coreアプリケーションの起動時に、上記で作成したサービス登録クラスを呼び出します。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
{
// ... その他のミドルウェア設定
// アプリケーション起動時にサービス登録を実行
new ServiceRegistrar(Configuration, lifetime).RegisterService();
}
2.3 サービスの起動
複数のサービスインスタンスを起動して、Consulが正常にサービスを発見できるか確認します。以下のコマンドを異なるポートで実行します。
dotnet ProductService.dll --urls="http://*:5210" --ServiceIp="127.0.0.1" --ServicePort=5210
dotnet ProductService.dll --urls="http://*:5211" --ServiceIp="127.0.0.1" --ServicePort=5211
dotnet ProductService.dll --urls="http://*:5212" --ServiceIp="127.0.0.1" --ServicePort=5212
これらのコマンドを実行後、ConsulのUI(http://localhost:8500)を確認すると、登録されたサービスが表示されます。サービスに問題が発生した場合は、以下のエンドポイントでヘルスチェックの結果を確認できます:http://localhost:8500/v1/agent/checks。
3. クライアントによるサービスの利用
サービスディスカバリを行い、利用可能なサービスのいずれかにリクエストを送信するクライアントアプリケーションを作成します。
class ServiceDiscoveryClient
{
private static List<string> _serviceEndpoints = new List<string>();
static async Task Main(string[] args)
{
Console.WriteLine("利用可能なサービスのアドレスを一覧表示します。");
await DiscoverServices();
for (int i = 0; i < 15; i++)
{
Console.WriteLine("ランダムなサービスアドレスにリクエストを送信します。");
var randomIndex = new Random().Next(_serviceEndpoints.Count);
var targetUrl = _serviceEndpoints[randomIndex];
Console.WriteLine($"リクエスト先のアドレス: {targetUrl}");
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync(targetUrl);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{response.StatusCode}: {content}");
}
Console.ReadLine();
}
public static async Task DiscoverServices()
{
var consulClient = new ConsulClient();
var services = await consulClient.Agent.Services();
var registeredServices = services.Response.Values;
foreach (var service in registeredServices)
{
var address = service.Address;
var port = service.Port;
var name = service.Service;
Console.WriteLine($"アドレス: {address}:{port}, サービス名: {name}");
_serviceEndpoints.Add($"http://{address}:{port}/api/products/getall");
}
}
}
このクライアントを実行すると、Consulから取得したサービスアドレスに対してランダムなリクエストが送信され、各サービスの応答がコンソールに表示されます。