【java中间件】自己动手实现一个属于自己的mydubbo

摘要

最近在学习zookeeper的选举机制和使用、java如何调用及应用场景,dubbo理所应当的进入了我的视野,作为阿里开源的强大中间件dubbo,我们也应该了解其基本原理和应用场景。
RPC,远程服务调用,dubbo作为服务调用的中间人,为服务消费者和服务提供者来提供服务,首先,要知道dubbo的主要功能:

  1. 提供服务注册和服务发现的功能(依赖zookeeper)
  2. 服务间的通讯
  3. 实现服务间无感知调用

了解这些之后,大致理一下我们主要需要做的事:

  1. (由于分布式情况下,需要保持一致性)需要从zookeeper上创建、查找服务
  2. 制定某种通讯协议实现服务间的通讯
  3. 使用某种设计模式来实现服务间的无感知调用

思路理清之后,可以开始动手了。
使用技术:
- zookeeper
- netty
- jdk自带动态代理

服务注册中心:服务注册和服务发现

由于需要调用zookeeper,先搭建好zookeeper环境

  1. 既然需要连接zookeeper,需要一个管理zk连接的类
/**
 * @author XCXCXCXCX
 * @date 2018/9/2
 * @comments
 */
public enum CuratorManager {
    INSTANCE;

    private CuratorFramework client;

    private CuratorManager(){
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        client =
                CuratorFrameworkFactory.builder()
                        .connectString("10.211.139.56:2181,10.211.139.56:2181,192.168.179.129:2181")
                        .sessionTimeoutMs(5000)
                        .connectionTimeoutMs(5000)
                        .retryPolicy(retryPolicy)
                        .build();
    }

    public CuratorFramework getClient(){
        return CuratorManager.INSTANCE.client;
    }
}
  1. 有了zk的连接类,可以实现一个注册中心的类了
/**
 * @author XCXCXCXCX
 * @date 2018/9/2
 * @comments
 */
public class ServiceRegistry {
   

    private static Logger log = LogManager.getLogger("ServiceRegistry");

    private CuratorFramework client = CuratorManager.INSTANCE.getClient();

    public void registerService(String serviceName,String serviceAddress){
        client.start();
        if(serviceName==null||serviceAddress==null){
            throw new NullParamException("ServiceRegistry: serviceName and serviceAddress should not be null!");
        }

        String path = "/registry/" + serviceName;
        try {
            if(client.checkExists().forPath(path) == null){
                client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path,serviceAddress.getBytes());
                log.info("服务注册成功!");
            }else{
                client.setData().forPath(path,serviceAddress.getBytes());
                log.info("服务已存在,更新成功!");
            }
//            System.out.println(client.getChildren().forPath(path));
//            System.out.println(new String(client.getData().forPath(path)));
//            Stat stat = new Stat();
//            System.out.println(new String(client.getData().storingStatIn(stat).forPath(path)));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String discoverService(String serviceName){
        client.start();
        //获取服务地址
        if(serviceName==null){
            throw new NullParamException("ServiceRegistry: serviceName should not be null!");
        }
        String path = "/registry/"+serviceName;
        try {
            return new String(client.getData().forPath(path));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

指定通讯协议,利用netty实现异步通讯

谈到通讯,无非就是server和client,理清server和client的任务:
Server:

  • 开启监听,等待client请求
  • 当client请求调用服务时,查询服务是否已注册在dubbo上
  • 如果存在服务,调用该服务并返回该服务调用情况

Client:

  • 根据服务接口,向远程服务器发起请求
  • 当请求发送成功后,等待远程服务器的响应,获取服务调用情况

Server

/**
 * @author XCXCXCXCX
 * @date 2018/9/2
 * @comments
 */
public class Main {
   

    public void init() {
        //初始化注册中心,注册已有服务
        
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值