关注

《微服务即时通讯中Etcd的作用》

在 MIMP 项目中,etcd 充当了微服务架构的**“神经中枢” 。它通过 服务注册 和 服务发现**机制,让各个独立的微服务(User, Message, Gateway 等)能够互相感知并协同工作。

下面我结合项目代码,从 服务注册 (我是谁)和 服务发现 (你在哪)两个维度详细说明。

1. 服务注册 (Service Registry) —— “我上线了,请联系我”

每个微服务(如 user_server )启动时,必须把自己登记到 etcd 上,这样其他服务才能找到它。
代码实现
在 etcd.hpp 中, Registry 类负责这个工作。

  1. 绑定租约 (Lease) :
    为了防止服务挂了但 etcd 上还有残留数据,注册时会绑定一个 短期租约 (如 3 秒)。
    // 创建租约,并开启自动续租 (KeepAlive)
    _lease_id = _client->leasekeepalive(3).get().ID;
    
  2. 写入数据 (Put) :
    将服务名和地址写入 etcd。Key 通常是 /service/服务名/实例ID ,Value 是 IP:Port 。
    // 注册服务:Key=/service/user_service/instance_1, 
    Value=127.0.0.1:10003
    _client->put(key, value, _lease_id);
    ```项目应用
    

在 user_server 启动时,会调用 Registry 将自己注册上去。
参考 user_server.hpp :

// 构造注册对象,将本机地址注册到 etcd
_registry_client = std::make_shared<Registry>(reg_host);
_registry_client->registry(service_name, access_host);

2. 服务发现 (Service Discovery) —— “我想找人,他在哪?”

调用方(如 gateway_server )需要知道下游服务(如 user_server )的地址。它不直接读配置文件,而是问 etcd。
代码实现
在 etcd.hpp 中, Discovery 类负责这个工作。

  1. 初始获取 (List) :
    刚启动时,先拉取目录下所有的服务节点。
    auto resp = _client->ls(basedir).get();
    
  2. 实时监听 (Watch) :
    关键点!它会启动一个 Watcher 线程,死死盯着 etcd 的目录。一旦有服务上线(Put)或下线(Delete),立刻触发回调。
    _watcher = std::make_shared<etcd::Watcher>(*_client, 
    basedir, 
        [this](etcd::Response const &resp) {
            if (resp.action() == "put") _put_cb(resp.key(), 
            resp.value());
            if (resp.action() == "delete") _del_cb(resp.key
            ());
        }, true);
    ```项目应用
    

在 gateway_server 中,它通过 ServiceManager 来管理这些发现的服务。
参考 gateway_server.hpp :

// 绑定回调函数:当 etcd 通知有服务上线/下线时,更新本地的连接池
auto put_cb = std::bind(&ServiceManager::onServiceOnline, 
_mm_channels.get(), _1, _2);
auto del_cb = std::bind(&ServiceManager::onServiceOffline, 
_mm_channels.get(), _1, _2);

// 启动服务发现,监听 /service 目录
_service_discoverer = std::make_shared<Discovery>
(reg_host, base_dir, put_cb, del_cb);

3. 实际运行流程 (举例:网关转发登录请求)

  1. UserServer 启动 :
    • 向 etcd 写入 /service/user_service/node1 -> 192.168.1.10:10003 。
    • 开始每秒发送心跳续租。
  2. Gateway 感知 :
    • Discovery 类的 Watcher 收到 PUT 事件。
    • 调用 ServiceManager::onServiceOnline ,建立到 192.168.1.10:10003 的 RPC 连接通道。
  3. UserServer 宕机 :
    • 进程退出,心跳停止。
    • 3秒后,etcd 租约过期,自动删除 /service/user_service/node1 。
  4. Gateway 摘除 :
    • Discovery 收到 DELETE 事件。
    • 调用 ServiceManager::onServiceOffline ,从连接池中移除该通道,后续请求不再发给它。

4. 为什么不用 Redis 做服务发现?

虽然 Redis 也能存 Key-Value,但 etcd 有两个 Redis 无法替代的优势:

  1. 强一致性 (CP) :etcd 基于 Raft 算法,保证集群中所有节点的数据完全一致。服务发现对数据准确性要求极高(不能把请求发给已经挂掉的节点),Redis 的主从复制是异步的,可能存在延迟。
  2. Watch 机制 :etcd 的 Watch 机制专为配置变更设计,能精确推送变更事件。Redis 的 Pub/Sub 是“发后即忘”,如果网络抖动,消费者可能会漏掉上下线通知。

总结

在 MIMP 项目中, etcd 是动态的、实时的服务通讯录 。

  • 代码中 Registry 类利用 Lease 机制实现了 自动注销 。
  • 代码中 Discovery 类利用 Watch 机制实现了 实时感知 。
    这保证了 Gateway 永远只把请求发给活着的服务节点,实现了系统的高可用。

etcd 就是 MIMP 项目的**“活地图”**。它保证了 Gateway 能实时找到所有的后端服务,并且在某个服务宕机时,能立刻感知并停止向其转发请求,确保系统的高可用。

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/fwfxhhx/article/details/158705207

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--