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

准备环境

 安装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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hexo+GitHub 快速搭建个人博客(三)---- 改变主题

前期准备&#xff1a; 基本的Linux命令 基本的GitHub命令 Hexo有多种博客框架&#xff0c;在 https://hexo.io/themes/ 里可以找到非常多优秀的博客框架&#xff0c;而且都是免费的。 首先大家可以去找一款自己喜欢的框架&#xff0c;可以选择浏览和直接进入GitHub进行fork …

Vue入门 ---- 组件式开发

##组件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible" conten…

/usr/bin/python^M: 解释器错误: 没有那个文件或目录

【1】问题现象 执行python脚本&#xff0c;提示错误&#xff1a;/usr/bin/python^M: 解释器错误: 没有那个文件或目录 【2】原因分析 大多数是因为脚本文件在windows下编辑过。在windows下&#xff0c;每一行的结尾是\r\n&#xff0c;而在linux下文件的结尾是\n。 那么&#xf…

Vue入门 ---- vuex

##简介 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 vuex分为三大部分&#xff1a; state&#xff0c;驱动应用的数据源&#xff1b; view&#xff0c;以声…

day1-参数化关联函数响应断言

1、参数化 1&#xff09;、准备参数化文件 2&#xff09;&#xff0c;添加CSV数据文件设置 3&#xff09;、在请求里 引用参数 2、关联函数 1&#xff09;、给学生充值金币需要从登录返回获取登录cookie 在登录接口添加后置处理器JSON Extractor 用户登录返回结果为&#xff1…

语句覆盖,判定覆盖,条件覆盖,条件/判定覆盖,条件组合覆盖,路径覆盖

最近在复习软件测试的考试&#xff0c;每次到白盒测试这里都要为这几种逻辑覆盖方法感到头疼&#xff0c;这次终于决定好好整理出来。 逻辑覆盖是通过对程序逻辑结构的遍历实现程序的覆盖。它是一系列测试过程的总称&#xff0c;这组测试过程逐渐进行越来越完整的通路测试。 根…

PHP实现简单文件上传系统

目录结构如下&#xff0c;其中包含两个代码文件和一个uploads文件夹&#xff08;用于存放上传的文件&#xff09; index.php 该代码实现html页面&#xff0c;包括需要填写学号和姓名&#xff0c;上传文件大小不得超过20M <form action"fileSystem.php" method&…

Vue入门 ---- 仿百度搜索

简述 学习vue的第二节&#xff0c;由于2.0版本并不向下兼容&#xff0c;视频中的不少内不能实现。下面列出一些主要知识点 // v-on 可简写为 // 事件冒泡是指当点击div内部的button触发show1()时&#xff0c;必然会冒泡到div上执行show2()&#xff0c;这才层级div中很常见 // …

Visual Studio引入外部库 ---- 弄懂静态库lib和动态库dll

这两天由于想要研究一下socket的相关内容&#xff0c;但是没想到引入外部库还有这么多门道。 根据维基百科定义&#xff1a;一个现代编译器的主要工作流程如下&#xff1a;源代码&#xff08;source code&#xff09;→ 预处理器&#xff08;preprocessor&#xff09;→ 编译器…

[G星计划]--项目开发总结

第一轮&#xff1a;Dr.Mech 参加了为期7天的第一轮DEMO竞赛&#xff0c;最佳团队&#xff0c;总结一下开发过程中的一些要点。 问题&#xff1a; 关于项目时间安排&#xff0c;由于项目核心代码量并不算太多&#xff0c;所以前几天还是比较从容的&#xff0c;不过这也导致许多…

在2020年学习cocos游戏引擎

常用链接 Cocos2d-x 用户手册 参考书目 《Cocos2d-X游戏开发实战精解》 《我所理解的Cocos2d-x》 《Effective C》中文版第三版 环境搭建 macOS 10.15.6 Xcode 11.5 cocos2d-x 3.17.2 cmake 3.17.3 创建工程 采用cocos2d-x 3.17版本可直接通过cocos console创建&#xf…

[源码学习]--UGUI

学习参考 从bitbucket上获取uGUI 2019.1源码 UGUI内核大探究 事件系统 UnityEngine.UI/EventSystem/EventSystem.cs private List<BaseInputModule> m_SystemInputModules new List<BaseInputModule>(); // 系统输入模块列表 private BaseInputModule m_Curr…

PureMVC在Unity游戏开发中的应用

作为开发人员&#xff0c;我们都想写出优雅的代码&#xff0c;可又苦于自身能力不知该如何下手&#xff0c;而框架的作用正在与能够让你规范的去开发。 之前写Web的时候&#xff0c;总被要求采用MVC架构&#xff0c;的确非常好用&#xff0c;也从来没有质疑过这种架构的好与不好…

Unity资源管理--AssetBundle学习

Unity资源目录 当用Unity创建一个工程的时候&#xff0c;目录如下&#xff1a; Assets&#xff1a;存放Unity工程实际的资源目录。 Library&#xff1a;存放Unity处理完毕的资源&#xff0c;由unity自动转化生成。 Log&#xff1a;存放日志文件。 Packages&#xff1a;统一管…

[读书笔记] 设计模式与游戏完美开发

最近在看《设计模式与游戏完美开发》&#xff0c;文章将记录一些要点和一些设计模式实现 GoF定义的23种设计模式及应用场景 系统设计可以采用的设计模式&#xff1a;单例、状态&#xff08;场景切换&#xff09;、外观&#xff08;保证高内聚&#xff09;、中介者&#xff08…

iOS开发——GPUImage源码解析

一、基本概念 GPUImage&#xff1a;一个开源的、基于openGL的图片或视频的处理框架&#xff0c;其本身内置了多达120多种常见的滤镜效果&#xff0c;并且支持照相机和摄像机的实时滤镜&#xff0c;并且能够自定义图像滤镜。同时也很方便在原有基础上加入自己的滤镜Filter&#…

[读书笔记] 敏捷软件开发:原则、模式与实践

关于面向对象编程的一些理解&#xff0c;这本书主要看六大原则的部分&#xff0c;书中关于设计模式的内容由于之前的那本《设计模式与游戏完美开发》已经很好的讲解了游戏开发领域的应用&#xff0c;所以不多关注。 面向对象的六大原则 单一职责原则SRP&#xff1a;一个类应该…

Caffe-SSD相关源码说明和调试记录

1 对Blob的理解及其操作&#xff1a; Blob是一个四维的数组。维度从高到低分别是: (num_&#xff0c;channels_&#xff0c;height_&#xff0c;width_) 对于图像数据来说就是&#xff1a;图片个数&#xff0c;彩色通道个数&#xff0c;宽&#xff0c;高 Blob中数据是row-…

[游戏策划] 读书笔记

交互式媒体最有趣的地方在于&#xff0c;它让玩家直面问题&#xff0c;思考、尝试各种解决方案&#xff0c;并体验各种解决方案的结果。然后玩家可以回到思考阶段&#xff0c;规划下一步行动。这种反复试错的过程中&#xff0c;玩家的脑海里就会构建出一个互动的世界。 [读书笔…

ECS框架学习

DOTS Unity DOTS是Unity官方基于ECS架构开发的一套包含Burst编辑器和JobSystem的技术栈&#xff0c;它旨在充分利用多核处理器的特点&#xff0c;充分发挥ECS的优势。 安装 Entities、Burst、Jobs、Hybrid Renderer&#xff08;必选&#xff0c;用于DOTS的渲染相关&#xf…