Realize their RPC framework (b)

Some time ago staged a RPC own wheels, but relatively simple, most recently to transform the original, based on the use Zookeeper realized the provider and consumer automatic addressing simple load balancing, go before the interested making wheels --- RPC hands to achieve .

RPC model

Based on registration and discovery services Zookeeper, the dependence of the transformation is the basis of the original direct connection using TCP on.

child-rpc

how to use

Did not talk much, we look at how to publish and reference services. IP and port number of the basic information services will end our services registered on the Zookeeper.

/**
 * @author wuhaifei 2019-08-02
 */
public class ZookeeperServerMainTest {

    public static void main(String[] args) {
        ServerConfig serverConfig = new ServerConfig();
        serverConfig.setSerializer(AbstractSerializer.SerializeEnum.HESSIAN.serializer)
                .setHost("172.16.30.114")
                .setPort(5201)
                .setRef(HelloServiceImpl.class.getName())
                .setRegister(true)
                .setInterfaceId(HelloService.class.getName());

        RegistryConfig registryConfig = new RegistryConfig().setAddress("127.0.0.1:2181")
                .setSubscribe(true)
                .setRegister(true)
                .setProtocol(RpcConstants.ZOOKEEPER);
        ServerProxy serverProxy = new ServerProxy(new NettyServerAbstract())
                .setServerConfig(serverConfig)
                .setRegistryConfig(registryConfig);
        try {
            serverProxy.export();
            while (true){

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
复制代码

Zookeeper by reference register on their services.

/**
 * @author wuhaifei 2019-08-02
 */
public class ZookeeperClientMainTest {
    public static void main(String[] args) {
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.setProtocol(RpcConstants.ZOOKEEPER)
                .setTimeoutMillis(100000)
                .setSerializer(AbstractSerializer.SerializeEnum.HESSIAN.serializer);

        RegistryConfig registryConfig = new RegistryConfig()
                .setAddress("127.0.0.1:2181")
                .setProtocol(RpcConstants.ZOOKEEPER)
                .setRegister(true)
                .setSubscribe(true);
        ClientProxy<HelloService> clientProxy = new ClientProxy(clientConfig, new NettyClientAbstract(), HelloService.class)
                .setRegistryConfig(registryConfig);
        for (int i = 0; i < 10; i++) {
            HelloService helloService = clientProxy.refer();
            System.out.println(helloService.sayHi());
        }
    }
}
复制代码

Operating results not one posted, interested partners can see the small landlord reached source on github This is a rpc wheel .

Publish and subscribe services

The landlord on the basis of the original code adds registered logic Zookeeper, the original code related presentations please turn made wheels --- RPC hands to achieve .

Publishing services

/**
* 发布服务
*/
public void export() {
    try {
        Object serviceBean = Class.forName((String) serverConfig.getRef()).newInstance();
        RpcInvokerHandler.serviceMap.put(serverConfig.getInterfaceId(), serviceBean);
        this.childServer.start(this.getServerConfig());

        if (serverConfig.isRegister()) {
            // 将服务注册到zookeeper
            register();
        }
    } catch (Exception e) {
        // 取消服务注册
        unregister();
        if (e instanceof ChildRpcRuntimeException) {
            throw (ChildRpcRuntimeException) e;
        } else {
            throw new ChildRpcRuntimeException("Build provider proxy error!", e);
        }
    }
    exported = true;
}

/**
 * 注册服务
 */
protected void register() {
    if (serverConfig.isRegister()) {
        Registry registry = RegistryFactory.getRegistry(this.getRegistryConfig());
        registry.init();
        registry.start();
        try {
            registry.register(this.serverConfig);
        } catch (ChildRpcRuntimeException e) {
            throw e;
        } catch (Throwable e) {
            String appName = serverConfig.getInterfaceId();
            LOGGER.info(appName, "Catch exception when register to registry: "
                    + registryConfig.getId(), e);
        }
    }
}

复制代码

Subscription service

/**
* 服务的引用.
*/
public T refer() {
    try {
        if (config.isSubscribe()) {
            subscribe();
        }
        childClient.init(this.clientConfig);
        return invoke();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * 订阅zk的服务列表.
 */
private void subscribe() {
    Registry registry = RegistryFactory.getRegistry(this.getRegistryConfig());
    registry.init();
    registry.start();

    this.clientConfig = (ClientConfig) config;
    List<String> providerList = registry.subscribe(this.clientConfig);

    if (null == providerList) {
        throw new ChildRpcRuntimeException("无可用服务供订阅!");
    }

    // 使用随机算法,随机选择一个provider
    int index = ThreadLocalRandom.current().nextInt(providerList.size());
    String providerInfo = providerList.get(index);
    String[] providerArr = providerInfo.split(":");
    clientConfig = (ClientConfig) this.config;
    clientConfig.setHost(providerArr[0]);
    clientConfig.setPort(Integer.parseInt(providerArr[1]));
}
复制代码

The above code is relatively simple, is to add the operation zk on the basis of the original Direct Connect is on, when the release services will be registered provider of IP and port number of the basic information on the zk, using a random algorithm to select from zk when referring to services available the provider information, and then invoke call.

summary

RPC (Remote procedure call) the underlying logic is relatively simple, the other part of the code landlord reference frame during the RPC implementation, benefit ~

Guess you like

Origin juejin.im/post/5d491a5ee51d45620771f076