一、Consul 在net6下的使用

一、什么是consul?

       首先我们来了解什么是consul,consul是服务注册与发现的一种常用工具之一,翻阅了网上的部分资料,指把服务地址注册到consul,然后在consul中读取来消费;但在我的理解中,consul的作用是服务治理,属于可以横向伸缩的注册中心;为什么这么说呢?在以前我们用Nginx做负载时,需要把服务地址一个个手动集成进去的,如果服务多了会有什么问题呢?1.需要新增一个服务,必须要重新配置Nginx然后重启;2.感知不了哪个服务停止了;3.如果某个服务停止了,无法自动创建新的服务代替;因为微服务其中一个特点是基础设施自动化,所以明显Nginx满足不了需求,那么服务注册与发现就横空而生了(除了consul外还可以使用etcd,K8S Services等)。

二、consul有几大核心功能:

1.服务注册

  其实就是把需要使用的服务注册到注册中心(consul的注册方式是已服务主动推送给consul客户端->服务端),其他客户端可以使用 Consul 发现给定服务的提供者。使用 DNS 或 HTTP,应用程序可以轻松找到它们所依赖的服务(它是通过代理注册的方式注册到注册中心,提供业务代码的解耦)

2.健康检查

  其实就是在程序中,建立一个接口,只返回状态使用,consul通过这个接口来检查服务是否健康,如果不健康,则通过策略去移除

3.多个数据中心

  其实就是支持集群,通过3个,或5个的单数服务端的consul来支持高可用(因为单数更适合做选举算法,如果数量太多又影响性能,所以这是官网标配);

4.安全服务通信

  Consul 可以为服务生成和分发 TLS 证书以建立相互 TLS 连接

consul工作流程图:

 

 

 

 

 

三、consul安装

  安装分2种,一种是二进制,以命令行的形式安装;一种是以exe文件免安装的形式;

四、consul运行问题

  运行时,最可能出现的问题就是端口占用,可新增文件,修改文件端口号,然后执行命令即可,百度上很多解决,请自行搜索命令

五、net6的代码实现

  1.服务注册代码,目的是把当前服务推送到consul,并且设置健康检查

依赖组件

consul
复制代码
 1 public static class RegisterToConsul
 2     {
 3         /// <summary>
 4         /// 把本服务注册到Consul
 5         /// </summary>
 6         /// <param name="config">参数配置</param>
 7         /// <param name="appLifetime">程序生命周期</param>
 8         public static void RegToConsul(this IConfiguration config)
 9         {
10             //Consul地址
11             var address= AppHelper.ReadAppSettings("Consul", "consulAddress"); 
12             var consulClient = new ConsulClient(p => { p.Address = new Uri(address); });
13 
14             //本地IP
15             var localIP = AppHelper.ReadAppSettings("Consul", "currentIp");
16             //本地服务端口
17             var localPort = Convert.ToInt32(AppHelper.ReadAppSettings("Consul", "currentPort")); //端口号从命令行参数获取(注:目前没找到直接获取本服务监听的端口的方法)
18 
19             //心跳检测设置
20             var httpCheck = new AgentServiceCheck()
21             {
22                 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(60), //心跳检测失败多久后注销
23                 Interval = TimeSpan.FromSeconds(10), //间隔多久心跳检测一次
24                 HTTP = $"http://{localIP}:{localPort}/api/Health/Check", //心跳检查地址,本服务提供的地址
25                 Timeout = TimeSpan.FromSeconds(5)  //心跳检测超时时间
26             };
27 
28             //服务名(这里通过命令行参数传入不同的服务名,模拟我们有不同的服务[其实只是同一个接口项目的不同运行实例])
29             var serviceName = AppHelper.ReadAppSettings("Consul", "serviceName");
30 
31             //注册信息
32             var registration = new AgentServiceRegistration()
33             {
34                 ID = $"{localIP}:{localPort}", //服务ID,唯一
35                 Name = serviceName, //服务名(如果服务搭集群,它们的服务名应该是一样的,但是ID不一样)
36                 Address = $"{localIP}", //服务地址
37                 Port = localPort, //服务端口
38                 Tags = new string[] { }, //服务标签,一般可以用来设置权重等本地服务特有信息
39                 Checks = new[] { httpCheck }, //心跳检测设置
40             };
41 
42             //向Consul注册服务
43             consulClient.Agent.ServiceRegister(registration).Wait();
44 
45         }
46     }
复制代码
复制代码
 1   "Consul": {
 2 
 3     "consulAddress": "http://127.0.0.1:8500",
 4 
 5     "serviceName": "Consultest",
 6 
 7     "currentIp": "127.0.0.1",
 8 
 9     "currentPort": "5247"
10 
11   }
appseting设置
复制代码
复制代码
 1 public class AppHelper
 2     {
 3         private static IConfiguration _config;
 4 
 5         public AppHelper(IConfiguration configuration)
 6         {
 7             _config = configuration;
 8         }
 9 
10         /// <summary>
11         /// 读取指定节点的字符串
12         /// </summary>
13         /// <param name="sessions"></param>
14         /// <returns></returns>
15         public static string ReadAppSettings(params string[] sessions)
16         {
17             try
18             {
19                 if (sessions.Any())
20                 {
21                     return _config[string.Join(":", sessions)];
22                 }
23             }
24             catch
25             {
26                 return "";
27             }
28             return "";
29         }
30 
31         /// <summary>
32         /// 读取实体信息
33         /// </summary>
34         /// <typeparam name="T"></typeparam>
35         /// <param name="session"></param>
36         /// <returns></returns>
37         public static List<T> ReadAppSettings<T>(params string[] session)
38         {
39             List<T> list = new List<T>();
40             _config.Bind(string.Join(":", session), list);
41             return list;
42         }
43     }
获取appsetting文件类
复制代码
复制代码
 1  [Route("api/[controller]")]
 2     [ApiController]
 3     public class HealthController : ControllerBase
 4     {
 5         [HttpGet]
 6         [Route("Check")]
 7         public IActionResult Check()
 8         {
 9             return Ok();
10         }
11     }
心跳代码
复制代码

 

  2.服务发现代码,目的是通过调用consul注册中心的服务

复制代码
 1 private static int index = 0;
 2         [HttpGet]
 3         [Route("Contents")]
 4         public IActionResult Contents()
 5         {
 6             string url = $"http://{AppHelper.ReadAppSettings("Consul", "serviceName")}/api/values";
 7             ConsulClient client = new ConsulClient(c=>
 8             {
 9                 c.Address = new Uri(AppHelper.ReadAppSettings("Consul", "consulAddress"));
10             }
11             );
12             var res = client.Agent.Services().Result.Response;
13             Uri uris = new Uri(url);
14             string groupname = uris.Host;
15             var dic = res.Where(s => s.Value.Service.Equals(groupname, StringComparison.OrdinalIgnoreCase)).ToArray();
16             //轮询读取
17             return Content(Newtonsoft.Json.JsonConvert.SerializeObject(dic[index++ % dic.Length].Value));
18         }
服务发现代码
复制代码

 

六、Consul集群,做集群测试

  配置地址:https://blog.csdn.net/weixin_46785144/article/details/117172621

七、拓展点

  上面的服务发现读取上,当单个服务达到瓶颈了,这时候我们就要负载均衡来分担服务器的压力,那么我们下一节来讲Consul如何进行负载均衡

 

代码:https://gitee.com/runwei/consul.git

 

posted @   冼润伟  阅读(1653)  评论(6编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示