.Net Core 微服务学习(二): 服务治理发现(Consul)
Consul([ˈkɒnsl],康搜)是注册中心,服务提供者、服务消费者等都要注册到Consul中,这样就可以实现服务提供者、服务消费者的隔离。
除了Consul之外,还有Eureka、Zookeeper等类似软件。
COnsul主要功能如下
1.服务注册与发现
2.服务负载均衡
3.健康检查
用DNS举例来理解Consul。consul是存储服务名称与IP和端口对应关系的服务器。
假设:我有3台用于发帖的服务器,他们的IP和端口分别是
127.0.0.1:5726
127.0.0.1:5727
127.0.0.1:5728
那么这三台服务器就在Consul中注册,那么Consul就知道了这三台服务器的IP可端口了。当我们要发帖,想调用发帖服务的时候,就像Consul要,Consul会告诉我们,哪些服务器提供了发帖服务,然后我们自己选择一个发帖服务器就可以了。(是不是特别简单,这样就不需要我们记住有那些发帖服务器的IP地址和端口了)
Consul还提供一个健康检查的功能
假如有三台发帖的服务器都在Consul进行注册了发帖服务,假如有一台服务器挂了怎么办? 所有Consul就提供了一个服务器的健康检查功能,他会每隔一段时间向这三台服务器发送心跳包,比如每隔10秒钟就向这三台服务器请求一次,通过这样来检查这三台服务器是否还活着
一:Consul服务器安装与启动
https://www.consul.io/downloads.html
因为我的电脑是windows64位的,因为仅仅是测试,所有就下了一个windows版本的Consul
下载下来后,在运行中输入cmd 命令,然后在cmd中输入命令,执行cd命令切换到consul文件所在的盘符及文件夹
然后执行 consul.exe agent -dev
【这是开发环境测试,所有运行一台服务器就够了,因为开发环境无所谓稳定不稳定,但是如果是生产环境就要建集群,要至少一台Server,多台Agent】如果觉得搭建环境麻烦的话就去阿里云去买Consul服务吧,阿里云都给你配置好了,直接用就行
开发环境中consul重启后数据就会丢失。
consul的监控页面http://127.0.0.1:8500/
consult主要做三件事:提供服务到ip地址的注册;提供服务到ip地址列表的查询;对提供服务方的健康检查(HealthCheck);
二:.Net Core连接consul
在nuget管理器中执行:Install-Package Consul
三、 Rest服务的准备
1>创建一个Asp.Net Core Web应用程序(这个应用程序主要提供发送信息的服务,所有我取名叫MsgServer)
在程序中添加一个API控制器(这个控制器主要用于做服务器的健康检查,所有我取名叫HealthController)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using Microsoft.AspNetCore.Mvc; namespace MsgServer.Controllers { [Produces( "application/json" )] [Route( "api/Health" )] public class HealthController : Controller { //这个控制器主要用于对这个服务的健康检查,如果返回OK表示服务正常,没有挂掉 [HttpGet] public IActionResult Get() { Console.WriteLine(DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) + "health check" ); return Content( "ok" ); } } } |
四、 服务注册到Consul 与 服务从Consul中注销
Program.cs文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | namespace MsgServer { public class Program { public static void Main( string [] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost( string [] args) { //程序通过selfhost方式启动,可以设置这个args参数值。比如:dotnet test.dll --ip 127.0.0.1 --port 8080 //args就会接收到ip,port这些值。如果直接以IIS Express方式启动,这里好像是接收不到args参数的 var config = new ConfigurationBuilder().AddCommandLine(args).Build(); string ip = config[ "ip" ]; string port = config[ "port" ]; return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() //.UseUrls("http://127.0.0.1:8080") //如果要在之类指定了URL地址,那么它的优先权最高 .UseUrls($ "http://{ip}:{port}" ) .Build(); } } } |
Startup.cs文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | using Consul; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace MsgServer { public class Startup { public Startup(IConfiguration configuration) { 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(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler( "/Home/Error" ); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default" , template: "{controller=Home}/{action=Index}/{id?}" ); }); string ip = Configuration[ "ip" ]; string port = Configuration[ "port" ]; string serviceName = "MsgService" ; //服务名称 string serviceId = serviceName + Guid.NewGuid(); //服务编号 using ( var consulClient = new ConsulClient(consulConfig)) { AgentServiceRegistration ars = new AgentServiceRegistration(); ars.Address = ip; //服务器的IP地址(必须能被调用者访问的IP地址,所有正式环境就不能用127.0.0.1) ars.Port = Convert.ToInt32(port); //服务器的端口号,必须能被调用者访问的的端口 ars.Name = serviceName; //服务器名称(同一个服务,服务名称都是一致的) ars.ID = serviceId; //服务器的编号(如果有5个发帖服务器,那么它们的服务器编号都是唯一的) ars.Check = new AgentServiceCheck() //健康检查 { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //发现服务器挂了后,多久时间注销掉这个服务器 HTTP = $ "http://{ip}:{port}/api/Health" ,//健康检查调用的控制器地址 Interval = TimeSpan.FromSeconds(10), //多久多一次健康检查(心跳检查) Timeout = TimeSpan.FromSeconds(5) }; consulClient.Agent.ServiceRegister(ars).Wait(); //注意:Consult客户端的所有方法几乎都是异步方法,但是都没按照规范加上Async后缀,所以容易误导。记得调用后要Wait()或者await }; //服务器正常退出的时候的注册事件,这个注册事件就是从Consul注销服务(它是调用的Register方法进行事件注册的) //它需要通过方法参数注入IApplicationLifetime对象,从这个对象中可以知道,服务器是否退出 appLifetime.ApplicationStopped.Register(() => { using ( var consulClient = new ConsulClient(consulConfig)) { Console.WriteLine( "应用退出,开始从consul注销" ); consulClient.Agent.ServiceDeregister(serviceId).Wait(); //即注销服务编号为serviceId的服务器 } }); //appLifetime.ApplicationStarted.Register(() => { });//服务启动的注册事件 //appLifetime.ApplicationStopping.Register(() => { }); //服务正在启动中的注册事件 } private void consulConfig(ConsulClientConfiguration c) { c.Address = new Uri( "http://127.0.0.1:8500" ); //Consul服务的地址,Consul默认端口号就是8500 c.Datacenter = "dc1" ; } } } |
启动项目
此处采用 命令行启动的方式 我们只有一套代码 要启动多个实例
命令如下
dotnet MicroService.dll --urls="http://*:5726" --ip="127.0.0.1" --port=5726
此处指定ip 和端口 启动服务实例
服务的调用
1>创建一个控制台项目(获取其他项目)我取名叫ClientProject
2>在项目中安装Consul
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | using Consul; using System; namespace ClientProject { class Program { static void Main( string [] args) { using ( var consulClient = new ConsulClient(r => r.Address = new Uri( "http://127.0.0.1:8500" ))) { //获取到在Consul中注册的所有服务 var services = consulClient.Agent.Services().Result.Response; foreach ( var service in services.Values) { //我们获取到所有的服务器后,自己决定要连接那台服务器(我们可以随机的选择一条服务器,或则采用轮询机制,或其他的方式,总之是达到负载均衡的效果) Console.WriteLine($ "id={service.ID},name={service.Service},ip={service.Address},port={service.Port}" ); } Console.ReadKey(); } } } } |
作者: Felix-Zhang
出处:https://www.cnblogs.com/zhangxiaoxia/p/12501890.html
版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探