共计 4670 个字符,预计需要花费 12 分钟才能阅读完成。
大家好,良久没有输入博文了,一是因为比较忙,另外一个起因是最近次要的精力是在给 AgileConfig 增加一个新的性能:服务注册与发现。
先说说为什么会增加这个性能。我本人的我的项目是用 Consul 来做为服务注册发现组件的。自从我上线了 AgileConfig 做为配置核心后,我就很少去 Consul 察看服务的在线状态了,因为 AgileConfig 客户端列表曾经在肯定水平上能代表服务的状态了。服务注册发现与配置核心其实实质上都是解决了一类问题,那就是配置的动态化,所以大家会看到业界驰名的组件很多都是同时实现这 2 个性能的,如 Consul,Nacos 等。所以我想罗唆把这个性能给加上吧,这样能够省去部署一个组件。
当然也有同学说我不务正业,不去好好搞配置核心去搞什么服务注册发现。然而我还是做了。。。
不过大家释怀 AgileConfig 的主业还是在配置核心上,服务注册发现只是附赠的小菜,能够用也能够不必,决定权齐全在你。在实现上我也是对两个性能是齐全解耦的。也就是说这 2 个性能都是互不影响独立运行的。惟一有交加的一个中央是,如果配置核心的客户端的 websocket 通道建设胜利的时候,服务的心跳会借用这个通道。
✨✨✨Github 地址:https://github.com/dotnetcore/AgileConfig 开源不易,欢送 star✨✨✨
✨✨✨Gitee 地址:https://gitee.com/kklldog/AgileConfig ✨✨✨
什么是服务注册与发现
首先先让咱们回顾下服务注册发现的概念。
在施行微服务之后,咱们的调用都变成了服务间的调用。服务间调用须要晓得 IP、端口等信息。再没有微服务之前,咱们的调用信息个别都是写死在调用方的配置文件里(当然这话不相对,有些公司会把这些信息写到数据库等公共的中央,以不便保护)。又因为业务的简单,每个服务可能依赖 N 个其余服务,如果某个服务的 IP,端口等信息产生变更,那么所有依赖该服务的服务的配置文件都要去批改,这样显然太麻烦了。有些服务为了负载是有个多个实例的,而且可能是随时会调整实例的数量。如果每次调整实例数量都要去批改其余服务的配置并重启那太麻烦了。
为了解决这个问题,业界就有了服务注册发现组件。
假如咱们有服务 A 须要调用服务 B,并且有服务注册发现组件 R。整个大抵流程将变成大略 3 部:
服务 B 启动向服务 R 注册本人的信息
服务 A 从服务 R 拉取服务 B 的信息
服务 A 调用服务 B
有了服务注册发现组件之后,当批改 A 服务信息的时候再也不必去批改其余相干服务了。
参考我的另外一篇:.Net Core with 微服务 – Consul 注册核心
应用服务注册与发现
应用服务注册与发现性能须要更新服务端与客户端至 1.6.0 及以上版本。
启动服务端
服务端更新至 latest 镜像或 v-1.6.0 以上的镜像。
应用 docker 运行服务端实例:
sudo docker run \
--name agile_config \
-e TZ=Asia/Shanghai \
-e adminConsole=true \
-e db:provider=sqlite \
-e db:conn="Data Source=agile_config.db" \
-p 5000:5000 \
#-v /your_host_dir:/app/db \
-d kklldog/agile_config:latest
根本的应用没有太大的变动,只是在界面上增加了服务的相干治理界面,这里不在赘述。
相干教程: .Net Core & Agile Config 配置核心
应用客户端
客户端须要从 nuget 上装置 1.6.0 版本以上的 client 包。
Install-Package AgileConfig.Client -Version 1.6.0
新版的 client 简化了应用形式,以下以 .net6 为示例:
调用 UseAgileConfig 扩大办法即可注入 AgileConfig client .
var builder = WebApplication.CreateBuilder(args);
//use agileconfig client
builder.Host.UseAgileConfig();
...
在 appsettings.json 增加配置信息:
"AgileConfig": {
"appId": "test_app",
"secret": "test_app",
"nodes": "http://agileconfig_server.xbaby.xyz/",
"name": "client123",
"tag": "tag123",
"serviceRegister": { // 服务注册信息,如果不配置该节点,则不会启动任何跟服务注册相干的服务 可选
"serviceId": "net6", // 服务 id,全局惟一,用来惟一标示某个服务
"serviceName": "net6MVC 服务测试", // 服务名,能够反复,某个服务多实例部署的时候这个 serviceName 就能够反复
"ip": "127.0.0.1", // 服务的 ip 可选
"port": 5005, // 服务的端口 可选
}
其中 appId , secret 等配置同原来配置核心的应用形式没有任何扭转。serviceRegister
节点形容的是服务注册信息(如果删除这个节点那么服务注册性能就不会启动):
- serviceId
服务 id,全局惟一,用来惟一标示某个服务 - serviceName
服务名,能够反复,某个服务多实例部署的时候这个 serviceName 就能够反复 - ip
服务的 ip 可选 - port
服务的端口 可选 - metaData
一个字符串数组,能够携带一些服务的相干信息,如版本等 可选 -
alarmUrl
告警地址 可选。
如果某个服务出现异常状况,如一段时间内没有心跳,那么服务端会往这个地址 POST 一个申请并且携带服务相干信息,用户能够本人去实现揭示性能,比方发短信,发邮件等:{ "serviceId":"0001", "serviceName":"xxxx", "time":"2022-01-01T12:00:000", "status":"Unhealty", "message": "服务不衰弱" }
- heartbeat:mode
指定心跳的模式,server/client。server 代表服务端被动检测,client 代表客户端被动上报。不填默认 client 模式 可选 - heartbeat:interval
心跳的距离,默认工夫 30s 可选 -
heartbeat:url
心跳模式为 server 的时候须要填写衰弱检测地址,如果是 httpstatus 为 200 段则断定存活,其它都视为失败 可选服务的注册
当配置好客户端后,启动对应的应用程序,服务信息会主动注册到服务端并且开始心跳。如果服务正确注册到服务端,控制台的服务治理界面能够查看:
服务发现
当初服务曾经注册下来了,那么怎么能力拿到注册核心所有的服务呢?同样非常简单,在程序内只有注入
IDiscoveryService
接口就能够通过它拿到所有的注册的服务。public interface IDiscoveryService {string DataVersion { get;} List<ServiceInfo> UnHealthyServices {get;} List<ServiceInfo> HealthyServices {get;} List<ServiceInfo> Services {get;} Task RefreshAsync();}
除了接口内置的办法,还有几个扩大办法不便用户应用,比方随机一个服务:
public static class DiscoveryServiceExtension {public static IEnumerable<ServiceInfo> GetByServiceName(this IDiscoveryService ds, string serviceName) {return ds.Services.GetByServiceName(serviceName); } public static ServiceInfo GetByServiceId(this IDiscoveryService ds, string serviceId) {return ds.Services.GetByServiceId(serviceId); } public static ServiceInfo RandomOne(this IDiscoveryService ds, string serviceName) {return ds.Services.RandomOne(serviceName); } }
至此服务的注册与发现就曾经实现了。
一些重要的信息
以上就是服务注册发现的简略应用,然而还有一些比拟重要的信息心愿大家在应用之前可能理解,这样有利于更好的应用以及呈现问题的时候定位问题。
高可用
同 AgileConfig 的配置核心性能一样,服务注册后最初都是写到了数据库里。AgileConfig 的服务端能够部署多个来避免单点故障,同时能够分担压力。所以高可用的最佳实际就是部署 2 个以上的服务端节点,而后数据库做高可用计划。这样足够应酬大多数要求不是特地高的场景。
强一致性
同上 AgileConfig 通过数据库保障多个节点部署的时候的一致性问题。
服务的衰弱检测
服务的衰弱检测个别有 2 种计划:
- 服务端被动询问
- 客户端被动心跳
AgileConfig 同时反对以上 2 个计划。AgileConfig client 默认实现了被动心跳。AgileConfig client 的被动心跳有 2 个渠道: - websocket
长连贯,如果 AgileConfig client 做为配置核心客户端是失常工作的,那么心跳会走 websocket 通道 - http
如果 websocket 不可用,那么会间接发动 http 申请做为心跳。
然而对于一些利用被动的心跳并不能代表服务真的是能够用的,因为心跳从服务已启动就会开始,然而某些接口可能还没真正的做好筹备被调用。那么这个时候就能够抉择服务端被动询问(heartbeat:mode=server)对应的检测接口来确定服务是否真的可用。
AgileConfig 其实还实现了第三种形式: -
不检测
如果一个服务你确定它会永远在线,或者是没方法集成 AgileConfig client 的 sdk,那么你能够标记它为不检测,这样它会始终是衰弱状态。服务发现是如何即时更新的
咱们的 client 在启动后会拉取一次全量的服务列表。然而服务是会一直的上线,下线的,所以服务状态的更新是须要告诉客户端的,而后客户端去拉取新的服务列表。AgileConfig 同样有 2 个策略来保障服务列表的即时刷新:
- 当服务状态变动的时候,服务端通过 websocket 即时告诉所有的 client 被动刷新配置列表
-
如果服务端的被动告诉因为网络等起因生效的时候,client 会在每次心跳的时候比拟本地服务列表 md5 版本跟服务端的列表的 md5 信息,如果不统一,那么 client 会被动拉取一次新的服务列表。
敞开服务注册与发现
删除
serviceRegister
配置节点或不要配置任何信息。
最初
✨✨✨Github 地址:https://github.com/dotnetcore/AgileConfig 开源不易,欢送 star✨✨✨
✨✨✨Gitee 地址:https://gitee.com/kklldog/AgileConfig ✨✨✨
演示地址:http://agileconfig_server.xbaby.xyz/ 超级管理员账号:admin 明码:123456