【重复造轮子系列】手撸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请求呢?这一部分我们放到下一篇中完成

相关推荐
Hacker_Nightrain26 分钟前
网络安全CTF比赛规则
网络·安全·web安全
网络安全指导员1 小时前
恶意PDF文档分析记录
网络·安全·web安全·pdf
问道飞鱼1 小时前
【微服务知识】开源RPC框架Dubbo入门介绍
微服务·rpc·开源·dubbo
co0t2 小时前
计算机网络(11)和流量控制补充
服务器·网络·计算机网络
极地星光2 小时前
JSON-RPC-CXX深度解析:C++中的远程调用利器
c++·rpc·json
白总Server2 小时前
JVM解说
网络·jvm·物联网·安全·web安全·架构·数据库架构
清尘沐歌2 小时前
有什么好用的 WebSocket 测试工具吗?
websocket·网络协议·测试工具
清尘沐歌2 小时前
有什么好用的 WebSocket 调试工具吗?
网络·websocket·网络协议
Li_0304062 小时前
Java第十四天(实训学习整理资料(十三)Java网络编程)
java·网络·笔记·学习·计算机网络
Tony聊跨境3 小时前
什么是 ISP:了解互联网服务提供商的作用
网络·人工智能·isp