准备环境

安装consul之后

1. 创建一个.net core webapi 举例为UsercenterService

2. nuget引用Consul组件  https://github.com/PlayFab/consuldotnet

3. 创建配置实体类 (后面涉及功能介绍时候再解释属性含义)

 1     public class AppSettings
 2     {
 3         /// <summary>
 4         /// 数据库连接字符串
 5         /// </summary>
 6         public string DbConnection { get; set; }
 7
 8         /// <summary>
 9         /// 服务注册参数
10         /// </summary>
11         public ServiceRegisterOptions ServiceRegisterOptions { get; set; }
12     }
13
14     public class ServiceRegisterOptions
15     {
16         /// <summary>
17         /// 是否启用
18         /// </summary>
19         public bool IsActive { get; set; }
20         /// <summary>
21         /// 服务名称
22         /// </summary>
23         public string ServiceName { get; set; }
24         /// <summary>
25         /// 服务IP或者域名
26         /// </summary>
27         public string ServiceHost { get; set; }
28         /// <summary>
29         /// 服务端口号
30         /// </summary>
31         public int ServicePort { get; set; }
32         /// <summary>
33         /// consul注册地址
34         /// </summary>
35         public string ConsulRegisterUrl { get; set; }
36         /// <summary>
37         /// 标签 例如laiwutest
38         /// </summary>
39         public string[] Tags { get; set; }
40     }

View Code

4. appsettings配置consul服务地址和UserService配置在consul的节点key

  4.1 配置consul地址(举例是在VS调试开发环境。所以在appsettings.Development.json中配置)

1 {
2   "ConsulForConfig": {
3     "Host": "{IP}:8500",//这里替换成自己consul服务的IP地址
4     "Prefix": "git-dev/huangqiang/usercenterRegionIIS.json"
5   }
6 }

View Code

4.2 在consul上创建该节点并且配置

 1 {
 2     "DbConnection": "111111111111111111111111111111111111111",
 3     "ServiceRegisterOptions":
 4     {
 5         "IsActive":true,
 6         "ServiceName":"UserCenterRegion",
 7         "ServiceHost":"{IP}",//修改{IP}为你注入的服务的ip地址
 8         "ServicePort":"{Port}",//修改{Port}为你注入的服务的端口
 9         "ConsulRegisterUrl":"{IP}:8500",//修改{IP}为你的consul服务的IP
10         "Tags":["浙江杭州"]
11     },
12 }

View Code


获取配置  

 1   public static AppSettings AddAppSettingByConsul(this IServiceCollection sc, IConfiguration configuration)
 2         {
 3             try
 4             {
 5                 //get local consul service address configration consulclient
 6                 var consulAddress = $"http://" + configuration["ConsulForConfig:Host"];
 7                 var key = configuration["ConsulForConfig:Prefix"];
 8                 if (string.IsNullOrWhiteSpace(consulAddress) || string.IsNullOrWhiteSpace(key))
 9                 {
10                     throw new Exception("无法获取consulAddress地址或者consul key");
11                 }
12                 var consulClient = new ConsulClient(cfg => { cfg.Address = new Uri(consulAddress); });
13                 sc.AddSingleton<IConsulClient>(p => consulClient);
14                 //get app config
15                 var res = consulClient.KV.Get(key).GetAwaiter().GetResult();
16                 var resStr = Encoding.UTF8.GetString(res.Response.Value);
17                 var appSettings = JsonConvert.DeserializeObject<AppSettings>(resStr);
18                 if (appSettings == null)
19                 {
20                     throw new Exception($"appSettings 为null,consul 配置:{resStr}");
21                 }
22                 sc.AddSingleton<AppSettings>(appSettings);
23                 return appSettings;
24             }
25             catch (Exception e)
26             {
27                 _log.Main.Error($"获取consul appsettings配置异常:{e.Message}");
28                 Environment.Exit(-1);
29             }
30             return null;
31         }

View Code

这里抽了一个扩展方法。使用的时候在Startup.cs类中的方法ConfigureServices中加入,这里弄了返回值只是偷懒下。

AddAppSettingByConsul方法逻辑:先是拿到配置的consull服务地址和Key,再通过前面nuget引用的consul组件中的consulclient获取配置,最后注入到容器

调试下 就拿到配置了。这样方便分布式服务,不用每台都配置,直接consul管理


配置健康检测和服务注册

准备健康检测接口:

1     [Route("api/v1/[controller]")]
2     [ApiController]
3     public class HealthController : ControllerBase
4     {
5         [HttpGet]
6         public IActionResult Get() => Ok("ok");
7     }

View Code

