• 8分钟学会Consul集群搭建及微服务概念


    Consul介绍:

    Consul 是由 HashiCorp 公司推出的开源软件,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。

    Consul的如何实现的?

    Consul 用 Golang 实现,因此具有天然可移植性(支持 Linux、windows 和 Mac OS X ),它的安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

    微服务概念:

    微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

    尽管“微服务”这种架构风格没有精确的定义,但其具有一些共同的特性,如围绕业务能力组织服务、自动化部署、智能端点、对语言及数据的“去集中化”控制等等。简而言之,微服务架构风格是一种将单个应用程序开发为一套小型服务的方法,每个小型服务都在自己的流程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务围绕业务功能构建,可通过全自动部署机制独立部署。这些服务至少集中管理,可以用不同的编程语言编写,并使用不同的数据存储技术。

     Consul的安装与配置

    我们需要去下载Consul ,下载很简单,直接去:https://www.consul.io/downloads.html 选择对应的平台即可,如果你的是Mac OS x 那么直接双击那个可执行文件即可,我的平台是windows10 ,那么相对于MacOsX是比较困难的,即配置环境变量,将文件的位置放到你的path中就可以了,其目的就是为了在Cmd终端中能够键入执行Consul命令,如果你的环境变量已经配置成功,请在Cmd中敲击consul,如果结果如下,那么恭喜您,你成功进入Consul大门。

     名词解释

    Client : Consul 的 Client模式,就是客户端模式。是 Consul 节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到 Server,本身是不持久化这些信息。
    Server :Consul 的 Server 模式,表明这个 Consul 是个 Server ,这种模式下,功能和 Client 都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。
    Server-Leader:  Server 是它们的老大,它和其它 Server 不一样的一点是,它需要负责同步注册的信息给其它的 Server ,同时也要负责各个节点的健康监测。
    raft: Server 节点之间的数据一致性保证协议使用的是 raft,而 zookeeper 用的 paxos,etcd采用的也是raft
    服务发现协议:Consul 采用 http 和 DNS 协议,etcd 只支持 http 。
    服务注册:Consul 支持两种方式实现服务注册,一种是通过 Consul 的服务注册 Http API,由服务自己调用 API 实现注册,另一种方式是通过 json 格式的配置文件实现注册,将需要注册的服务以 json 格式的配置文件给出。Consul 官方建议使用第二种方式。

    启动Consul

    如果是在单机情况下使用开发模式启动,在终端中输入:

    ~ » consul agent -dev
    

    开启Consul 集群

    首先创建Server-Leader,即老大,那么在终端上输入以下命令:

    //Server
    consul agent -server -ui -bootstrap-expect=2 -data-dir=/tmp/consul -node=con
    sul-server-1 -client=0.0.0.0 -bind=10.211.55.2 -datacenter=dc1
    //Client
     consul agent -client -bind 0.0.0.0  本机ip -data-dir=	mpconsul -node 节点名 -join 随意一个服务器的地址

    其中:

    consul agent -server 表示以服务器模式启动代理。
    -bootstrap-expect=2 表示节点个数为2个。
    -node=consul-server-1 表示节点名称
    -client=0.0.0.0 表示客户端 IP
    -bind=10.211.55.2 表示服务端 IP
    -datacenter=dc1 数据中心名称

    需要注意的是,如果你启动的Server模式的话,你一定要注意node名不要相同,否则将会替换你的项。

    那么Server-Leader已经创建了,需要别的服务器去进行连接了,如果是Server模式,输入以下命令,只不过是拼接了-join id.

    consul agent -server -ui -bootstrap-expect=2 -data-dir=/tmp/consul -node=con
    sul-server-2 -client=0.0.0.0 -bind=10.211.55.4 -datacenter=dc1 -join 10.211.
    55.2
    
    • -data-dir=/tmp/consul 表示临时数据存储路径
    • -join 10.211.55.2 表示加入 10.211.55.2 所在的集群

    这个时候如果出现Consul agent Running!!还有一大堆东西。那么说明你已经集群成功了,你可以去自己的通过Consul提供的UI去看节点状况,地址为 你自己的id+8500端口,即192.168.10.6:8500或者你的子节点均可,但是如果说你的节点个数是4个,你还有几个节点没有放上去,那么UI是出不来了(有可能会报500错)。

    那么除了UI查看节点以外,还可以通过终端输入指令来查看我们的节点状态。

    consul members 
    

    如果我们希望得到更为详细的信息,可以使用指令来查看

    consul operator raft list-peers 

    如果说你没有服务器集群,那么输入以上命令就会出现以下结果:

     创建.NET Core API 并注册服务

    如果你的 Consul Cluster 已经搭建完成,那么可以接下来创建一个.NET Core API 来实现服务的注册。

    我们创建一个空的解决方案,添加解决方案文件夹 “服务注册”,创建Api项目。

     

    修改启动配置文件

    在launchSettings.json中修改启动ip和端口。

    {
      "profiles": {
        "BasicPlatformService": {
          "commandName": "Project",
          "applicationUrl": "http://192.168.43.174:8080",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        }
      }
    }
    

    添加健康检查控制器

    在项目中添加一个名为  HealthController 的 API 控制器,用于在将服务注册到 Consul 后的健康检查。

        [Route("api/[controller]")]
        [ApiController]
        public class HealthController : ControllerBase
        {
            /// <summary>
            /// 服务健康检测 ⽅方法
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public IActionResult Get() => Ok(" health check ok");
        }

     在项目中添加Consul,或者键入命令,这当然,由你选择。

    install-package Consul

     注册Consul中间件,修改Startup.cs文件,这里使用的是 Consul 的服务注册 Http API。

     public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime life)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseMvc();
    
                using (ConsulClient client = new ConsulClient(x => x.Address = new Uri("http://192.168.43.174:8500")))
                {
                    var httpCheck = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                        Interval = TimeSpan.FromSeconds(10),
                        HTTP = $"http://192.168.43.174:8080/api/health",
                        Timeout = TimeSpan.FromSeconds(5)
                    };
                    var registration = new AgentServiceRegistration()
                    {
                        Checks = new[] { httpCheck },
                        ID = "MicroService.Service",
                        Name = "MicroService.Service",
                        Address = "192.168.43.174",
                        Port = 8080,
                        Tags = new[] { "urlprefix-/MicroService.Chanpter01.Service" }
                    };
                    // 服务启动时注册,内部实现是使⽤用 Consul API 进⾏行行注册(HttpClient发起)
                    client.Agent.ServiceRegister(registration).Wait();
                    // 当服务停⽌止时,取消注册
                    life.ApplicationStopping.Register(() =>
                    {
                        // 服务停⽌止时取消注册
                        client.Agent.ServiceDeregister(registration.ID).Wait();
                    });
                }
            } 
    

      完成后,启动项目,此时已成功注册。

    2018-12-18 更新 使用Json文件配置

    为了不让每个服务器都打以上的代码,那么我们可以使用json配置(放到你的config中)。创建一个ProjectServer.json

    {
      "services": [
        {
          "ID": "t169_000000001_student_service",
          "name": "T169.ZhangZiHao.Service",
          "tags": [
            "urlprefix-/T169.Studeent.Service"
          ],
          "address": "192.168.43.174",
          "port": 8080,
          "checks": [
            {
              "name": "Student Service check",
              "http": "http://192.168.43.174:8080/api/health",
              "interval": "10s",
              "timeout": "5s"
            }
          ]
        },
        {
          "ID": "t169_000000002_mail_service",
          "name": "T169.Mail.Service",
          "tags": [
            "urlprefix-/T169.Mail.Service"
          ],
          "address": "192.168.43.174",
          "port": 8081,
          "checks": [
            {
              "name": "Mail Service check",
              "http": "http://192.168.43.174:8081/api/health",
              "interval": "10s",
              "timeout": "5s"
            }
          ]
        }
      ]
    }

    其中每个节点我就不一一阐述了,和硬编码中的都一样,就需要改改http address。

    然后开始部署集群的时候要注意了,和上面不一样的是 需要你去指定tmp了,就是你的那个config的地方 。

    consul agent -server -ui -bootstrap-expect=2 -data-dir=/tmp/consul -config-d
    ir=/tmp/consul/config -node=consul-server-2 -client=0.0.0.0 -bind=10.211.55.
    4 -datacenter=dc1 

    如果要加入集群则是:

    consul agent -server -ui -bootstrap-expect=2 -data-dir=/tmp/consul -config-d
    ir=/tmp/consul/config -node=consul-server-2 -client=0.0.0.0 -bind=10.211.55.
    4 -datacenter=dc1 -join 10.211.55.2

    2018-12-19 更新 使用MailKit

    为了更好的接收健康状态,那么我们使用MailKit,使用这个之前,先nuget这个emailkit。

    定义EmailHelper.cs:

    public class EmailSettings
        {
            public string SmtpServer { get; set; }
            public int SmtpPort { get; set; }
            public string AuthAccount { get; set; }
            public string AuthPassword { get; set; }
            public string ToWho { get; set; }
            public string ToAccount { get; set; }
            public string FromWho { get; set; }
            public string FromAccount { get; set; }
            public string Subject { get; set; }
        }
        public class EmailHelper
        {
            public static void SendHealthEmail(EmailSettings settings, string content)
            {
                try
                {
                    dynamic list = JsonConvert.DeserializeObject(content);
                    if (list != null && list.Count > 0)
                    {
                        var emailBody = new StringBuilder("健康检查故障:
    ");
                        foreach (var noticy in list)
                        {
                            emailBody.AppendLine($"--------------------------------------");
                            emailBody.AppendLine($"Node:{noticy.Node}");
                            emailBody.AppendLine($"Service ID:{noticy.ServiceID}");
                            emailBody.AppendLine($"Service Name:{noticy.ServiceName}");
                            emailBody.AppendLine($"Check ID:{noticy.CheckID}");
                            emailBody.AppendLine($"Check Name:{noticy.Name}");
                            emailBody.AppendLine($"Check Status:{noticy.Status}");
                            emailBody.AppendLine($"Check Output:{noticy.Output}");
                            emailBody.AppendLine($"--------------------------------------");
                        }
    
                        var message = new MimeMessage();
                        // 从谁发出
                        message.From.Add(new MailboxAddress(settings.FromWho, settings.FromAccount));
                        // 发送给谁
                        message.To.Add(new MailboxAddress(settings.ToWho, settings.ToAccount));
    
                        // 设置邮件标题
                        message.Subject = settings.Subject;
                        // 设置邮件内容
                        message.Body = new TextPart("plain") { Text = emailBody.ToString() };
    
                        using (var client = new SmtpClient())
                        {
                            client.ServerCertificateValidationCallback = (s, c, h, e) => true;
                            client.Connect(settings.SmtpServer, settings.SmtpPort, false);
                            client.AuthenticationMechanisms.Remove("XOAUTH2");// 去除安全令牌
                            // 验证账号+密码
                            client.Authenticate(settings.AuthAccount, settings.AuthPassword);
                            // 发邮件
                            client.Send(message);
                            client.Disconnect(true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
    View Code

    创建一个MailController:

     [Produces("application/json")]
        [Route("api/Mail")]
        public class MailController : Controller
        {
            public IConfiguration Configuration { get; }
    
            public MailController(IConfiguration configuration)
            {
                Configuration = configuration;
            }
            
            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            [HttpPost("/notice")]
            public IActionResult Notice()
            {
                var bytes = new byte[10240];
                var i = Request.Body.ReadAsync(bytes, 0, bytes.Length);
                var content = System.Text.Encoding.UTF8.GetString(bytes).Trim('');
                
                EmailSettings settings = new EmailSettings()
                {
                    SmtpServer = "smtp.126.com",    // 发送邮件的服务器地址
                    SmtpPort = 25,                  // 服务器端口号
                    AuthAccount = "",        // 用户名
                    AuthPassword = "",     // 密码
                    ToWho = "接收方名字",             // 接收方的名字
                    ToAccount = "",    // 接收方邮箱
                    FromWho = "你自己的名字",          //  发邮件的人姓名
                    FromAccount ="", //  发邮件的邮件地址
                    Subject = "health check notice" //  邮件标题
                };
    
                EmailHelper.SendHealthEmail(settings, content);
    
                return Ok();
            }
        }

    然后再创建emailserver.json 那么就ok了 ,重新启动集群。

    {
        "watches": [
        {
          "type": "checks",
          "handler_type": "http",
          "state": "critical",
          "http_handler_config": {
            "path": "http://10.211.55.4:8081/notice",
            "method": "POST",
            "timeout": "10s",
            "header": { "Authorization": [ "token" ] }
          }
        }
      ]
    }
  • 相关阅读:
    JSP语法学习笔记
    jsp 自定义标签
    java排序算法
    Linux系统rootpassword改动
    人生中第一次面试——北漂18年(1)
    msgsnd的一个小问题
    推荐系统中的矩阵分解演变方式
    FZU 2124 FOJ 2124 吃豆人【BFS】
    啦啦啦啦、新人学习中。。
    【Linux】线程并发拷贝程序
  • 原文地址:https://www.cnblogs.com/ZaraNet/p/10123291.html
Copyright © 2020-2023  润新知