【RPC项目】3.增加注册中心

该博客介绍了如何在RPC项目中增加注册中心,利用ZooKeeper作为注册中心,通过Curator框架进行操作。主要内容包括服务注册、服务发现、服务下线和负载均衡。服务注册将服务写入ZooKeeper,服务发现则采用负载均衡策略选择服务地址。此外,ZkServiceProviderImpl采用单例模式,并引入RpcServiceConfig以version和group区分服务。
摘要由CSDN通过智能技术生成

增加注册中心工作内容主要是服务注册、服务发现、服务下线,负载均衡。并且将服务端提供的服务用 ZkServiceProviderImpl 保存。

注册中心使用 ZooKeeper 实现,使用 Curator 框架对 ZooKeeper 进行调用。
服务注册包括注册服务的方法,将服务写到 ZooKeeper 中。
服务发现包括发现服务的方法,通过负载均衡选择服务地址。
服务下线包括删除所有服务端的服务。
负载均衡这里只实现了最简单的随机分配。
ZkServiceProviderImpl 需要使用单例模式,增加了 SingletonFactory 类。

为了方便不同的服务端之间进行区分,增加了 RpcServiceConfig 类,主要用 version 和 group 来区分。同时将之间的 Service 和 Client 类优化,提取了启动的关键代码,将其他过程放到 Client 和 Server 文件夹内。
在这里插入图片描述
在这里插入图片描述

以下是部分重要代码:

package common.dto;

import lombok.*;

/**
 * @Author:Summer
 * @Data:2022/2/21 20:07
 */
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@ToString
public class RpcServiceConfig {
   
    /**
     * service version
     */
    private String version = "";
    /**
     * when the interface has multiple implementation classes, distinguish by group
     */
    private String group = "";

    /**
     * target service
     */
    private Object service;

    public String getRpcServiceName() {
   
        return this.getServiceName() + this.getGroup() + this.getVersion();
    }

    public String getServiceName() {
   
        return this.service.getClass().getInterfaces()[0].getCanonicalName();
    }
}

package common.provider.impl;

import common.Exceptions.RpcException;
import common.dto.RpcServiceConfig;
import common.provider.ServiceProvider;
import common.register.ServiceRegistry;
import common.register.zookeeper.ZkServiceRegistryImpl;
import demo4.Server.SocketRpcServer;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author:Summer
 * @Data:2022/2/21 20:08
 */
@Slf4j
public class ZkServiceProviderImpl implements ServiceProvider {
   

    /**
     * key: rpc service name(interface name + version + group)
     * value: service object
     */
    private final Map<String, Object> serviceMap;
    private final Set<String> registeredService;
    private final ServiceRegistry serviceRegistry;

    public ZkServiceProviderImpl() {
   
        serviceMap = new ConcurrentHashMap<>();
        registeredService = ConcurrentHashMap.newKeySet();
        serviceRegistry = new ZkServiceRegistryImpl();
    }

    @Override
    public void addService(RpcServiceConfig rpcServiceConfig) {
   
        String rpcServiceName = rpcServiceConfig.getRpcServiceName();
        if (registeredService.contains(rpcServiceName)) {
   
            return;
        }
        registeredService.add(rpcServiceName);
        serviceMap.put(rpcServiceName, rpcServiceConfig.getService());
        log.info("Add service: {} and interfaces:{}", rpcServiceName, rpcServiceConfig.getService().getClass().getInterfaces());
    }

    @Override
    public Object getService(String rpcServiceName) {
   
        Object service = serviceMap.get(rpcServiceName);
        if (null == service) {
   
            throw new RpcException("SERVICE_CAN_NOT_BE_FOUND");
        }
        return service;
    }

    @Override
    public void publishService(RpcServiceConfig rpcServiceConfig) {
   
        try {
   
            String host = InetAddress.getLocalHost().getHostAddress();
            this.addService(rpcServiceConfig);
            serviceRegistry.registerService(rpcServiceConfig.getRpcServiceName(), new InetSocketAddress(host, SocketRpcServer.port));
        } catch (UnknownHostException e) {
   
            log.error("occur exception when getHostAddress", e);
        }
    }

}
package common.register.zookeeper;

import common.register.ServiceRegistry;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;

import java.net.InetSocketAddress;

/**
 * @Author:Summer
 * @Data:2022/2/21 00:29
 */
@Slf4j
public class ZkServiceRegistryImpl 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.createPersistentNode(zkClient, servicePath);
    }
}
package common.register.zookeeper;

import common.Exceptions.RpcException;
import common.dto.RpcRequest;
import common.loadbalance.LoadBalance;
import common.loadbalance.loadbalancer.RandomLoadBalance;
import common.register.ServiceDiscovery;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * @Author:Summer
 * @Data:2022/2/21 00:18
 */
@Slf4j
public class ZkServiceDiscoveryImpl implements ServiceDiscovery {
   
    private final LoadBalance loadBalance;

    public ZkServiceDiscoveryImpl() {
   
        //this.loadBalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension("loadBalance");
        this.loadBalance = new RandomLoadBalance();
    }

    @Override
    public InetSocketAddress lookupService(RpcRequest rpcRequest) {
   
        String rpcServiceName = rpcRequest.getRpcServiceName();
        CuratorFramework zkClient = CuratorUtils.getZkClient();
        List<String> serviceUrlList = CuratorUtils.getChildrenNodes(zkClient, rpc
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值