基于Netty和Zookeeper实现RPC框架

前言:所谓RPC是一种通过网络从远程计算机请求服务,而不必了解底层技术的协议,客户端不在乎传输层使用TCP或者UDP,不在意IO模型选择select还是epoll。现在典型的RPC框架有:Thrift,Dubbo等。接下来将参考一些dubbo的东西,展示如何基于Netty和zookeeper开发实现一个高性能RPC框架,同时结合问题分析解决方法

一,定义RPC请求和响应消息结构。
1,首先是请求类。必须包含的是:(1)类名(2)方法名(3)参数(4)参数结构。然后为了其他的一些考虑,我们可以加入其他的特性。例如:本次请求ID,服务的版本号等。实现如下:

public class RpcRequest {

    private String requestId;
    private String interfaceName;
    private String serviceVersion;
    private String methodName;
    private Class<?>[] parameterTypes;
    private Object[] parameters;

    //省略get和set
}

2,响应类。包括(1)请求ID(2)异常信息(3)执行结果

public class RpcResponse {

    private String requestId;
    private Exception exception;
    private Object result;

    public boolean hasException() {
        return exception != null;
    }

    //省略set和get
}

二,定义消息协议和消息encode和decode
1,消息协议:
一个消息报文分为两部分:(4bytes)消息长度+消息主体。

2,TCP半包和粘包问题
发生的原因:
(1)应用程序写入的字节大小大于套接字发送的缓冲区大小
(2)进行MSS大小的TCP分段
(3)以太网的payload大于MTU进行IP分片
(4)接收端读取速度小于接受速度
Netty内置了LengthFieldBasedFrameDecoder处理读半包问题,但是为了了解如何处理,选择了使用ByteToMessageDecoder。

3,Decoder
因为选择ByteToMessageDecoder,所以会出现读半包问题,那么我们可以这样来解决:由于我们定义了4个byte来存储消息长度,所以如果可读byte小于4和消息主体长度跟消息长度不吻合,那么就先不读,以为这是个半包,可以等到下次再来读取。

public class RpcDecoder extends ByteToMessageDecoder {
   

    private Class<?> genericClass;

    public RpcDecoder(Class<?> genericClass) {
        this.genericClass = genericClass;
    }

    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes() < 4) {
            return;
        }
        in.markReaderIndex();
        int dataLength = in.readInt();
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        byte[]
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值