Dubbo教程-04-手写一个RPC

本文通过手写RPC,详细介绍了基于Netty框架的RPC编程模型,从理解RPC概念到实现过程,包括服务接口定义、服务提供者、服务消费者、网络通信等关键环节。通过代码示例展示了从1.0到2.0的升级,强调了通用性和参数序列化的重要性,加深了对RPC原理和Netty事件驱动模型的理解。
摘要由CSDN通过智能技术生成

为什么要手写?

 主要是 为了 理解下 RPC 的一个具体编程模型
和他实现的一些细节
其实就是一个编程模型的 理解 和 实践 过程

基于netty框架

我们之前 学过netty框架的一个 编程模型
server client
基于事件驱动的模式。
上一个例子我们 把 数据传递到服务器
然后 服务器给我们返回数据
中间通过 netty的网络连接 实现打通
那么我们就会想 是否可以 把 传递过去的数据
变成一个抽象,
然后 服务器端的 数据获取 及处理 编程 具体的 实现类
客户端的 模拟调用
变成面向接口

简单画了个图片给大家理解下

说白了就是 客户端 现在 要利用 service 接口
动态生成代理对象
而动态代理的实现细节中加入 和 网络交互
把 具体的代码实现放到了远程服务器。
远程服务器把结果通过网络返回给客户端
客户端再交由代理对象返回
于是我们感知到的就是
本地调用的返回

看起来很你牛逼的样子
不错确实很牛逼

代码

Service.java

public interface Service {

    String sayHelloWithName(String name);
}

这个就是一个服务接口咯
没啥可说的
他接收一个参数
然后返回一个字符串。

ServiceProvider.java

public class ServiceProvider implements Service {
    @Override
    public String sayHelloWithName(String name) {
        return "hello "+name;
    }
}

这个是 service 的具体实现
没啥可说的
就是拿到了 入参 然后 稍微处理下
加了个hello 然后返回了
我们这里只是模拟下

ServiceServer.java

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class ServiceServer {

    private int port = 0;

    public ServiceServer(int port) {
        this.port = port;
    }

    //接收请求
    NioEventLoopGroup boss = new NioEventLoopGroup();
    //处理请求
    NioEventLoopGroup worker = new NioEventLoopGroup();
    //用来启动server
    ServerBootstrap bootstrap = new ServerBootstrap();

    public void run(){
        //告诉用户 输入在哪个端口上
        System.out.println("running on port :"+port);
        try {
            //设置工作组
            bootstrap.group(boss,worker);
            //基于什么样的管道来进行通信
            bootstrap.channel(NioServerSocketChannel.class);
            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline p = ch.pipeline();
                    //解码
                    p.addLast(new StringDecoder());
                    //编码
                    p.addLast(new StringEncoder());
                    //逻辑的实现
                    p.addLast(new ServiceProviderHandler());
                }
            });
            //绑定ip  和端口
            ChannelFuture channelFuture = bootstrap.bind("127.0.0.1", port).sync();
            //启动起来
            channelFuture.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //将worker close
            worker.shutdownGracefully();
            boss.shutdownGracefully();
        }
    }



    public static void main(String[] args) {
        ServiceServer serviceServer = new ServiceServer(9999);
        serviceServer.run();
    }


}

这个就是一个编程模型
netty作为网络服务器
这个类就是一个 server端的代码
万年不变的哦
都是这么写的
大家可以在网上找到很多类似代码
不过我这个是 参照 netty官网 规范写的啊
大家可以借鉴下
server端 我们定有两个 NioEventLoopGroup
一个是boss 一个是 worker
boss 接收请求
worker 处理请求
别的没啥可说的了 照着写

ServiceProviderHandler.java

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class ServiceProviderHandler extends ChannelHandlerAdapter {

    private static final Service SERVICE = new ServiceProvider();


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String s = msg.toString();
        System.out.println("get str from client:"+s);
        ctx.writeAndFlush(SERVICE.sayHelloWithName(s));
    }
}

这个类正式 如他所说的 handler 或者是 adapter
其实 netty也看到了这个 地方的不妥
所以他们现在都叫 adapter了
你可以去看最新的 netty代码 之前 这部分 是 handler 现在都叫 adapter
这个地方就是 让 具体实现 接收网络传输数据
然后 自己 逻辑处理下
然后 通过网络传出 结果数据
这个地方 我们称为 adapter

ServiceClient.java

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executo
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值