【重复造轮子系列】手撸RPC(二)

一、前言

在上一篇文章中我们模仿着Dubbo初步搭建了一个RPC框架,虽然目前什么都没有实现,但是万丈高楼平地起,接下来我们会一步步完善我们的框架。

二、一次RPC的流程是什么样的

在正式编写代码之前我们需要了解的是一次完整的RPC调用是怎么样的。这里我们以ZK为注册中心,UserService作为服务提供方,OrderService做为消费方为例来聊一聊一次完整的RPC调用。

  1. 首先在服务启动的初期服务提供方(UserService)需要将提供的接口注册到ZK上(假设该接口为getUserInfo(Long userId))
  2. 消费方(OrderService)想要获取用户信息所以需要调用UserService。那么就至少需要知道UserSerivce的地址信息(IP+端口),所以OrderService会到ZK中查找对应的信息。
  3. 拿到信息后就要调用UserService对应的方法,在UserService没有提供Http接口的前提下我们怎么调用呢?显然就要用到RPC调用。OrderService通过网络发送对应的请求,UserService收到请求后返回对应的响应,这就是一个简单的RPC调用过程。接下来我们要讨论的是如这个网络请求是如何发送的。

三、在RPC调用中怎么发送网络请求

Java天生是支持网络编程的,想要发送一个网络请求也是比较容易的,下面就是几个方案。

1、最容易想到的就是采用Socket实现BIO模型的网络通信,每次调用之前服务端和消费端都要建立一个Socket,然后通信结束后释放链接,这么做的优缺点都非常明显,优点:模型简单,代码易懂。缺点:效率很低,浪费资源。一个线程处理一个链接。

2、NIO模型,Jdk1.4之后提供了NIO相关API(这里不细谈NIO)。这个方案弥补了方案1缺点,但是NIO的代码相对晦涩难懂。

3、基于Netty实现网络通信,Netty是一个基于事件驱动的NIO框架,提供了相对简单的API屏蔽了Jdk自带NIO晦涩难懂的概念。

综上我们采用Netty作为我们RPC框架的网络模块框架。既然选中了Netty作为网络框架,那么整个网络发送的流程是怎么样的?

  1. 首先我们要知道,作为网络通信一定是有一定的规则的,这个规则我们称之为"通信协议"。所谓的协议,可以认为是一种约定,即服务端和客户端定义好数据是如何解析的。由于在网络传输的过程都是比特流(01010101),所以双方需要约定好如何解读这些数据。
  2. 我们发送的请求在网络中传输的过程中是比特流,所以我们需要将参数进行序列化操作。

这两个是必须的,当然我们也可以在此基础上做一些额外的操作,例如记录日志,压缩等等。下面我们以图的形式来展示。

四、来一次简单的网络通信

1、服务端代码

复制代码
public class ServerTest {

    public static void main(String[] args) throws InterruptedException {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //boss 只负责接收请求
        final NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //worker 负责具体业务
        final NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        final ChannelFuture channelFuture = serverBootstrap.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(final SocketChannel channel) throws Exception {
                    //服务器初始化
                    channel.writeAndFlush(Unpooled.copiedBuffer("Hello I am Server".getBytes(StandardCharsets.UTF_8)));
                }
            }).bind(8888);
        channelFuture.sync();
        channelFuture.channel().closeFuture().sync();
    }
}

2、客户端代码

复制代码
public class ConsumerTest {

    public static void main(String[] args) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        EventLoopGroup group = new NioEventLoopGroup();
        bootstrap.group(group).remoteAddress("127.0.0.1",8888).channel(NioSocketChannel.class)
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(final SocketChannel socketChannel) throws Exception {
                    System.out.println("客户端初始化handler");
                    socketChannel.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
                        @Override
                        protected void channelRead0(final ChannelHandlerContext channelHandlerContext,
                            final ByteBuf byteBuf)
                            throws Exception {
                            System.out.println("收到服务端的消息:"+byteBuf.toString(Charset.defaultCharset()));
                        }
                    });
                }
            });
        final ChannelFuture connect = bootstrap.connect();
        final ChannelFuture channelFuture = connect.sync();
        channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("hello world".getBytes(StandardCharsets.UTF_8)));
        //阻塞,等待接收关闭消息
        channelFuture.channel().closeFuture().sync();
    }
}

3、结果

至此我们已经完成了一次最简单的客户端和服务端的通信,那么接下来要考虑的是如何完成我们的RPC请求呢?这一部分我们放到下一篇中完成

相关推荐
andxe5 小时前
安科士 AndXe 技术博客:400G QSFP112 SR4 光模块|AI 算力与超算短距互联最优方案
网络·人工智能·光模块·光通信
shiyi.十一6 小时前
第2章:应用层 — 知识要点与架构
网络·计算机网络·架构
DFT计算杂谈7 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
水境传感 李兆栋7 小时前
GNSS 位移监测站 :毫米级感知,筑牢安全监测防线
网络
中微极客9 小时前
2026主流AI Agent框架技术选型与性能对比
运维·网络·人工智能
猿的天空13 小时前
机器人双手迎来全栈训练系统:灵初智能EgoSteer让灵巧手无所不能
网络·人工智能·计算机·ai·程序员·机器人·编程
Xzaveir_77713 小时前
OPPO、vivo、荣耀号码认证:多终端拨测矩阵与异常复现
大数据·网络·科技·矩阵·产品经理·ai-native
wuqingshun31415913 小时前
从网络角度来看,用户从输入网址到网页显示,期间发生了什么?
网络
牛马工作号13 小时前
Zigbee 专业详解:从协议到排障
网络·物联网·安全
牛马工作号13 小时前
Wi‑Fi 完全指南:从 802.11 协议到 Wi‑Fi 7、AC+AP 与 Mesh 工程组网
网络·网络协议·智能路由器