实战中的asp.net core结合Consul集群&Docker实现服务治理
0、目录
整体架构目录:ASP.NET Core分布式项目实战-目录
一、前言
在写这篇文章之前,我看了很多关于consul的服务治理,但发现基本上都是直接在powershell或者以命令工具的方式在服务器上面直接输入consul agent .... 来搭建启动consul集群,一旦把命令工具关掉,则consul无法再后台启动,尤其是在linux系统中。
如果在window系统中,采用bat文件到时可以做成开机自启,或者在linux中把命令做成一个service 服务文件来启动就可以实现后台运行。
因此为了社区能更好的发展技术,且能把consul应用在生产环境中,我认真回顾了在公司项目中的应用,特此把我开发及总结的分享给大家,此篇文章采用docker引擎,并且只涉及到consul集群部署以及结合asp.net core微服务注册。
当然如果内容有涉及安全隐患的,大家可以积极留言,共同进步。
注:以下所涉及到部署过程全部经过楼主我反复的验证,总结得来。大家在应用的过程中如果出现问题,可以留言咨询。
二、部署consul集群
1、介绍一下Consul
consul 关键特性
服务发现:支持服务发现。你可以通过 DNS 或 HTTP 的方式获取服务信息。
健康检查:支持健康检查。可以提供与给定服务相关联的任何数量的健康检查(如 web 状态码或 cpu 使用率)。
K/V 存储:键/值对存储。你可用通过 consul 存储如动态配置之类的相关信息。
多数据中心:支持多数据中心,开箱即用。
WEB UI:支持 WEB UI。点点点,你就能够了解你的服务现在的运行情况,一目了然,对开发运维是非常友好的。
说明:
在Consul方案中,每个提供服务的节点上都要部署和运行Consul的Client 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与其他工具的比较
consul的端口解释
好了,该介绍的已经介绍了,接下来就是正式部署吧
2、Docker上运行Consul
第一步:安全配置,适用授权和数据加密传输(生产环境是必须的)
为了consul的安全,需要进行gossip加密以及RPC加密结合TLS。
Gossip加密:主要用于节点间的接收发送集群信息安全。
RPC加密:主要用于Agent之间调用RPC授权的安全性。
此处大家可以参考官网或者一下资料:
https://www.jianshu.com/p/3d074ed76a68
https://www.consul.io/docs/agent/encryption.html
第二步:consul集群部署
准备服务器(可以采用虚拟机部署)
名称 | IP | |
CentOS7-1 | server1 | 192.168.216.160 |
CentOS7-2 | server2 | 192.168.216.161 |
CentOS7-3 | server3 | 192.168.216.162 |
CentOS7-4 | client1 | 192.168.216.163 |
vs 2017 | project部署在docker上 | 192.168.216.163 |
部署server1
docker run -d --net=host -v $PWD/data:/consul/data -v $PWD/config:/consul/config --restart always --name consulServer1 consul agent -server -bind=192.168.216.160 -node=server1 -bootstrap-expect 3 -data-dir=/consul/data -config-file=/consul/config -client 0.0.0.0 -ui
部署server2
docker run -d --net=host -v $PWD/data:/consul/data -v $PWD/config:/consul/config --restart always --name cs2 consul agent -server -bind=192.168.216.161 -node=server2 -bootstrap-expect 3 -data-dir=/consul/data -config-file=/consul/config -client 0.0.0.0 -ui -retry-join=192.168.216.160
部署server3
docker run -d --net=host -v $PWD/data:/consul/data -v $PWD/config:/consul/config --restart always --name cs3 consul agent -server -bind=192.168.216.162 -node=server3 -bootstrap-expect 3 -data-dir=/consul/data -config-file=/consul/config -client 0.0.0.0 -ui -retry-join=192.168.216.160
部署client-连接server
docker run -d --net=host -v $PWD/data:/consul/data -v $PWD/config:/consul/config --restart always --name cc1 consul agent -bind=192.168.216.163 -node=client1 -data-dir=/consul/data -config-file=/consul/config -client 0.0.0.0 -retry-join=192.168.216.160
注:(针对以上的参数以及配置解释)
1、此处的数据挂载就是把容器内的data以及配置挂载到外部地址,$PWD代表当前目录即你运行docker命令时的目录,当然$PWD可以替换为具体的路径。
2、-data-dir=/consul/consul -config-file=/consul/config :这两个地方代表在consul启动后会把数据以及配置文件放到指定的目录下,这个对于在服务器模式下运行的代理尤其重要,因为它们必须能够保持群集状态。
3、总结,以上两点结合就是说明 consul产生的数据然后挂载在外部地址进行持久化存储。
4、server端 的-client 参数可以不用,官方推荐是 服务注册到client端,由client端再把数据统一提交到server端。
参数说明
-client : 0.0.0.0 代表绑定到所有接口的选项,如果没有此选项,则asp.net core无法进行服务注册使用
-bind :该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的
--net=host 使得docker容器越过了net namespace的隔离,免去手动指定端口映射的步骤
-retry-join 允许你在第一次失败后进行尝试,加入一个已经启动的agent的ip地址
-bootstrap-expect 提供的server节点数目
-ui 启动自有主机的界面
-data-dir :提供一个目录用来存放agent的状态,所有的agent允许都需要该目录,该目录必须是稳定的,系统重启后都继续存在
CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}:在0.7版本之后默认是true,因此不是必须的。
CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}:在0.7版本之后默认是true,因此不是必须的。如果启用,当代理收到TERM信号时,它将向Leave群集的其余部分发送消息并正常离开
打开浏览器器查看 consul :
看所有consul节点情况
docker exec -t cs1 consul members
查看server的状态,以及哪一个节点是leader
docker exec -t cs1 consul operator raft list-peers
注:
如果其中一台或者多台server端挂掉,则Consul集群就会重新选举新的Leader,
但是一旦挂掉阿的节点数量超过一半,则Consul集群就无法工作了。
三、asp.net core微服务进行服务注册
1、新建一个项目asp.net core webapi项目
引入 consul ,nuget包
2、在控制器中新建一个控制器Health,代表健康检查
[Produces("application/json")]
[Route("api/Health")]
public class HealthController : Controller
{
[HttpGet]
public IActionResult Get() => Ok("ok");
}
3、然后在appsetting.json中添加配置文件
需要手动配置一下地址和端口号。
{
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
},
"ServiceRegister": { //服务注册
"IsActive": true,
"ServiceName": "testconsul6",
"ServiceHost": "192.168.216.163",
"ServicePort": ,
"Register": {
"HttpEndpoint": "http://192.168.216.163:8500"
}
}
}
4、这一步是服务注册的类
ServiceRegisterOptions.cs
public class ServiceRegisterOptions
{
/// <summary>
/// 是否启用
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; }
/// <summary>
/// 服务IP或者域名
/// </summary>
public string ServiceHost { get; set; }
/// <summary>
/// 服务端口号
/// </summary>
public int ServicePort { get; set; }
/// <summary>
/// consul注册地址
/// </summary>
public RegisterOptions Register { get; set; }
}
RegisterOptions.cs
public class RegisterOptions
{
public string HttpEndpoint { get; set; }
}
5、在startup.cs 中的服务注册
public void ConfigureServices(IServiceCollection services)
{
#region 服务注册基础信息配置
services.Configure<ServiceRegisterOptions>(Configuration.GetSection("ServiceRegister"));
services.AddSingleton<IConsulClient>(p => new ConsulClient(cfg =>
{
var serviceConfiguration = p.GetRequiredService<IOptions<ServiceRegisterOptions>>().Value;
if (!string.IsNullOrEmpty(serviceConfiguration.Register.HttpEndpoint))
{
cfg.Address = new Uri(serviceConfiguration.Register.HttpEndpoint);
}
}));
#endregion services.AddMvc();
}
在Configure 方法中配置代码
private static void RegisterService(IApplicationBuilder app,
IOptions<ServiceRegisterOptions> serviceRegisterOptions,
IConsulClient consul,
IApplicationLifetime appLife)
{
var serviceId = $"{serviceRegisterOptions.Value.ServiceName}_{serviceRegisterOptions.Value.ServiceHost}:{serviceRegisterOptions.Value.ServicePort}"; var httpCheck = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(),//服务启动多久后注册
Interval = TimeSpan.FromSeconds(),//健康检查时间间隔,或者称为心跳间隔
HTTP = $"http://{serviceRegisterOptions.Value.ServiceHost}:{serviceRegisterOptions.Value.ServicePort}/api/health",//健康检查地址
}; var registration = new AgentServiceRegistration()
{
Checks = new[] { httpCheck },
Address = serviceRegisterOptions.Value.ServiceHost,
ID = serviceId,
Name = serviceRegisterOptions.Value.ServiceName,
Port = serviceRegisterOptions.Value.ServicePort
//Tags = new[] { $"urlprefix-/{serviceRegisterOptions.Value.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
};
//.GetAwaiter().GetResult()
consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult(); appLife.ApplicationStopping.Register(() =>
{
consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();//服务停止时取消注册
});
}
#endregion
自此,可以把我们的项目部署到163服务器上面的docker上啦。
我们看一下效果,成功注册到了
参考资料:
Conusl TLS配置:
https://www.jianshu.com/p/3d074ed76a68
https://www.consul.io/docs/agent/encryption.html
consul 参数配置:
https://blog.csdn.net/zl1zl2zl3/article/details/79622476
consul服务治理:
http://michaco.net/blog/ServiceDiscoveryAndHealthChecksInAspNetCoreWithConsul
https://www.cnblogs.com/myzony/p/9168851.html
https://www.cnblogs.com/edisonchou/p/9124985.html
asp.net Core 交流群: 欢迎加群交流
如果您认为这篇文章还不错或者有所收获,您可以点击右下角的【推荐】按钮精神支持,因为这种支持是我继续写作,分享的最大动力!
微信公众号:欢迎关注 QQ技术交流群: 欢迎加群
实战中的asp.net core结合Consul集群&Docker实现服务治理的更多相关文章
- .net core结合Consul集群&Docker实现服务治理
实战中的asp.net core结合Consul集群&Docker实现服务治理 https://www.cnblogs.com/guolianyu/p/9614050.html 0.目录 整体 ...
- ASP.NET Core使用Docker-Swarm集群部署实现负载均衡实战演练
一.需求背景 人生苦短,我用.NET Core!阿笨对Docker是这样评价的:Docker在手,环境我有!Docker出手,集群我有!前面的Doc基础课程我们学习了如何使用Docker来部署搭建单机 ...
- asp.net core 负载均衡集群搭建(centos7+nginx+supervisor+kestrel)
概述 本文目的是搭建三台asp.net core 集群, 并配上 nginx做负载均衡 首先准备要运行的源码 http://pan.baidu.com/s/1c20x0bA 准备三台服务器(或则虚 ...
- 关于ASP.NET Core WebSocket实现集群的思考
前言 提到WebSocket相信大家都听说过,它的初衷是为了解决客户端浏览器与服务端进行双向通信,是在单个TCP连接上进行全双工通讯的协议.在没有WebSocket之前只能通过浏览器到服务端的请求应答 ...
- 使用Docker搭建consul集群+registrator实现服务自动注册。
准备工作:10.173.16.83 master10.172.178.76 node110.171.19.139 node210.162.204.252 node3 一.安装consul-cluste ...
- consul集群docker版本脚本
https://blog.csdn.net/fenglailea/article/details/79098246 docker run -d --name node1 -e 'CONSUL_LOCA ...
- Prometheus 通过 consul 分布式集群实现自动服务发现
转载自:https://cloud.tencent.com/developer/article/1611091 1.Consul 介绍 Consul 是基于 GO 语言开发的开源工具,主要面向分布式, ...
- Service Discovery And Health Checks In ASP.NET Core With Consul
在这篇文章中,我们将快速了解一下服务发现是什么,使用Consul在ASP.NET Core MVC框架中,并结合DnsClient.NET实现基于Dns的客户端服务发现 这篇文章的所有源代码都可以在G ...
- List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac
List多个字段标识过滤 class Program{ public static void Main(string[] args) { List<T> list = new List& ...
随机推荐
- 使用UICollectionView
使用UICollectionView 使用UICollectionView的流程: 1. 设定一个UICollectionViewFlowLayout 2. 使用这个设定的UICollectionVi ...
- 阿里云全球首次互联网8K直播背后的技术解读
3月28日,云栖大会·深圳峰会现场,阿里云发布并现场演示了阿里视频云最新8K互联网直播解决方案.这是全球发布的首个8K视频云解决方案,也是全球首次8K互联网视频直播. 视频地址:https://v.q ...
- oracle 28001错误 密码过期失效
背景 服务器演示地址,无法使用.排查原因,是数据库密码有问题,报28001错误 问题 确定是oracle密码机制,180失效了 解决 1.进入sqlplus模式 sqlplus / as sysdba ...
- ZT Shell 排序
Shell 排序 分类: 算法 C 2008-09-17 11:02 1898人阅读 评论(4) 收藏 举报 shell语言c 刚才在CSDN的C语言板块看到了有人说Shell排序的问题,所以一起学习 ...
- [2018HN省队集训D5T1] 沼泽地marshland
[2018HN省队集训D5T1] 沼泽地marshland 题意 给定一张 \(n\times n\) 的棋盘, 对于位置 \((x,y)\), 若 \(x+y\) 为奇数则可能有一个正权值. 你可以 ...
- 浅析JS中的堆内存与栈内存
最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...
- C++中重载决议与可访问性检查的顺序
http://blog.csdn.net/starlee/article/details/1406781 对于如下的类: class ClxECS{public: double Test(dou ...
- cocos2d-x发生undefined reference to `XX'异常 一劳永逸解决的方法
转自:http://www.myexception.cn/operating-system/1620542.html cocos2d-x发生undefined reference to `XX'错误 ...
- c++ 多态,虚函数、重载函数、模版函数
c++三大特性:封装.继承.多态.封装使代码模块化,继承扩展已存在的代码,多态的目的是为了接口重用 虚函数实现:虚函数表:指针放到虚函数表 多态:同名函数对应到不同的实现 构造父类指针指向子类的对象 ...
- django 模板关闭自动转义
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全.但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰 ...