【Dubbo系列】Easy-Dubbo——简单的Dubbo框架实现

Easy-Dubbo——简单的Dubbo框架实现

实现原理

  1. 服务提供者端将将接口注册到注册中心,并指明对应的实现类。通过tomcat、netty等实现网络通信,将服务暴露出去。内部使用servlet等实现路由在收到消费端请求时找到对应的实现类。
  2. 服务消费者使用从注册中心获取url列表,使用随机数等算法找到一个url,将参数、方法名当做http等协议的请求请求参数发起调用。

源码解析

服务端

  1. 服务端启动。
  2. 将url注册到远程服务器上
  3. 将本地实现缓存
  4. 根据协议启动服务,协议有dubbo和http
public class Provider {


    public static void main(String[] args) {


        LocalRegister.register(HelloService.class.getName(),"1.0", HelloServiceImpl.class);
        LocalRegister.register(HelloService.class.getName(),"2.0", HelloServiceImpl2.class);
        //注册中心
        URL u1 = new URL("localhost", 9999);
        URL u2 = new URL("localhost", 9998);
        RemoteMapRegister.regist(HelloService.class.getName(),"1.0", u1);
        RemoteMapRegister.regist(HelloService.class.getName(),"2.0", u1);
      //  RemoteMapRegister.regist(HelloService.class.getName(),"2.0", u2);

//        HttpServer httpServer = new HttpServer();
        Protocol protocol = ProtocolFactory.getProtocol();
        protocol.start(u1);
        //protocol.start(u2);
    }
}

客户端

  1. 获取代理对象
public class Consumer {

    public static void main(String[] args) {
        HelloService helloService = ProxyFactory.getProxy(HelloService.class,"1.0");
        String cgm = helloService.say("CGM");
        System.out.println(cgm);
    }
}
  1. 根据协议获取对应的服务,进行发送消息。
public class ProxyFactory {


    public static <T> T getProxy(Class interFaceClass,String version) {
        
        return (T) Proxy.newProxyInstance(interFaceClass.getClassLoader(), new Class[]{interFaceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Invocation invocation = new Invocation();
                invocation.setInterfaceName(interFaceClass.getName());
                invocation.setMethodName(method.getName());
                invocation.setParamTypes(method.getParameterTypes());
                invocation.setParams(args);
                invocation.setVersion(version);
                //HttpClient httpClient = new HttpClient();
                //NettyClient httpClient = new NettyClient<>();
                Protocol protocol = ProtocolFactory.getProtocol();
                List<URL> urls = RemoteMapRegister.get(interFaceClass.getName()+version);
                //负载均衡
                URL url = LoadBalance.
                        getUrl(urls);

                String result = protocol.send(url, invocation);
                return result;
            }
        });
    }
}

Netty的启动服务器

netty启动服务

public class NettyServer {

    public void start(String hostName, int port) {
        try {
            final ServerBootstrap bootstrap = new ServerBootstrap();
            NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
            bootstrap.group(eventLoopGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast("decoder", new ObjectDecoder(ClassResolvers
                                    .weakCachingConcurrentResolver(this.getClass()
                                            .getClassLoader())));
                            pipeline.addLast("encoder", new ObjectEncoder());
                            pipeline.addLast("handler", new NettyServerHandler());
                        }
                    });
            bootstrap.bind(hostName, port).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void close() {

    }
}

// netty服务器接收消息处理:NettyServerHandler
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Invocation invocation = (Invocation) msg;

        Class serviceImpl = LocalRegister.get(invocation.getInterfaceName() + invocation.getVersion());

        Method method = serviceImpl.getMethod(invocation.getMethodName(), invocation.getParamTypes());
        Object result = method.invoke(serviceImpl.newInstance(), invocation.getParams());

        System.out.println("Netty-------------" + result.toString());
        ctx.writeAndFlush("Netty:" + result);
    }
}

netty客户端发消息

public class NettyClient<T> {

    public NettyClientHandler client = null;

    private static ExecutorService executorService = Executors.newCachedThreadPool();

    public void start(String hostName, Integer port) {
        client = new NettyClientHandler();

        Bootstrap b = new Bootstrap();
        EventLoopGroup group = new NioEventLoopGroup();
        b.group(group)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        pipeline.addLast("decoder", new ObjectDecoder(ClassResolvers
                                .weakCachingConcurrentResolver(this.getClass()
                                        .getClassLoader())));
                        pipeline.addLast("encoder", new ObjectEncoder());
                        pipeline.addLast("handler", client);
                    }
                });

        try {
            b.connect(hostName, port).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public String send(String hostName, Integer port, Invocation invocation) {
        if (client == null) {
            start(hostName, port);
        }

        client.setInvocation(invocation);
        try {
            return (String) executorService.submit(client).get();
        } catch (InterruptedException e) {
//            e.printStackTrace();
        } catch (ExecutionException e) {
//            e.printStackTrace();
        }
        return null;
    }
}

// netty客户端接收消息处理:NettyClientHandler
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext context;
    private Invocation invocation;
    private String result;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        context = ctx;
    }

    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        result = msg.toString();
        notify();
    }

    public synchronized Object call() throws Exception {
        context.writeAndFlush(this.invocation);
        wait();
        return result;
    }

    public void setInvocation(Invocation invocation) {
        this.invocation = invocation;
    }
}

项目地址

  • https://gitee.com/charles_ruan/easy-dubbo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值