GVKun编程网logo

【NET CORE微服务一条龙应用】开始篇与目录(.net core 微服务)

15

在本文中,我们将为您详细介绍【NETCORE微服务一条龙应用】开始篇与目录的相关知识,并且为您解答关于.netcore微服务的疑问,此外,我们还会提供一些关于.NetCore微服务——Consul(3

在本文中,我们将为您详细介绍【NET CORE微服务一条龙应用】开始篇与目录的相关知识,并且为您解答关于.net core 微服务的疑问,此外,我们还会提供一些关于.Net Core微服务——Consul(3):健康检查、.Net Core微服务——服务发现:Consul(一)、.NET Core微服务之基于Consul实现服务治理、.NET Core微服务之基于Consul实现服务治理(续)的有用信息。

本文目录一览:

【NET CORE微服务一条龙应用】开始篇与目录(.net core 微服务)

【NET CORE微服务一条龙应用】开始篇与目录(.net core 微服务)

简介

    随着业务的发展和变更,项目原先的分布式框架应用业务发展已有些不适应,所以18年初开始准备使用微服务框架,当时正好看到了ocelot项目,特意翻看了源码,发现很灵活和易扩展

    于是就开始了微服务的开发与使用,现在已经使用了一年的时间,特意开了博客想把使用的经验与问题和大家进行探讨与学习。

    前段时间就准备写了,但是公司突然推出了两个产品,又忙碌在撸码的队伍中,最近终于有点时间进行整理

目录

【NET CORE微服务一条龙应用】网关使用

【NET CORE微服务一条龙应用】配置中心应用

【NET CORE微服务一条龙应用】认证授权与动态权限配置

【NET CORE微服务一条龙应用】错误码应用

【NET CORE微服务一条龙应用】消息总线应用

【NET CORE微服务一条龙应用】分布式调度应用

【NET CORE微服务一条龙应用】全局监听与定时任务

【NET CORE微服务一条龙应用】统一日志中心应用

【NET CORE微服务一条龙应用】Orm使用

【NET CORE微服务一条龙应用】子服务服务注册与服务发现使用

【NET CORE微服务一条龙应用】度量监控应用与扩展

【NET CORE微服务一条龙应用】链路追踪应用扩展与实时展示监听数据

【NET CORE微服务一条龙应用】gRpc使用

【NET CORE微服务一条龙应用】综合管理平台应用使用,包括用户中心、日志中心、配置中心、网关路由、链路追踪、服务管理

【NET CORE微服务一条龙应用】一键发布和测试之持续集成工具Jenkins

【NET CORE微服务一条龙应用】企业统一支付网关

【NET CORE微服务一条龙应用】应用部署

整体结构图

 还没绘制好...

 

项目源码

源码已上传github

https://github.com/q315523275/FamilyBucket

https://github.com/q315523275/FamilyBucket-UI

 

.Net Core微服务——Consul(3):健康检查

.Net Core微服务——Consul(3):健康检查

继续上一篇的话题,顺便放上一篇的传送门:点这里。

健康检查

经过之前的操作,我的consul已经支持自动扩展,并且调用也很靠谱。但是这里有个问题,一旦服务列表里的某个服务挂了,consul并不知道,还是会把实际无效的地址返回给我,就算重启consul容器也无法刷新到最新的状态。所以,咱们要监控服务可用性,主动区分出不可用服务,这种手段,就称之为健康检查。

进入编码环节。老规矩,还是进入到之前我封装好的注册方法,在注册时增加健康检查的内容:

       client.Agent.ServiceRegister(new AgentServiceRegistration()   {    ID = $"server {ip}:{port}",    Name = "shenzhen-ma",    Address = ip,    Port = int.Parse(port),    Tags = new string[] { weight },    Check = new AgentServiceCheck()    {     Interval = TimeSpan.FromSeconds(10),//每隔10秒发起检查     HTTP = $"http://{ip}:{port}/v1/client/base/index",//检查请求地址     Timeout = TimeSpan.FromSeconds(5),//超时时长5秒     DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10)//超过10秒还没能连接到服务,就开始注销本服务    }   });

变色部分就是健康检查的配置了。根据上面的配置,consul会周期性发起健康检查,并且根据结果自动移除不可用的服务。

这次我要严谨一些,用真实的远程服务器来模拟生产环境。手头服务器太多,很多有项目在跑。仔细翻了翻,发现还有两台相对空闲的服务器,一台是win server,另一台centos,嘿嘿,正好。centos做consul服务器,win服务器用来做下游调用方。

先把consul搞起来:

 进去访问下:

 OK了,现在转到另一台服务器跑几个客户端。这里偷个懒,直接把可运行文件拷贝过去,哈哈:

&n..............

.Net Core微服务——服务发现:Consul(一)

.Net Core微服务——服务发现:Consul(一)

先思考一些问题:它是做什么的、以及怎么使用它。带着这些问题往下走。

consul是做什么的

consul用于微服务下的服务治理。服务治理是什么?它包含但不限于:服务发现、服务配置、健康检查、键值存储、安全服务通信、多数据中心等。

为什么需要服务治理?举个例子:最开始的服务比较简单,各服务之间通过API就能访问。后面业务复杂了,服务也跟着复杂了,搞分布式了,而分布式又必然是多服务器部署,这就有一个问题:如果服务之间还是用API访问,那某个服务所在的服务器挂掉以后这个服务就不能用了,也不能自动转移,那么只能人肉运维了。这时候大家在想:如果下游调用上游,只需要一个统一的地址,不用关注负载均衡、节点失效之类的问题,也不用关注可用性,这些都有一个中间件来完成,那该有多好。这个中间件要做的事情,就是服务治理,也就是本文的consul,它就是解决这个事的。但其实也不是只有它能做这个事,zooKeeper、etcd也能做这个事,也没有什么高下之分,用什么主要看自己,看公司。对自己来说,哪个摸得透、玩的熟就用哪个。对公司来说,哪个市场认可度高就用哪个,说白了就是哪个用的人多。用的人多会的人就多,招人换人速度就快了,互联网企业追求的不就是速度么?“时间就是金钱,效率就是生命”,这句话早期在深圳随处可见,至今仍然适用。

题外话有点多,接着往下走。

怎么使用consul

这里只讲docker内的consul。首先下载一个镜像:

dokcer pull consul

然后运行起来:

docker run -itd -p 8700:8500 --name myconsuldemo consul

成功运行后能看到如下页面:

 tips:consul的默认端口是8500,docker启动可以映射到任意端口。

 服务注册

服务发现的概念,简单来说就是所有节点程序启动时都去consul注册一下,注册后的信息统一保存在consul中以供调用。是不是很简单?

现在net core 3.1下完成consul服务注册。

首先需要添加nuget包:

 然后自行封装一个注册服务,节省时间先上源码:

public static void Reg(IConfiguration configuration)  {   string ip = configuration.GetSection("ip").Value.ToString();   string port = configuration.GetSection("port").Value.ToString();   string weight = configuration.GetSection("weight").Value.ToString();   string address = configuration.GetSection("address").Value.ToString();//consul的启动地址   string center = configuration.GetSection("center").Value.ToString();//数据中心名称   ConsulClient client = ..............

.NET Core微服务之基于Consul实现服务治理

.NET Core微服务之基于Consul实现服务治理

Tip: 此篇已加入.NET Core微服务基础系列文章索引

一、Consul基础介绍

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

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

  关于Consul的更多介绍,比如优点,这里就不再赘述了,上网一搜就可以随处找到了。但是,必须贴一个和其他类似软件的对比:

  此外,关于Consul的架构以及相关的角色,如下图所示:

  要想利用Consul提供的服务实现服务的注册与发现,我们需要建立Consul Cluster。在Consul方案中,每个提供服务的节点上都要部署和运行Consul的Client Agent,所有运行Consul Agent节点的集合构成Consul Cluster。Consul Agent有两种运行模式:ServerClient。这里的Server和Client只是Consul集群层面的区分,与搭建在Cluster之上的应用服务无关。以Server模式运行的Consul Agent节点用于维护Consul集群的状态,官方建议每个Consul Cluster至少有3个或以上的运行在Server Mode的Agent,Client节点不限。

  Consul支持多数据中心,每个数据中心的Consul Cluster都会在运行于Server模式下的Agent节点中选出一个Leader节点,这个选举过程通过Consul实现的raft协议保证,多个 Server节点上的Consul数据信息是强一致的。处于Client Mode的Consul Agent节点比较简单,无状态,仅仅负责将请求转发给Server Agent节点。

二、Consul集群搭建

2.1 环境准备

  这里我准备了三台Linux(CentOS)虚拟机和一台Windows Server 2008 R2虚拟机,借助VMware Workstation搭建,如下图所示。

  其中,192.168.80.100会作为leader角色,其余两台192.168.80.101和192.168.80.102会作为follower角色。当然,实际环境中leader角色不会是一个固定的,会随着环境的变化(比如Leader宕机或失联)由算法选出新的leader。在进行下面的操作会前,请确保三台节点能够相互ping通,并能够和宿主机也ping通。另外,192.168.80.71会作为client角色,并且和其余三台虚拟机互相ping通。

2.2 下载Consul

  Consul的下载很简单,直接去:https://www.consul.io/downloads.html 选择对应的平台即可。

  这里我们的linux虚拟机选择的是Linux版本:

  

  下载之后是一个zip文件,我们通过XFtp等工具将其传送到我们的linux节点中即可。

  而Windows Server虚拟机选择的是Windows版本,不再赘述。

2.3 安装与配置Consul

  1.解压Consul.zip:

  分别在三台节点中解压,解压命令:

> unzip consul_1.1.0_linux_386.zip   

  解压之后将consul复制到我们的自定义文件目录中,比如:/usr/local/consul

> cp consul /usr/local/consul

  2.设置环境变量

  分别在三台节点中设置环境变量:

> vim /etc/profile  

  在profile中增加一行CONSUL_HOME并更改PATH:

# Consul

export CONSUL_HOME=/usr/local/consul

export PATH=$PATH:$JAVA_HOME/bin:$CONSUL_HOME;  

  使得配置生效

> source /etc/profile

  测试是否生效,在三个节点测试输入consul

> consul

  看到下图所示的命令提示,就代表OK了。

  

  3.启动Server(s)

  分别在三台节点上执行以下命令即可启动Consul

192.168.80.100>consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=consul-1 -client=0.0.0.0 -bind=192.168.80.100 -datacenter=dc1

192.168.80.101>consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=consul-2 -client=0.0.0.0 -bind=192.168.80.101 -datacenter=dc1 -join 192.168.80.100

192.168.80.102>consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=consul-3 -client=0.0.0.0 -bind=192.168.80.102 -datacenter=dc1 -join 192.168.80.100

  注意101和102的启动命令中,有一句 -join 192.168.80.100 => 有了这一句,就把101和102加入到了100所在的集群中。

  启动之后,集群就开始了Vote(投票选Leader)的过程,通过下面的命令可以看到集群的情况:

  

  在Windows Server虚拟机上启动:

> consul agent -bind 0.0.0.0 -client 192.168.80.71 -data-dir=C:\Counsul\tempdata -node EDC.DEV.WebServer -join 192.168.80.100

  启动后会有如下提示:

  

  4.通过UI查看集群

  Consul不仅提供了丰富的命令查看集群情况,还提供了一个WebUI,默认端口8500,我们可以通过访问这个URL(eg.http://192.168.80.100:8500)得到如下图所示的WebUI:

  可以看到三个节点都正常启动,下面我们就来试试向Consul注册一下我们基于ASP.NET Core的WebAPI服务。

  5.模拟Leader挂掉,查看Consul集群的新选举Leader

  这里我暴力一点直接将Leader节点关机:shutdown -h now,可以看到我们的80.100已经挂了。

  

  查看其余两个节点的日志可以发现,consul-3 (80.102)被选为了新的leader:

  

  当然,也可以通过80.101或102的WebUI查看:

  也可以通过以下命令查看目前的各个Server的角色状态:

> consul operator raft list-peers

  

  虽然这里80.100这个原leader节点挂掉了,但是只要超过一半的Server(这里是2/3还活着)还活着,集群是可以正常工作的,这也是为什么像Consul、ZooKeeper这样的分布式管理组件推荐我们使用3个或5个节点来部署的原因。

三、ASP.NET Core WebAPI服务注册

3.1 准备一个ASP.NET Core WebAPI程序

  Step1.创建一个ASP.NET Core WebAPI程序

  

  Step2.创建一个HealthController用于Consul的健康检查

复制代码
[Produces("application/json")]
    [Route("api/Health")]
    public class HealthController : Controller
    {
        [HttpGet]
        public IActionResult Get() => Ok("ok");
    }
复制代码

  *.Consul会通过call这个API来确认Service的健康状态

  Step3.改写启动代码,调用Consul API注册服务

  (1)通过Nuget安装Consul的.NET客户端

PM> install-package Consul

  (2)基于IApplicationBuilder写一个扩展方法,用于调用Consul API

复制代码
public static class AppBuilderExtensions
    {
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ServiceEntity serviceEntity)
        {
            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 = $"http://{serviceEntity.IP}:{serviceEntity.Port}/api/health",//健康检查地址
                Timeout = TimeSpan.FromSeconds(5)
            };

            // Register service with consul
            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();//服务停止时取消注册
            });

            return app;
        }
复制代码

  *.这里主要是参考的田园的蟋蟀的Code,链接见参考资料部分

  (3)在Starup类的Configure方法中,调用此扩展方法

复制代码
// 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();
            // register this service
            ServiceEntity serviceEntity = new ServiceEntity
            {
                IP = NetworkHelper.LocalIPAddress,
                Port = Convert.ToInt32(Configuration["Service:Port"]),
                ServiceName = Configuration["Service:Name"],
                ConsulIP = Configuration["Consul:IP"],
                ConsulPort = Convert.ToInt32(Configuration["Consul:Port"])
            };
            app.RegisterConsul(lifetime, serviceEntity);
        }
复制代码

  其中ServiceEntity类定义如下:

  View Code

  其中用到了appSettings.json配置文件,其定义如下:

  View Code

  *.这段代码不再解释,一眼就能看懂。另外,除了调用Consul API之外,还可以通过配置文件的方式,例如以下配置文件格式,这里不再演示。

  View Code

  Step4.保留默认创建的ValuesController,其余不再创建任何API,不是本次实验的重点。当然,你可以集成一下Swagger,这样有个界面文档可以看。

  这里我默认跳转到healthcontroller:

  

3.2 发布到IIS

  Step1.在.NET Core程序中进行发布很简单,既可以采用原来在VS里边创建配置文件进行发布,也可以使用命令行(例如:dotnet publish),这里我还是在VS里面发布,得到Release文件

  Step2.通过Ftp工具copy到Windows Server虚拟机中

  Step3.这里我的Windows Server虚拟机是2008 R2,需要装一个Windows Server Hosting,下载地址:点我点我。如果不安装这个,你的IIS是跑不起来.NET Core程序的。

  Step4.按照你熟悉的方式在IIS中添加一个网站(服务):

  

  Step5.更改默认应用程序池的.net framework版本为“无托管代码”。

  

  Step6.照理说,到这里就OK了,点击浏览访问,TMD,给我报了个502.5的错误

  

  于是乎网上一阵搜索,发现需要打个补丁(Windows6.1-KB2533623-x64.msu),下载地址:点我点我。

  Step7.安装补丁之后,重启IIS,可以成功访问了=>确保Consul能够call到我们的服务的health API。

3.3 查看Consul集群状态

  Step1.访问Consul的WebUI查看服务是否注册成功:可以看到我们的ClientService已成功注册

  Step2.Consul不仅仅提供了服务注册,还提供了服务发现,我们可以通过调用其提供的API来发现服务的IP和Port。

Url>http://192.168.80.100:8500/v1/catalog/service/CAS.NB.ClientService  

  *.我们可以看到返回了ClientService的ServiceAddress和ServicePort,就可以通过其组成URL进行服务调用了。当然,我们可能会对一个服务部署多个实例,以组成集群来实现负载均衡。我们可以设置一些负载均衡的策略,假设通过取模运算随机选择一个服务地址返回给服务消费者

  Step3.这里我们将发布的Release文件在Windows Server虚拟机上copy一份,并改一下配置文件,让其ServiceName变为CAS.NB.ProductService,其Port变为8820,在IIS上再添加一个网站,启动起来,再通过WebUI查看Consul集群状态:

  Step4.这时我们再通过以下API进行服务发现:

Url>http://192.168.80.100:8500/v1/catalog/service/CAS.NB.ProductService

  

四、小结与后续工作

  本篇主要基于一个最小化的集群搭建了一个Consul服务治理组件,并将ASP.NET Core API程序注册到了Consul,并尝试通过Consul进行服务发现(虽然没有模拟具体的服务消费)。本篇没有仔细讲述Consul的介绍、优点、缺点,因为本人也没有啥实际的经验,因此只能是站在其他园友的肩膀上做个小实验。ASP.NET Core是一个天生适合微服务的技术,也希望能在我们的学习和推动下,让公司把.NET Core应用起来,将来能够跑在Linux和Docker上,这是我目前的目标,与大家共勉。

  后续我会继续尝试基于Ocelot构建API网关,到时会结合Consul进行进一步的集成。另外,还会尝试Polly进行熔断降级、Identity Server进行验证,Exceptionless作分布式日志,基本上会遵循.NET Core大队长张善友的微服务示例项目NanoFabric用到的(或者说是给我们安利的技术框架)那些开源技术来搭建一个初步的微服务架构,以便于以后在公司内部推广和应用。此外,考虑到公司目前的微服务架构是基于Java的(Spring Cloud),那么也会考虑通过 Steeltoe 来和Spring Cloud进行兼容,让Java和.Net Core微服务能够共存(可以参考资料里的第7个,田园里的蟋蟀出品)。这里,也安利一下正在学习微服务的.NET Coder们,可以看看张善友老师的NanoFabric,或者是杨中科老师的.NET Core微服务课程。

  

  最近很多朋友问我为什么不再写技术文了,老是写一些观后感、读后感之类的,一来因为读那些书其实也是我今年的个人OKR,二来这半年来的确不想看技术书和资料,最后因为身体原因没法过多地熬夜。现在学习.NET Core以来被其深深吸引,就像是找到了一个那些年我们追过的女孩儿,觉得它样样都美,很想跟它继续走下去,发现它更多的美,因此也会趁着微服务学习的劲跟大家分享更多的文章。

  

附件下载

  示例代码:点我下载

参考资料

(1)田园里的蟋蟀,《Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践》

(2)不小下,《服务发现 - consul 的介绍、部署和使用》

(3)二胡槽子,《我是服务的执政官-服务发现和注册工具consul简介》

(4)大副,《consul分布式集群搭建&简单功能测试&故障恢复》

(5)94cool,《win2008server R2 x64 部署.net core到IIS》

(6)杨中科《.NET Core微服务课件》

(7)田园里的蟋蟀,《.NET Core 微服务架构 Steeltoe 使用(基于 Spring Cloud)》

 

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

.NET Core微服务之基于Consul实现服务治理(续)

.NET Core微服务之基于Consul实现服务治理(续)

Tip: 此篇已加入.NET Core微服务基础系列文章索引

上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧。

一、Consul服务注册之配置文件方式

1.1 重温Consul实验集群

  这里我们有三个Consul Server节点,一个Consul Client节点,在Client节点上跑了两个ClientService实例,分别占用8810和8820端口。至于基于Ocelot的API网关服务,还没有实现,留到以后跟各位分享。这里假设我们已经启动了这几个节点,并且能够成功访问这两个ClientService实例(事先把实例启动起来,可以通过IIS,也可以通过命令行启动Kerstel服务器运行)。

  实例1:192.168.80.71:8810

  

  实例2:192.168.80.71:8820

  

1.2 准备好json配置文件

  这里我准备了一个如下所示的JSON配置文件(eg.取名为services_config.json),配置了两个服务在里边:

{
    "services":[
        {
            "id": "EDC_DNC_MSAD_CLIENT_SERVICE_01",
            "name" : "CAS Client Service",
            "tags": [
                "urlprefix-/ClientService01"
            ],
            "address": "192.168.80.71",
            "port": 8810,
            "checks": [
                {
                    "name": "clientservice_check",
                    "http": "http://192.168.80.71:8810/api/health",
                    "interval": "10s",
                    "timeout": "5s"
                }
            ]
        },
      {
            "id": "EDC_DNC_MSAD_CLIENT_SERVICE_02",
            "name" : "CAS Client Service",
            "tags": [
                "urlprefix-/ClientService02"
            ],
            "address": "192.168.80.71",
            "port": 8820,
            "checks": [
                {
                    "name": "clientservice_check",
                    "http": "http://192.168.80.71:8820/api/health",
                    "interval": "10s",
                    "timeout": "5s"
                }
            ]
        }
     ]
}

  至于配置文件的含义,这里不再赘述,和上一篇在代码中进行注册的items一致。

  编辑完成后,我们在Consul Client节点中新建一个文件夹,放入json配置文件,然后启动/重启Consul Client服务:

192.168.80.71>consul agent -bind 0.0.0.0 -client 192.168.80.71 -config-dir=C:\Server\Consul\config -data-dir=C:\Server\Consul\tempdata -node EDC.DEV.WebServer -join 192.168.80.100 

  

  启动之后,可以看到Consul已经通过扫描配置文件,去注册了这两个ClientService的实例。

1.3 通过WebUI查看服务状况

  

  可以看到,两个ClientService实例已经成功注册。

1.4 通过API进行服务发现

URL>192.168.80.100:8500/v1/catalog/service/CAS Client Service  

  

  可以看到返回了两个服务实例的信息,当然,这里建议服务名还是不要有空格为好。此外,在服务发现的过程中,会加以一定的负载均衡策略,从这两个服务实例中选择一个返回给服务消费端,比如:随机、轮询、加权轮询、基于性能的最小连接数等等。关于这一块,会在后面的API网关实践中跟大家分享。

二、Consul集群之Key/Value存储

  Consul除了可以实现服务注册和服务发现之外,还提供了强大的KV(Key/Value)存储。我们可以使用Consul的分层KV存储干任何事情,比如:动态配置,特征标记,协调,leader选举等。KV存储的API是基于http的。

2.1 查看所有KV

  我们可以通过命令行在consul节点中进行查询:

192.168.80.100>curl -v http://192.168.80.100:8500/v1/kv/?recurse  

  

  可以看到,返回的是404 Not Found,可见现在木有一个Key/Value存储项。

  *.关于?recurse参数=>用来指定查看多个KV

  当然我们也可以通过WebUI来查看和管理KV,如下图所示,后续我们都以Shell命令行来调用API,不会进行WebUI界面的调用。

  

2.2 新增KV

  这里假设我们要配置一个视频直播平台的账号:

192.168.80.100>curl -X PUT -d ''edisonchou'' http://192.168.80.100:8500/v1/kv/web/vhallaccount

  key:vhallaccount, value:edisonchou

  添加后可以通过如下命令调用接口查看这个Key的Value

192.168.80.100>curl http://192.168.80.100:8500/v1/kv/web/vhallaccount

  

  *.由于Consul的Value是经过Base64编码的(主要是为了允许非UTF-8的字符),所以这里看到的是编码后的结果。我们可以通过解码得到最终的Value值。

2.3 验证KV是否同步

  由于我们调用的是Leader节点进行的KV存储,我们想要验证一下是否在另外两个节点进行了同步,否则KV只存在一个节点达不到同步的效果。

  192.168.80.101 节点:

  

  192.168.80.102 节点:

  

  可以看到该key值已经在集群中三个节点进行了同步。

2.4 编辑KV和删除KV

  编辑KV其实和添加KV完全一致,如下所示:

192.168.80.100>curl -X PUT -d ''andyai'' http://192.168.80.100:8500/v1/kv/web/vhallaccount  

  删除KV主要用到HTTP DELETE

192.168.80.100>curl -X DELETE http://192.168.80.100:8500/v1/kv/web/vhallaccount  

  这里不再演示结果。

三、Consul服务告警之Watch机制

  熔断保护在Consul和Ocelot中都有实现,意思就是当一个服务不正常时(比如我们的一个服务实例挂了,Consul的健康检查机制检测到了),应该给系统维护人员给以告警。在Consul中,服务告警也是通过配置文件来实现的。

3.1 添加watch.json配置文件

{
  "watches": [
    {
      "type": "checks",
      "handler_type": "http",
      "state": "critical",
      "http_handler_config": {
        "path": "http://192.168.80.71:9000/notice",
        "method": "POST",
        "timeout": "10s",
        "header": { "Authorization": [ "token" ] }
      }
    }
  ]
}

  *.有关watch的细节,请参考:https://www.consul.io/docs/agent/watches.html

  这里编辑完成之后,就可以放到config目录下了,后面重启Consul Client Agent服务时会加载新的watches_config.json配置文件。

  

3.2 添加NoticeService服务

 新写一个ASP.NET Core WebAPI程序,其主要功能就是接受Consul POST过来的参数并调用方法发送电子邮件。

  (1)Controller编写

[Route("api/[controller]")]
    public class HomeController : Controller
    {
        public IConfiguration Configuration { get; }

        public HomeController(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        [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 = Configuration["Email:SmtpServer"],
                SmtpPort = Convert.ToInt32(Configuration["Email:SmtpPort"]),
                AuthAccount = Configuration["Email:AuthAccount"],
                AuthPassword = Configuration["Email:AuthPassword"],
                ToWho = Configuration["Email:ToWho"],
                ToAccount = Configuration["Email:ToAccount"],
                FromWho = Configuration["Email:FromWho"],
                FromAccount = Configuration["Email:FromAccount"],
                Subject = Configuration["Email:Subject"]
            };

            EmailHelper.SendHealthEmail(settings, content);

            return Ok();
        }
    }

  不再解释这段代码。

  (2)SendHealthEmail方法编写

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);
            }
        }

  这里使用的是MailKit库(支持.net core),可以通过NuGet搜索并安装,此外为何接受的参数属性是这些,大家可以看看Consul官方文档中watches页中的checks类型,见下图所示:

  

  (3)发布NoticeService到192.168.80.71服务器中,同样也可以加入Consul配置文件中:

