大家好,好久没有输出博文了,一是因为比较忙,另外一个原因是最近主要的精力是在给 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种方案:

  1. 服务端主动询问
  2. 客户端主动心跳
    AgileConfig 同时支持以上2个方案。AgileConfig client 默认实现了主动心跳。AgileConfig client 的主动心跳有2个渠道:
  • websocket
    长连接,如果AgileConfig client做为配置中心客户端是正常工作的,那么心跳会走websocket通道
  • http
    如果 websocket 不可用,那么会直接发起 http 请求做为心跳。
    但是对于一些应用主动的心跳并不能代表服务真的是可以用的,因为心跳从服务已启动就会开始,但是某些接口可能还没真正的做好准备被调用。那么这个时候就可以选择服务端主动询问(heartbeat:mode=server)对应的检测接口来确定服务是否真的可用。
    AgileConfig 其实还实现了第三种方式:
  1. 不检测
    如果一个服务你确定它会永远在线,或者是没办法集成 AgileConfig client 的 sdk ,那么你可以标记它为不检测,这样它会一直是健康状态。

服务发现是如何即时更新的

我们的 client 在启动后会拉取一次全量的服务列表。但是服务是会不断的上线,下线的,所以服务状态的更新是需要通知客户端的,然后客户端去拉取新的服务列表。AgileConfig 同样有2个策略来保证服务列表的即时刷新:

  1. 当服务状态变化的时候,服务端通过 websocket 即时通知所有的 client 主动刷新配置列表
  2. 如果服务端的主动通知由于网络等原因失效的时候,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

关注我的公众号一起玩转技术

AgileConfig 1.6.0 发布 - 支持服务注册与发现的更多相关文章

  1. 搞懂Dubbo服务发布与服务注册

    一.前言 本文讲服务发布与服务注册,服务提供者本地发布服务,然后向注册中心注册服务,将服务实现类以服务接口的形式提供出去,以便服务消费者从注册中心查阅并调用服务. 本文源码分析基于org.apache ...

  2. spring boot 2.0.3+spring cloud (Finchley)1、搭建服务注册和发现组件Eureka 以及构建高可用Eureka Server集群

    一 .搭建Eureka 编写Eureka Server 由于有多个spring boot项目,采用maven多module的结构,项目结构如下: 新建一个maven主工程,在主maven的pom文件中 ...

  3. Spring Cloud Consul 实现服务注册和发现

    Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具,它为基于 JVM 的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布 ...

  4. Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现

    自Spring Cloud Alibaba发布第一个Release以来,就备受国内开发者的高度关注.虽然Spring Cloud Alibaba还没能纳入Spring Cloud的主版本管理中,但是凭 ...

  5. 基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现

    0.简介 0.1 什么是 Consul Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置. 这里所谓的服务,不仅仅包括常用的 Api 这些服务,也包括软件开发过程 ...

  6. 微服务SpringCloud之服务注册与发现

    在找.net core 微服务框架时发现了Steeltoe开源项目,它可以基于Spring Cloud实现.net core和.net  Framework的微服务.正好之前也有学习过SpringBo ...

  7. 三. SpringCloud服务注册与发现

    1. Eureka 1.1 Eureka理解 什么是服务治理 Spring Cloud封装了Netflix公司开发的Eurkeka模块来实现服务治理 在传统的rpc远程调用框架中,管理每个服务与服务之 ...

  8. 一起来学Spring Cloud | 第二章:服务注册和发现组件 (Eureka)

    本篇文章,很浅显的一步步讲解如何搭建一个能运行的springcloud项目(带所有操作截图).相信!看完本篇之后,你会觉得springcloud搭建如此简单~~~~ 一. Eureka简介: 1.1  ...

  9. .NET Core微服务之基于Steeltoe使用Eureka实现服务注册与发现

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 =>  Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...

随机推荐

  1. CVE-2021-3129:Laravel远程代码漏洞复现分析

    摘要:本文主要为大家带来CVE-2021-3129漏洞复现分析,为大家在日常工作中提供帮助. 本文分享自华为云社区<CVE-2021-3129 分析>,作者:Xuuuu . CVE-202 ...

  2. CF1106F题解

    居然没人写常系数齐次线性递推/jy 题意明确. 首先我们注意到这个系数是在幂上面的,这道题的各种信息都是建立在乘法上的,十分不好处理,考虑求一个 \(\ln\) 将这些信息建立在加法上. \[\ln ...

  3. Linux特殊权限之suid、sgid、sbit权限

    文件权限管理之特殊命令 一:特殊权限 昨天所学的Linux基本权限为为9个:分别是rwx rwx rwx.但有时会发现系统中会有一些特殊的权限位符号: 例如: Linux系统一共有12个特殊权限符: ...

  4. MySQL — 索引

    目录 1.索引概述 2.索引结构 3.索引分类 4.索引语法 5.SQL 性能分析 5.1.执行频次 5.2.慢日志查询 5.3.profile 5.4.explain 6.索引使用规则 6.1.单列 ...

  5. Python可变参数*args和**kwargs

    本文我们将通过示例了解 Python函数的可变参数*args和 **kwargs的用法. 知识预备:Python 函数和 Python 函数参数 在Python编程中,我们定义一个函数来生成执行类似操 ...

  6. MongoDB 镜像配置方法

    镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. 配置方法 安装 ...

  7. Docker重要容器命令

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 容器重要命令 启动守护式容器 docker run -d 镜像 docker run -d image [command][arg...] 使用c ...

  8. 4月27日 python学习总结 GIL、进程池、线程池、同步、异步、阻塞、非阻塞

    一.GIL:全局解释器锁 1 .GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.GIL的优缺点: 优点:  保 ...

  9. SQL注入手册

    英文版:链接: https://sqlwiki.netspi.com/ 中文版:链接: https://pan.baidu.com/s/1WWmjvYYnLC6_nItMVvUVig 密码: e98r ...

  10. 有序全排列c++实现(递归)

    1 #include <iostream> 2 #include <algorithm> 3 #include <iterator> 4 #include < ...