• .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)

    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文件

    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文件

    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

    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();
                }
            }
        }
    }
    
  • 相关阅读:
    [ICLR 2021] Revisiting Dynamic Convolution via Matrix Decomposition 学习笔记
    Codeforces Round #769 (Div. 2) ABCD
    Swin Transformer论文阅读笔记
    Leetcode 1765. 地图中的最高点(BFS)
    2022牛客寒假算法基础集训营3 ABCDEGIL
    Codeforces Round #767 (Div. 2) C. Meximum Array(主席树/整活解法)
    30
    27
    23
    29
  • 原文地址:https://www.cnblogs.com/zhangxiaoxia/p/12501890.html
Copyright © 2020-2023  润新知