{
    "services":[
        {
            "id": "EDC_DNC_MSAD_CLIENT_SERVICE_01",
            "name" : "CAS.Client.Service",
            "tags": [
                "urlprefix-/ClientService01"
            ],
            "address": "192.168.80.71",
            "port": 8810,
            "checks": [
                {
                    "name": "clientservice_check",
                    "http": "http://192.168.80.71:8810/api/health",
                    "interval": "10s",
                    "timeout": "5s"
                }
            ]
        },
    {
            "id": "EDC_DNC_MSAD_CLIENT_SERVICE_02",
            "name" : "CAS.Client.Service",
            "tags": [
                "urlprefix-/ClientService02"
            ],
            "address": "192.168.80.71",
            "port": 8820,
            "checks": [
                {
                    "name": "clientservice_check",
                    "http": "http://192.168.80.71:8820/api/health",
                    "interval": "10s",
                    "timeout": "5s"
                }
            ]
        },
    {
            "id": "EDC_DNC_MSAD_NOTICE_SERVICE",
            "name" : "CAS.Notice.Service",
            "tags": [
                "urlprefix-/NoticeService"
            ],
            "address": "192.168.80.71",
            "port": 9000,
            "checks": [
                {
                    "name": "noticeservice_check",
                    "http": "http://192.168.80.71:9000/api/health",
                    "interval": "10s",
                    "timeout": "5s"
                }
            ]
        }
     ]
}
View Code

  发布完成之后,重启Consul Client节点(192.168.80.71)的Consul服务,可以看到NoticeService也注册成功:

  

