【手写dubbo-3】rpc框架起源——远程调用最开始的样子!

功能介绍

​ 第一个版本,使用netty完成一个RPC调用,使得在开发时通过调用本地方法即可完成远程调用。主要设计内容netty、自定义协议、反射等。

功能架构图

image-20210508180915785

  1. 启动nettyserver。
  2. 客户端调用本地UserService的方法。
  3. 客户端通过反射实现netty远程调用,调用server的实现类。
  4. 客户端请求成功,获得响应之后打印结果。

功能预览

image-20210508214651041

image-20210508214720896

项目结构图

±–dubbo-client springboot服务,client端

±–dubbo-common 公共模块,放rpc的编解码内容

±–dubbo-server netty服务模块

±–dubbo-server-service 接口信息

主要说明

​ 此为第一个版本,使用很牵强的方式,完成了RPC调用,稍后会逐步优化,稍后会逐步分完善,添加自动扫描加载,负载均衡等RPC框架中必要的功能。

核心代码

Server端

public class NettyServer {
    public static void startServer(String hostName, int port) {
        startServer0(hostName,port);
    }
    //编写一个方法,完成对NettyServer的初始化和启动
    private static void startServer0(String hostname, int port) {

        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {

            ServerBootstrap serverBootstrap = new ServerBootstrap();

            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                                      @Override
                                      protected void initChannel(SocketChannel ch) throws Exception {
                                          ChannelPipeline pipeline = ch.pipeline();
                                          pipeline.addLast(new DubboDecoder ());
                                          pipeline.addLast(new DubboEncoder ());
                                          pipeline.addLast(new NettyServerHandler ()); //业务处理器

                                      }
                                  }

                    );

            ChannelFuture channelFuture = serverBootstrap.bind(hostname, port).sync();
            System.out.println("服务提供方开始提供服务~~");
            channelFuture.channel().closeFuture().sync();

        }catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

Client端

public static void main (String[] args)
	{
		RpcProxy rpcProxy = new RpcProxy();
		UserService bean = rpcProxy.getBean (UserService.class);
    	//调用本地方法,实际是进行了远程调用。
		String userNameById = bean.getUserNameById (12l);
		System.out.println ("userName:"+userNameById);
	}
public class RpcProxy
{
    //编写方法使用代理模式,获取一个代理对象
    public <T> T  getBean(final Class<T> serivceClass) {
        return (T) Proxy.newProxyInstance(serivceClass.getClassLoader(),
                new Class<?>[]{serivceClass}, new InvocationHandler() {
                    //这里实际上是封装RpcRequest请求对象,然后通过Netty发给服务端
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //封装RpcRequest对象---->
                        NettyClientHandler client = new NettyClientHandler();
                        //创建EventLoopGroup
                        NioEventLoopGroup group = new NioEventLoopGroup();
                        Bootstrap bootstrap = new Bootstrap();
                        bootstrap.group(group)
                                .channel(NioSocketChannel.class)
                                .option(ChannelOption.TCP_NODELAY, true)
                                .handler(
                                        new ChannelInitializer<SocketChannel>() {
                                            @Override
                                            protected void initChannel(SocketChannel ch) throws Exception {
                                                ChannelPipeline pipeline = ch.pipeline();
                                                pipeline.addLast(new DubboDecoder ());
                                                pipeline.addLast(new DubboEncoder ());
                                                pipeline.addLast(client);
                                            }
                                        }
                                );

                        try {
                            ChannelFuture future = bootstrap.connect ("127.0.0.1", 7777).sync ();
                            String s = serivceClass.getSimpleName () + "#" + method.getName () + "#" + args[0];
                            DubboProtocol dubboProtocol = new DubboProtocol (s);
                            future.channel ().writeAndFlush (dubboProtocol);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //等待其返回
                        Thread.sleep (1000L);
                        return client.getResult ();
                    }
                });
    }

}

源码地址:git源码地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叁滴水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值