手写RPC框架之服务注册与发现

本文介绍了在自定义RPC框架中如何实现服务注册与发现功能,对比了Zookeeper和Nacos的区别,并详细阐述了两者在服务注册、服务发现的流程。在Zookeeper中,服务存储采用树形结构,服务提供方注册服务,消费方订阅并从Zookeeper获取服务信息。而在Nacos中,服务提供方与Nacos保持长连接,服务变更时会自动更新。文章提供了Zookeeper和Nacos的代码实现示例。
摘要由CSDN通过智能技术生成

在这里插入图片描述
dubbo的服务架构可以看出, Registry主要提供服务的注册与发现功能:即服务的提供方将服务注册在Registry中,而服务的消费方可以从注册的服务里获取提供方的ip地址等信息,从而进行远程过程调用。

服务注册发现中心

Zookeeper Nacos Eureka 的区别

面试需要知道的Zookeeper知识

接口定义

在这里插入图片描述

@SPI
public interface ServiceRegistry {
   
    /**
     * 注册服务
     * @param rpcServiceName
     * @param inetSocketAddress
     */
    void registerService(String rpcServiceName, InetSocketAddress inetSocketAddress);

    /**
     * 下线服务
     * @param rpcServiceName
     * @param inetSocketAddress
     */
    void unregisterService(String rpcServiceName, InetSocketAddress inetSocketAddress);
}
@SPI
public interface ServiceDiscovery {
   
    /**
     * lookup service by rpcServiceName
     * @param rpcServiceName
     * @return
     */
    InetSocketAddress lookupService(String rpcServiceName);
}

Zookeeper

服务存储分层

Zookeeper数据存储方式类似于树的组织方式,一个节点下可以有多个子节点。
在这里插入图片描述
参考上面dubbozookeeper的分层方式,在该rpc框架中简化分为rootserviceaddress三层,如下。root层主要就是标识框架的名字,无实际含义;service存储服务的名字,包括Service接口类的全限定名和分组(group用于区分一个接口的多个实现类);address层主要存储的就是提供该服务的服务提供者ip地址和端口。
在这里插入图片描述

服务注册发现流程

调用关系说明

  • 服务提供方启动,注册本地服务到zookeeper
  • 服务消费方启动,订阅感兴趣的服务,从zookeeper上拉取感兴趣的服务及服务的提供者地址到本地;同时监听zookeeper中感兴趣的服务节点。
  • 服务提供方一旦上线新服务,或者服务提供方关机而从zookeeper中删除自己注册的服务,此时会触发服务消费方监听节点的事件响应,服务消费方会重新拉取最新的服务提供列表到本地。

注意

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动及服务变更时与注册中心交互,不是每次都需要去注册中心查找服务列表,注册中心不转发请求,压力较小
  • 注册中心,服务提供者,服务消费者三者之间均为长连接
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者(通过Zookeeper的监听事件感知)

代码实现

在这里插入图片描述
ZkServiceRegistry 服务注册

public class ZkServiceRegistry implements ServiceRegistry {
   
    @Override
    public void registerService(String rpcServiceName, InetSocketAddress inetSocketAddress) {
   
        String servicePath = CuratorUtils.ZK_REGISTER_ROOT_PATH + "/" + rpcServiceName + inetSocketAddress.toString();
        CuratorFramework zkClient = CuratorUtils.getZkClient();
        CuratorUtils.createEphemeralNode(zkClient, servicePath);
    }

    @Override
    public void unregisterService(String rpcServiceName, InetSocketAddress inetSocketAddress) {
   
        String servicePath = CuratorUtils.ZK_REGISTER_ROOT_PATH + "/" + rpcServiceName + inetSocketAddress.toString();
        try {
   
            CuratorUtils.getZkClient().delete().forPath(servicePath);
        } catch (Exception e) {
   
            e.printStackTrace(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值