3.3 测试服务告警

 (1)手动在IIS中关闭一个ClientService服务,例如:这里我关闭了ClientService.01

  

 (2)查看自动发送的Email内容:从Email中我们可以知道哪个Server节点的哪个Service出了问题,并且可以大概了解原因(Check Output),这时我们的系统维护人员就该起床加班了。

  

  *.需要注意的是确保你的虚拟机可以访问外网,不然是发布出来Email的。

4.小结

  本篇将上篇中遗留的内容进行了弥补,下篇将开始基于Ocelot+Polly的API网关服务实践,敬请期待,我要睡了。

  

  此外,今天是高考第二天,也预祝各位高三学子高考成功,加油最后两科!

  

参考资料

桂素伟,《Ocelot+Consul实践》

卓一抗,《学习Consul》

陈冲,《Consul分布式集群搭建&简单功能测试&故障恢复》

 

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

今天关于【NET CORE微服务一条龙应用】开始篇与目录.net core 微服务的分享就到这里,希望大家有所收获,若想了解更多关于.Net Core微服务——Consul(3):健康检查、.Net Core微服务——服务发现:Consul(一)、.NET Core微服务之基于Consul实现服务治理、.NET Core微服务之基于Consul实现服务治理(续)等相关知识,可以在本站进行查询。

本文标签: