consul实现服务治理(代码片段)

Leo_wlCnBlogs Leo_wlCnBlogs     2022-11-21     122

关键词:

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

https://www.cnblogs.com/edisonchou/p/9124985.html

一、Consul基础介绍

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

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

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

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

  要想利用Consul提供的服务实现服务的注册与发现,我们需要建立Consul Cluster。在Consul方案中,每个提供服务的节点上都要部署和运行Consul的agent,所有运行Consul Agent节点的集合构成Consul Cluster。Consul Agent有两种运行模式:Server和Client。这里的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大队长张善友的POC-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

.netcore微服务之:基于consul实现服务治理

...技术A本篇文章为.NETCore实现企业级微服务架构技术点介绍Consul是一个分布式,高可用、支持多数据中心的服务注册、发现、健康检查和配置共享的服务软件。由HashiCorp公司用Go语言开发推出的开源产品用于实现分布式系统的服务... 查看详情

分布式服务治理zookeeper原理及使用大全(代码片段)

...是可以集群化的。实现上是基于观察者模式。不想eureka/consul等同类产品需要心跳机制 查看详情

一篇文章了解consul服务发现实现原理(代码片段)

从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后来逐步应用于生产环境,并总结了少许使用经验。   最开始使用Consul的人不多,这两年微服务越来越火,使用Consul的人也越来越多。经常有人会问一些... 查看详情

部署consul服务实现docker容器跨主机通信(代码片段)

consul数据中心的含义,可以将其当做数据库来理解,类似于Redis等非关系型数据库,采用的是键-值对的方式,存放着各个容器的IP及端口信息。consul的功能很强大,可以以群集的方式运行,并且具备健康监测等功能。环境如下dock... 查看详情

centos安装consul微服务(代码片段)

一、简介    Consul([?k?nsl],康搜)是注册中心,服务提供者、服务消费者等都要注册到Consul中,这样就可以实现服务提供者、服务消费者的隔离。除了Consul之外,还有Eureka、Zookeeper等类似软件。consul是存储服务名... 查看详情

springcloud分布式之consul探索(代码片段)

文章目录consul安装后台启动客户端注册pom引入配置文件启动注解订单调用consul集群搭建docker安装单机安装可以忽略docker默认IPconsul运行原理之前罗列了eureka作为服务治理的整合,并简单介绍了eureka的工作原理。eureka在cap理论... 查看详情

winserver的consul部署实践与.netcore客户端使用(附demo源码)(代码片段)

原文:winserver的consul部署实践与.netcore客户端使用(附demo源码)前言随着微服务兴起,服务的管理显得极其重要。都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的服务,每个服务可以在短周期内重构、迭... 查看详情

.net6使用consul实现服务注册与发现(代码片段)

...微服务项目,大多数都上了k8s,基本上都看不到Consul的身影,所以在工作之余折腾了下Consul,作为个人来讲还是得学习下,所以也就顺便通过文章来记录下学习过程。还有就是现在基本上只要提到微服务,... 查看详情

docker+consul+registrator实现服务自动注册与发现(代码片段)

...就不多介绍了,毕竟已经火遍大街小巷了,主要了解一下Consul、Registrator、Consul-tpmplate。consul:是一个服务网格解决方案,它是一个一个分布式的、高可用的系统,而且开发使用都很简单、方便、它主要提供了一个功能齐全的控... 查看详情

基于etcd实现大规模服务治理应用实战(代码片段)

架构师(JiaGouX)我们都是架构师!架构未来,你来不来?err!=b:=tx.Bucket([]v:=b.Get([]fmt.Println(tx.Commit()*Cursor)search(key[]byte,pgidpgid)p,n:=p!=&&(p.flags&(branchPageFlag|leafPageFlag))==panic(fmt.e:=elemRe 查看详情

springcloud:服务治理——springcloudeureka(代码片段)

...治理是微服务架构中最为核心和基础的模块,主要作用是实现各个微服务实例的自动化注册和发现。SpringCloudEureka是SpringCloudNetflix微服务套件中的一部分,基于NetflixEureKa做了二次封装,主要负责微服务架构中的服务治理功能。 ... 查看详情

springcloud-2.0(7.服务注册发现-consul)(代码片段)

...eper下一篇:8.负载均衡-Ribbon文章目录1.简介1.1什么是[Consul](https://so.csdn.net/so/search?q=Consul&spm=1001.2101.3001.7020)1.2作用1.3下载地址1.4中文文档1.5启动Consul2.服务提供者Provider3.服务消费者Consumer4.三个注册中心异同点4.1背景... 查看详情

springcloud——consul服务注册中心的介绍安装与使用(代码片段)

Consul介绍用于实现分布式系统的服务发现与配置,内置了服务注册与发现框架,分布一致性协议实现,健康检查,Key/Value存储,多数据中心方案,不再需要依赖其它工具,使用起来比较简单Consul特性Raft... 查看详情

winserver的consul部署实践与.netcore客户端使用(附demo源码)(代码片段)

 前言随着微服务兴起,服务的管理显得极其重要。都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的服务,每个服务可以在短周期内重构、迭代、交付。随着微服务的数量增多,因量变引起了质量,... 查看详情

winserver的consul部署实践与.netcore客户端使用(附demo源码)(代码片段)

前言随着微服务兴起,服务的管理显得极其重要。都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的服务,每个服务可以在短周期内重构、迭代、交付。随着微服务的数量增多,因量变引起了质量,带来... 查看详情

springcloudconsul

SpringCloudConsul项目是针对Consul的服务治理实现。Consul是一个分布式高可用的系统,它包含多个组件,但是作为一个整体,在微服务架构中为我们的基础设施提供服务发现和服务配置的工具。它包含了下面几个特性:服务发现健康... 查看详情

springboot(微服务)注册分布式consul(代码片段)

Consul是什么Consul是一个基于HTTP的服务发现工具,用于配置和管理系统和服务之间的依赖关系。它提供了一个简单的方式来注册、发现和配置服务,并包括健康检查、负载均衡和故障转移等功能。Consul是一种分布式系统... 查看详情

java之springcloud微服务搭建consul(第一个阶段)springboot项目实现商品服务器端是调用(代码片段)

Eureka替换方案ConsulEureka替换方案Consul1、Eureka闭源的影响(1)Eureka闭源影响(2)Eureka的替换方案2、什么是consul(1)consul概述(2)consul与Eureka的区别1)一致性2)开发语言和使用(3)... 查看详情