微服务学习笔记(2)——使用Consul 实现 MagicOnion(GRpc) 服务注册和发现
程序员文章站
2022-04-28 13:55:46
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.预告
下一篇我会想法办法使他们能相互通讯(其实我还不知道怎么搞)