.net core 配置注册和健康检测的地址

 1  public static void UseConsul(this IApplicationBuilder app, IApplicationLifetime appLife)
 2         {
 3             try
 4             {
 5                 var appSettings = app.ApplicationServices.GetService<AppSettings>();
 6                 var consulClient = app.ApplicationServices.GetService<IConsulClient>();
 7
 8                 //config consul health check
 9                 var healthCheck = new AgentServiceCheck
10                 {
11                     DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
12                     Interval = TimeSpan.FromSeconds(30),
13                     HTTP = $"{appSettings.ServiceRegisterOptions.ServiceHost}:{appSettings.ServiceRegisterOptions.ServicePort}/api/v1/Health",
14                 };
15
16                 //service register
17                 var serviceId = $"{appSettings.ServiceRegisterOptions.ServiceName}_{appSettings.ServiceRegisterOptions.ServiceHost}:{appSettings.ServiceRegisterOptions.ServicePort}";
18                 var registration = new AgentServiceRegistration
19                 {
20                     Checks = new[] { healthCheck },
21                     Address = appSettings.ServiceRegisterOptions.ServiceHost,
22                     Port = appSettings.ServiceRegisterOptions.ServicePort,
23                     ID = serviceId,
24                     Name = appSettings.ServiceRegisterOptions.ServiceName,
25                     Tags = appSettings.ServiceRegisterOptions.Tags
26                 };
27                 consulClient.Agent.ServiceRegister(registration).GetAwaiter().GetResult();
28
29                 //service Deregister when app stop
30                 appLife.ApplicationStopped.Register(() =>
31                 {
32                     consulClient.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
33                 });
34
35
36             }
37             catch (Exception e)
38             {
39                 _logger.Main.Error($"UseConsul error:{e.Message}");
40                 Environment.Exit(-1);
41             }
42
43         }

View Code

这里也是抽了个扩展方法。调用放到Startup

UseConsul方法解释:先是从容器中拿到前面注入的配置实体AppSettings和ConsulClient。再配置健康检测,再配置服务注册,再配置当服务关闭时候注销服务。

其中健康检测的DeregisterCriticalServiceAfter表示如果服务启动失败,多少时间内注销consul上的该服务。

服务注册的参数就不介绍了

然后跑起来之后,到consul ui瞧一瞧。是不是注册成功,心跳正常

状态为passing为正常的,刚启动时候状态会为critical。 当你的状态一直为critical时候,过了前面DeregisterCriticalServiceAfter的时间,服务将会注销,也就是注册失败。可能原因:服务地址配置有问题,consul无法访问你的health地址,也可能你的端口没打开。telnet看看

当都成功的时候,服务已经正常注册到consul。下面再说说服务发现和服务变更发现


 

服务发现和服务变更发现

服务发现调用的方法有很多,agent,catalog,health,都可以获取列表。但是agent是查询本地自己的,catalog是整个集群的,heath是查询健康的。这里用health获取举例

关键就一句话:_consulClient.Health.Service(serviceName, tag, true, queryOptions).Result。

这样就能获取到注册到consul的服务列表了,但是如果有服务变更了(新的服务注册,旧的服务停止),应该怎么办?

一般想到启动一个线程不停的去拿,是没有问题,但是有个更好的东西,“Blocking Queries”  https://www.consul.io/api/index.html

这个东西简单来说就是会记录一个版本,consul服务端通过这个版本来判断是不是已经是最新的服务列表,如果是的话,那么将会阻塞一定时间(这个时间可配置)

在c# 里面体现就是第三个参数queryOptions的WaitIndex和WaitTime,以及返回LastIndex,下面po出一部分代码。

        public void GetAllService(){_serviceIndexList.ForEach(p =>{Task.Run(() =>{var queryOptions = new QueryOptions { WaitTime = TimeSpan.FromSeconds(_waitTime) };while (true){GetAgentServices(queryOptions, p.ServiceName, p.Tag);}});});}public void GetAgentServices(QueryOptions queryOptions, string serviceName, string tag = null){try{var res = _consulClient.Health.Service(serviceName, tag, true, queryOptions).Result;_logger.Main.Info($"GetServiceList:{serviceName} {tag} waitIndex:{res.LastIndex}");if (queryOptions.WaitIndex != res.LastIndex){queryOptions.WaitIndex = res.LastIndex;var currentService = _consulServices.FirstOrDefault(p => p.ServiceName == serviceName);if (currentService == null){_consulServices.Add(new ConsulService{ServiceName = serviceName,Tag = tag,ServiceEntries = new ConcurrentBag<ServiceEntry>(res.Response)});}else{currentService.ServiceEntries = new ConcurrentBag<ServiceEntry>(res.Response);}}}catch (AggregateException ae){_logger.Main.Error($"consul获取{serviceName},{tag}服务列表资源错误:{ae.Flatten()}",ae);}catch (Exception e){_logger.Main.Error($"consul获取{serviceName},{tag}服务列表资源错误",e);}}

View Code

注:代码中的_serviceIndexList是存着需要获取哪些服务的服务tag,_consulServices是程序维护的最新服务列表

转载于:https://www.cnblogs.com/TeemoHQ/p/10523637.html

