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

Consul介绍:html

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

Consul的如何实现的?编程

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

微服务概念:bootstrap

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

尽管“微服务”这种架构风格没有精确的定义,但其具备一些共同的特性,如围绕业务能力组织服务、自动化部署、智能端点、对语言及数据的“去集中化”控制等等。简而言之,微服务架构风格是一种将单个应用程序开发为一套小型服务的方法,每一个小型服务都在本身的流程中运行,并与轻量级机制(一般是HTTP资源API)进行通讯。这些服务围绕业务功能构建,可经过全自动部署机制独立部署。这些服务至少集中管理,能够用不一样的编程语言编写,并使用不一样的数据存储技术。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=\tmp\consul -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("健康检查故障:\r\n"); 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('\0'); 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" ] } } } ] }
相关文章
相关标签/搜索