1.下載打開Consul 筆者是windows下麵開發的(也可以使用Docker)。 官網下載windows的Consul https://www.consul.io/ 使用cmd視窗打開,輸入 訪問預設127.0.0.1:8500就可以看到界面化的Consul 2.在服務端註冊 接著上一篇 app ...
1.下載打開Consul
筆者是windows下麵開發的(也可以使用Docker)。
官網下載windows的Consul
使用cmd視窗打開,輸入consul agent -dev
訪問預設127.0.0.1:8500就可以看到界面化的Consul
2.在服務端註冊
接著上一篇
using Consul;
using Grpc.Core;
using GRPCServer.Entity;
using MagicOnion.Server;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace GRPCServer
{
public class Startup
{
public Startup(IConfiguration configuration)
{
this.Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
MagicOnionServiceDefinition service = MagicOnionEngine.BuildServerServiceDefinition(new MagicOnionOptions(true)
{
MagicOnionLogger = new MagicOnionLogToGrpcLogger()
});
Server server = new Server
{
Services = { service },
Ports = { new ServerPort(this.Configuration["Service:LocalIPAddress"], Convert.ToInt32(this.Configuration["Service:Port"]), ServerCredentials.Insecure) }
};
server.Start();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
ServiceEntity serviceEntity = new ServiceEntity
{
IP = this.Configuration["Service:LocalIPAddress"],
Port = Convert.ToInt32(this.Configuration["Service:Port"]),
ServiceName = this.Configuration["Service:Name"],
ConsulIP = this.Configuration["Consul:IP"],
ConsulPort = Convert.ToInt32(this.Configuration["Consul:Port"])
};
var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{serviceEntity.ConsulIP}:{serviceEntity.ConsulPort}"));//請求註冊的 Consul 地址
var httpCheck = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務啟動多久後註冊
Interval = TimeSpan.FromSeconds(10),//健康檢查時間間隔,或者稱為心跳間隔
HTTP = this.Configuration["Service:Examination"],//健康檢查地址
Timeout = TimeSpan.FromSeconds(5)
};
var registration = new AgentServiceRegistration()
{
Checks = new[] { httpCheck },
ID = Guid.NewGuid().ToString(),
Name = serviceEntity.ServiceName,
Address = serviceEntity.IP,
Port = serviceEntity.Port,
Tags = new[] { $"urlprefix-/{serviceEntity.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 標簽,以便 Fabio 識別
};
consulClient.Agent.ServiceRegister(registration).Wait();//服務啟動時註冊,內部實現其實就是使用 Consul API 進行註冊(HttpClient發起)
lifetime.ApplicationStopping.Register(() =>
{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服務停止時取消註冊
});
}
}
}
appsettings.json
{
"Service": {
"Name": "Test3",
"Port": "8083",
"LocalIPAddress": "192.168.1.8",
"Examination": "http://192.168.1.8:5000/api/Values"
},
"Consul": {
"IP": "127.0.0.1",
"Port": "8500"
}
}
3.客戶端調用
using Consul;
using Grpc.Core;
using MagicOnion.Client;
using ServerDefinition;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
var aaa= AvaliableServices("Test3","").Result;
public static async Task<ServiceEntry[]> AvaliableServices(string name, string tags)
{
var services = new List<ServiceEntry>();
using (var client = new ConsulClient())
{
foreach (var tag in tags.Split(','))
{
var result = await client.Health.Service(name, !string.IsNullOrEmpty(tag) ? tag : null, true).ConfigureAwait(false);
foreach (var item in result.Response)
{
if (!services.Any(service => service.Node.Address == item.Node.Address
&& service.Service.Port == item.Service.Port))
{
services.Add(item);
}
}
}
//交集處理,僅取出完全匹配服務
foreach (var tag in tags.Split(','))
{
if (string.IsNullOrEmpty(tag))
{
continue;
}
var alsorans = services.Where(service => !service.Service.Tags.Contains(tag)).ToList();
foreach (var alsoran in alsorans)
{
services.Remove(alsoran);
}
}
}
return services.ToArray();
}
4.思考
這個時候我就能通過'Test3'來獲得Test3的服務和介面。
但是我是使用的MagicOnion,還是沒辦法拿到我定義的方法SumAsync
怎麼辦?
1.引用ITest (讓微服務之間有引用,不太好)
2.使用網關
5.預告
下一篇我會想法辦法使他們能相互通訊(其實我還不知道怎麼搞)