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中初体验的更多相关文章

  1. .Net Core SignalR 初体验

    前言 Asp.Net SignalR已经出来很久了,但是一直没有静下心来好好看看.昨天花了几个小时的时间看了下.首先借鉴了官方文档,如何搭建一个SignalR的Demo. 参考文章:https://d ...

  2. asp net core 跨平台初体验

    标: 在 ubuntu 16.04 上部署一个 asp.net core 站点,打开网站后显示一段文字.   安装 net core 运行环境:ubuntu 16.04 LTS 1.添加 apt 源 ...

  3. vscode 创建.net core项目初体验

    微软的virtual studio编辑器那是宇宙第一大编辑器,可惜就是太笨重,遇到性能差一些的电脑设备,简直无法快速的编辑项目. 而vs code编辑器轻便易用,想要编辑哪种项目,只需扩展插件就OK, ...

  4. .Net Core Serverless初体验

    什么是Serverless Serverless 是一个当今软件世界中比较新的话题.它并没有一个普遍公认的权威定义,每个人每个企业对它的解释可能都有不同,而 Serverless 正是在这种情况下不断 ...

  5. ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

    早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...

  6. Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验

    Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...

  7. Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验

    Net Core平台灵活简单的日志记录框架NLog初体验 前几天分享的"[Net Core集成Exceptionless分布式日志功能以及全局异常过滤][https://www.cnblog ...

  8. .net core安装及初体验

    .net core安装及初体验 .net core 作为微软的新一代技术,在开发跨平台.微服务等方面有很大的优势,也更贴近现代的编码习惯.在2.0版发布很久以后,近期终于决定进行学习和体验. 安装 作 ...

  9. JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中

    JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中 一.JMS的理解JMS(Java Message Service)是jcp组织02-03年定义了jsr914规范(http://j ...

随机推荐

  1. NPOI 读取Excel文件

    private void buttonExcel_Click(object sender, EventArgs e) { FileStream fs = null; List<ISheet> ...

  2. BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)

    Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 871  Solved: 365[Submit][Status][Discuss] Description ...

  3. 洛谷P4302 [SCOI2003]字符串折叠(区间dp)

    题意 题目链接 Sol 裸的区间dp. 转移的时候枚举一下断点.然后判断一下区间内的字符串是否循环即可 `cpp #include<bits/stdc++.h> #define Pair ...

  4. 17.Odoo产品分析 (二) – 商业板块(10) – 电子商务(1)

    查看Odoo产品分析系列--目录 安装电子商务模块 1. 主页 点击"商店"菜单:  2. 添加商品 在odoo中,你不用进入"销售"模块,再进入产品列表添加产 ...

  5. 小米手机Toast显示带应用名称问题解决方法

    近期为了适配刘海屏,向公司申购了一步小米8的手机,然后测试人员那边测出来一堆适配的问题,其中有一个每一个Toast会显示app的名称+显示的内容,然后网上查找了一下解决方法记录一下,顺便封装了Toas ...

  6. Android滑动冲突解决

    (1).场景一:外部滑动方向跟内部滑动方向不一致,比如外部左右滑动,内部上下滑动   ViewPager+Fragment配合使用,会有滑动冲突,但是ViewPager内部处理了这种滑动冲突   如果 ...

  7. 章节二、2-String 引用数据类型-字符串类

    一.创建String(字符串对象)的两种方式 1.String str1 = "nihao"("nihao"值存储在常量值中) 2.String str2 = ...

  8. Orchard详解--第九篇 拓展模块及引用的处理

    在分析Orchard的模块加载之前,先简要说一下因为Orchard中的模块并不是都被根(启动)项目所引用的,所以当Orchard需要加载一个模块时首先需要保证该模块所依赖的其它程序集能够被找到,那么才 ...

  9. Scala抽象类型

    package big.data.analyse.scala import scala.io.{BufferedSource, Source} /** * 抽象类型 * Created by zhen ...

  10. IDLE提供的常用快捷键

    IDLE提供的常用快捷键 快捷键 说明 适用于 F1 打开Python帮助文档 Python文件窗口和shell窗口均可用 Alt+P 浏览历史命令(上一条) 仅Python Shell窗口可用 Al ...