.net core consul 服务配置 服务发现 服务健康检测 服务变更加载相关推荐

  1. Eureka服务注册与发现:什么是服务注册与发现,Server注册中心

    Eureka服务注册与发现 一套微服务架构的系统由很多单一职责的服务单元组成,而每个服务单元又有众多运行实例.例如,世界上最大的收费视频网站Netflix的系统是由600多个服务单元构成的,运行实例的 ...

  2. 服务注册与发现用mysql_yeasul: 轻量级服务注册与发现中心,具有健康检查功能。...

    yeasul 亿联定制版服务注册与发现中心,具备心跳检测功能,由于接口参考了consul,所以取名为yeasul. 项目架构 使用Java语言开发,依赖于MySQL 8.0数据库,基于Spring B ...

  3. .Net Core 商城微服务项目系列(二):使用Ocelot + Consul构建具备服务注册和发现功能的网关...

    1.服务注册 在上一篇的鉴权和登录服务中分别通过NuGet引用Consul这个包,同时新增AppBuilderExtensions类: public static class AppBuilderEx ...

  4. 一个故事,一段代码告诉你如何使用不同语言(GolangC#)提供相同的能力基于Consul做服务注册与发现

    文章目录 引言 什么是微服务 传统服务 微服务 什么是服务注册与服务发现 为什么要使用不同的语言提供相同的服务能力 服务协调器 服务注册 Golang C#(.NetCore3.1) 服务发现 通过H ...

  5. SpringCloud从入门到放弃 03 ——Consul服务注册与发现

    文章目录 SpringCloud从入门到放弃 03 --Consul服务注册与发现 一.Consul简介 1.什么是consul 2.consul能做什么 二.安装并运行Consul 1.下载安装 2 ...

  6. AgileConfig 1.6.0 发布 - 支持服务注册与发现

    大家好,好久没有输出博文了,一是因为比较忙,另外一个原因是最近主要的精力是在给 AgileConfig 添加一个新的功能:服务注册与发现. 先说说为什么会添加这个功能.我自己的项目是用 Consul ...

  7. 微服务探索与实践—服务注册与发现

    前言 微服务从大规模使用到现在已经有很多年了,从之前的探索到一步步的不断完善与成熟,微服务已经成为众多架构选择中所必须面对的一个选项.服务注册与发现是相辅相成的,所以一般会合起来思索.其依托组件有很多 ...

  8. 聊聊微服务的服务注册与发现

    聊起微服务的服务注册与发现,很多人立马就会脱口而出 zk.etcd.consul.eureka 这些组件,进而聊到 CAP 如何取舍,性能如何,高可用和容灾是怎么实现的. 引言 聊起微服务的服务注册与 ...

  9. jsp调用controller方法_RPC调用_服务注册与发现

    RPC调用_单体架构_SOA架构 系统架构的演变 1 传统的单体架构 1.1 什么是单体架构 一个归档包(例如 war 格式或者 Jar 格式)包含了应用所有功能的应用程序,我们通常称之 为单体应用. ...

最新文章

  1. 去除cpp中注释的小程序
  2. python从oracle提取数据库_[python] python 和远程oracle 数据库连接,select提取文件 环境搭建过程...
  3. 《人月神话》阅读笔记--02
  4. LeetCode 413 等差数列划分
  5. CICD详解(三)——SVN基本概念
  6. 相机标定-opencv
  7. MySQL 入门常用命令大全
  8. 电音插件auto_Antares 发布新型人声制作插件 Auto-Tune EFX +
  9. linux gt240驱动下载,NV显卡Linux驱动195.36.08版发布
  10. 电脑显示网络计算机和设备不可见,win10系统网络发现已关闭看不到网络计算机和设备的解决方法...
  11. 使用计算机能播放音乐也能观看视频,我电脑可以放歌有声音。怎么播放视频没声音啊?给我解决方案...
  12. ubuntu 安裝deb_Ubuntu离线安装deb包和依赖
  13. 枫叶永恒 服务器维护,3月8日服务器维护公告
  14. vue中使用图片裁切器
  15. 解释外显子,内含子,CDS、cDNA、EST、mRNA、ORF间的区别
  16. JAVA 生成二维码 并设置 +失效机制
  17. 计算机代表学校拿什么奖,学校荣获第十届中国大学生计算机设计大赛优秀组织奖...
  18. 创建React + Ts项目
  19. 普华i-VirtualCloud应用案例之--国家海洋局北海分局
  20. 访问网络中的计算机密码忘了怎么办,忘记wifi密码怎么办,用这招可以知道电脑中的wifi密码...

热门文章

  1. 编写一个java打印心程序_java – ?同时打印心脏符号
  2. 视频显示边缘空白的真相
  3. Redis 实用技术——事务
  4. spring源码分析第四天------springmvc核心原理及源码分析
  5. 问题反馈信息处理平台开发过程
  6. 燃气灶电气线路图及原理_一位造价大神的电气工程造价知识整理笔记_深圳电气造价预算培训要多少钱...
  7. 深入jvm虚拟机第三版源码_深入JVM虚拟机,阿里架构师直言,这份文档真的是JVM最深解读...
  8. linux里用c实现cat_【案例】用T云做了什么能让企业在工业自动化控制系统行业里实现逆向增长?...
  9. KMP算法 串模式识别 用nextval[j]改进next[j]
  10. 微信 语音转文字 java,在微信——怎么将语音转化为文字,你需要学习了