그 RPC 프레임 워크 (b)를 실현

언젠가는 관심이 전에 이동 전에 RPC 자신의 바퀴를 개최하지만, 사육사는 단순로드 밸런싱을 해결 공급자 및 자동 소비자를 실현 사용을 기반으로, 원본을 변화시킬 가장 최근에, 비교적 간단 바퀴 --- 달성하기 위해 RPC 손을 .

RPC 모델

등록 및 검색 서비스 사육사에 기초하여, 변형의 의존성에 TCP를 사용하여 원래의 직접 연결에 기초한다.

아이-RPC

사용 방법

말을 많이하지 않았나요, 우리는 게시 및 참조 서비스하는 방법에 대해 알아. IP 및 기본 정보 서비스의 포트 번호는 사육사에 등록 된 우리의 서비스를 종료합니다.

/**
 * @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();
        }
    }
}
复制代码

그들의 서비스에 대한 참조 레지스터에 의해 사육사.

/**
 * @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());
        }
    }
}
复制代码

운영 결과를 게시하지 하나가 관심이 파트너는 GitHub의에 작은 집주인에 도달 소스 볼 수 이것은 RPC 휠입니다 .

게시 및 서비스를 가입

원래 코드에 기초 집주인은 논리 사육사, 켜십시오 원래의 코드와 관련된 프리젠 테이션 등록 추가합니다 --- RPC 손으로 만든 바퀴가 달성하기를 .

출판 서비스

/**
* 发布服务
*/
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);
        }
    }
}

复制代码

서브 스크립 션 서비스

/**
* 服务的引用.
*/
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]));
}
复制代码

위의 코드는 원래의 직접 연결을 기준으로 동작 ZK를 추가, 비교적 간단하다에,이다 가능한 서비스를 참조 할 때 릴리스 서비스는 IP의 공급자 및 ZK에 대한 기본 정보의 포트 번호, ZK에서 선택하는 임의의 알고리즘을 사용하여 등록 할 때 공급자 정보는 다음 전화를 호출합니다.

개요

RPC (원격 프로 시저 호출) 기본 논리는 비교적 간단는 RPC 구현하는 동안 코드 집주인 참조 프레임의 다른 부분, 혜택을 ~

추천

출처juejin.im/post/5d491a5ee51d45620771f076