Consul在.Net Core中初体验
Consul在.Net Core中初体验
简介
在阅读本文前我想您应该对微服务架构有一个基本的或者模糊的了解
Consul是一个服务管理软件,它其实有很多组件,包括服务发现配置共享键值对存储等
本文主要讲解Consul的服务注册服务发现以及集群的配置
参考资料:
https://blog.csdn.net/younger_china/article/details/79462530
https://www.cnblogs.com/shanyou/p/6286207.html
服务发现
假设有服务A,B,C.服务A需要调用服务B和C,传统的方式我们需要在服务A中记录服务B和C的ip及端口号。这些配置一般写在配置文件等地方存储。
这种做法有两个显而易见的缺点:1.如果将来B的ip改变了就需要修改所有调用者的ip配置。 2.难以做负载均衡
而服务发现就是用来解决这个问题的,怎么解决呢?请看下面这张图

这张图中在服务消费者和服务生产者之间加了一个服务注册中心的模块,用上面的服务器ABC来举例,服务B在发布的时候会在注册中心注册,注册中心会记录服务B的名字及ip地址。当服务A请求服务B的时候,只需要带着服务B的名字来注册中心查询即可。集群情况下,注册中心会有多个服务B。同时注册中心会定期检查每一个服务否可以正常访问,移除不可访问的服务。(健康检查)
总的来说,服务发现就是通过一个标志来获取服务列表,并且服务列表可随着每个服务的上线或下线动态变更
Consul术语及解释
下面列出几个consul中出现频率较高的术语
- Agent,Agent是长期运行在每个consul集群成员节点上守护进程。通过命令consul agent启动。Agent有client和server两种模式。由于每个节点都必须运行agent,所有节点要么是client要么是server。所有的Agent都可以可以调用DNS或HTTP API,并负责检查和维护服务同步。
- client 运行client模式的Agent,将所有的RPCs转发到Server。Client是相对无状态的。Client唯一所做的是在后台参与LAN gossip pool。只消耗少量的资源,少量的网络带宽。
- Server 运行Server模式的Agent,参与Raft quorum,维护集群的状态,响应RPC查询,与其他数据中心交互WAN gossip,转发查询到Leader或远程数据中心。
datacenter 数据中心的定义似乎是显而易见的,有一些细节是必须考虑的。例如,在EC2,多个可用性区域是否被认为组成了单一的数据中心?我们定义数据中心是在同一个网络环境中——私有的,低延迟,高带宽。这不包括基于公共互联网环境,但是对于我们而言,在同一个EC2的多个可用性区域会被认为是一个的数据中心。
- 关于client和server我搞了好久才搞明白,实际上client不存储数据,发送到client的请求,client都会转发给它绑定的server,也就是说client必须绑定server。server会存储数据,如果只有一个server并在上面注册了一个服务,这个server挂了然后你又重启了,那么这个服务的注册信息仍然保存在server上。
如果你在一台服务器上运行了一个server,它会默认有一个client绑定到server上,并且地址是127.0.0.1
consul安装
consul下载地址:https://www.consul.io/downloads.html
我用的win10 系统,所以下载的最后一个windows64位的,下载下来有个exe文件,随便放个到一个文件夹下就可以了。
进入cmd,转到consul的存放目录,打命令就可以了。
或者可以把consul的目录路径加入到Path环境变量中,就不用每次到目录下打命令了
启动consul
上面说过,consul可以以client和server的方式启动
Server:consul agent -server -bootstrap-expect 1 -data-dir=C:\consul -node=n1 -bind=192.168.3.233 -ui-dir=C:\consul\dist -client=0.0.0.0
Client:consul agent -bootstrap-expect 1 -data-dir=C:\consul -node=n1 -bind=192.168.3.233 -ui-dir=C:\consul\dist
把-server去掉就是client模式了
- consul agent:启动consul的命令,要么是server要么是client
- -bootstrap-expect:期望的server节点数目,如果集群中的server节点小于这个数据,集群则失效,并且该server也失效,一直等到集群中的数目达到相应的数量才生效,如果是1的话,代表一个server就可以了
- -data-dir:data存放的目录,server会保存一些配置缓存等信息,存在此目录下
- -node:该节点的名称,急群众名称必须唯一
- -client:代表该server对外暴漏的client地址,0.0.0.0代表我可以通过:127.0.0.1和192.168.3.233访问,不设置的话默认是:127.0.0.1
- -bind:这是设置集群中server之间互相通信的地址,必须可以互相访问到
- -ui-dir:设置webui的界面,理论上通过命令可以查看到我们需要的任何信息,但是通过ui来查看更直观
搭建集群
我开启了两台虚拟机和本机一共是三台机器,所以我搭建了三个server节点
Ser1:consul agent -server -bootstrap-expect=3 -data-dir=C:\consul -node=node1 -bind=192.168.3.233 -client=0.0.0.0
Ser2:consul agent -server -bootstrap-expect=3 -data-dir=C:\consul -node=node2 -join=192.168.3.233 -bind=192.168.3.201 -client=0.0.0.0
Ser3: consul agent -server -bootstrap-expect=3 -data-dir=C:\consul -node=node3 -join=192.168.3.233 -bind=192.168.3.243 -client=0.0.0.0
-join:表示加入到哪个集群内,ser2中我们指定加入到了ser1中,这时候ser1和ser2组成了集群,ser3我们可以指定加入到ser1和ser2,不管加入哪个最终这三个server都组成了一个集群,最终三个server商量了一下选出了一个leader
服务注册
可以通过命令来注册服务,因为最终是要在.net core上使用,所以我就直接贴上.net core中的相关代码
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifeTime)
{
string ip = Configuration["ip"];
string port = Configuration["port"];
string serviceName = "MsgService";
string serviceId = serviceName + Guid.NewGuid();
Action<ConsulClientConfiguration> ConsulConfig = (config) =>
{
config.Address = new Uri("http://192.168.3.201:8500"); //服务注册的地址,集群中任意一个地址
config.Datacenter = "dc1";
};
using (var consulClient = new ConsulClient(ConsulConfig))
{
AgentServiceRegistration asr = new AgentServiceRegistration
{
Address = ip,
Port = Convert.ToInt32(port),
ID = serviceId,
Name = serviceName,
Check = new AgentServiceCheck
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
HTTP = $"http://{ip}:{port}/api/Health",//健康检查访问的地址
Interval = TimeSpan.FromSeconds(10), //健康检查的间隔时间
Timeout = TimeSpan.FromSeconds(5), //多久代表超时
},
};
consulClient.Agent.ServiceRegister(asr).Wait();
}
//注销Consul
appLifeTime.ApplicationStopped.Register(() =>
{
using (var consulClient = new ConsulClient(ConsulConfig))
{
consulClient.Agent.ServiceDeregister(serviceId).Wait(); //从consul集群中移除服务
}
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
运行程序后向consul集群注册了一个服务,访问集群的任何一个ip都可取到该服务的ip。客户端查询服务的代码如下:
static void Main(string[] args)
{
using (var consul = new Consul.ConsulClient(c =>
{
c.Address = new Uri("http://192.168.3.233:8500"); //Consul地址
}))
{
var services = consul.Catalog.Service("MsgService").Result.Response;
foreach (var s1 in services)
{
Console.WriteLine($"ID={s1.ServiceID},Service={s1.ServiceName},Addr={s1.Address},Port={s1.ServicePort}");
}
}
}
这样我们一个基本的consul集群就可以正常使用了
对于consul和服务发现目前还只是刚刚开始接触。还是有很多问题暂时没有搞明白。
比如客户端连接的server突然挂了怎么办如何切换到另一个server?以及一个服务下线了如何通知客户端删除缓存等等。还请大家不吝赐教
Consul在.Net Core中初体验的更多相关文章
- .Net Core SignalR 初体验
前言 Asp.Net SignalR已经出来很久了,但是一直没有静下心来好好看看.昨天花了几个小时的时间看了下.首先借鉴了官方文档,如何搭建一个SignalR的Demo. 参考文章:https://d ...
- asp net core 跨平台初体验
标: 在 ubuntu 16.04 上部署一个 asp.net core 站点,打开网站后显示一段文字. 安装 net core 运行环境:ubuntu 16.04 LTS 1.添加 apt 源 ...
- vscode 创建.net core项目初体验
微软的virtual studio编辑器那是宇宙第一大编辑器,可惜就是太笨重,遇到性能差一些的电脑设备,简直无法快速的编辑项目. 而vs code编辑器轻便易用,想要编辑哪种项目,只需扩展插件就OK, ...
- .Net Core Serverless初体验
什么是Serverless Serverless 是一个当今软件世界中比较新的话题.它并没有一个普遍公认的权威定义,每个人每个企业对它的解释可能都有不同,而 Serverless 正是在这种情况下不断 ...
- ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)
早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...
- Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验
Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...
- Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验
Net Core平台灵活简单的日志记录框架NLog初体验 前几天分享的"[Net Core集成Exceptionless分布式日志功能以及全局异常过滤][https://www.cnblog ...
- .net core安装及初体验
.net core安装及初体验 .net core 作为微软的新一代技术,在开发跨平台.微服务等方面有很大的优势,也更贴近现代的编码习惯.在2.0版发布很久以后,近期终于决定进行学习和体验. 安装 作 ...
- JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中
JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中 一.JMS的理解JMS(Java Message Service)是jcp组织02-03年定义了jsr914规范(http://j ...
随机推荐
- 数据库sql语句常见面试题
转载:本文转载自:https://blog.csdn.net/woshinidedege/article/details/78659202 一.有以下几张表及表结构Student(Sid,Sname, ...
- php生成xml数据
1.php生成xml数据一般有2种方式, 一个是组装字符串,另一个就是使用php内置的系统类 2.使用php内置类生成xml数据 3.拼装字符串生成xml数据 public function stat ...
- ASPxGridView 选中主表一行数据,从表自动选中(勾选)对应的行
一.图解 下图为效果图,点击 [A表]种的某一行,[B表]会有与之相对于一行会被自动选中并且勾选上: 二.Html 代码 <html xmlns="http://www.w3.org/ ...
- vue的data的数据进行指定赋值,用于筛选条件的清空,或者管理系统添加成功后给部分数据赋值为空
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- BZOJ 1022: [SHOI2008]小约翰的游戏John (Anti-nim)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3134 Solved: 2003[Submit][Status][Discuss] Descripti ...
- Android 弹性布局 FlexboxLayout了解一下
原文链接:https://mp.weixin.qq.com/s/Mi3cK7xujmEMI_rc51-r4g RelativeLayout.LinearLayout等常用布局相信大家早已耳熟能详,今天 ...
- <1>Linux日志查找方法
Linux日志查找方法 适用于测试,开发,运维人员,用来查找Linux服务器问题的一般方法,比较实用,如果有更好的办法可以一块讨论,欢迎大神们来指导哈!!! 进入正题 第一步.通过Xshell登录服务 ...
- CSS之表格边框合并、兄弟标签外边距合并、父子标签的外边距合并
本文内容: 表格边框合并 兄弟标签外边距合并 父子标签的外边距合并 首发日期:2018-05-01 表格边框合并: 发生情况: 当设置了cellpadding="0" cellsp ...
- Kotlin Native
Kotlin Native 不是 Jni 的概念,它不仅仅是要与底层代码比如 C.C++ 交互,而且还要绕过 Jvm 直接编译成机器码供系统运行.也就是说,Kotlin 准备丢掉 Java 这根拐杖了 ...
- realloc 用方法
realloc 用方法 void* realloc(void*, n) 根据n的大小,如果n比较小,就沿用原来的内存地址(也就是返回的地址就是原来的地址),在原来地址的内存空间的最后面,加上n大小的内 ...