菜鸟的进阶--手写一个小型dubbo框架

本文详细介绍了RPC调用流程,包括使用Protobuf和JSON进行编解码,对比了两种序列化方式的性能。接着讨论了负载均衡策略,如加权轮询和一致性哈希,并给出了具体的实现代码。此外,还阐述了基本的心跳机制用于检测服务的可用性。最后,文章提到了压力测试的结果以及简单的服务管理界面的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.rpc调用流程


2.组件


1.Redis注册中心


3.编解码/序列化


在本例的Netty通信中,由于每次调用rpc服务都要发送同一个类对象invoker,所以可以使用Protobuf。但是在接受方法调用结果的时候就不行了,因为我们无法提前确定对方方法返回结果的类型,所以在发送result的时候需要使用序列化将object 变成 byte [] ;接收 result的时候需要使用反序列化将 byte [] 变成 object

invoker

publicclassInvokerimplementsSerializable {
​
    privateStringinterfaceName;
    privateStringmethodName;
    privateClass[] paramsType;
    privateObject[] params;
}

序列化


序列化/反序列化可以使用数据流完成,也就是jdk的那一套序列化 / 反序列化操作。

publicstaticObjectByteToObject(byte[] bytes) {
    Objectobj=null;
    try {
        // bytearray to object
        ByteArrayInputStreambi=newByteArrayInputStream(bytes);
        ObjectInputStreamoi=newObjectInputStream(bi);
​
        obj=oi.readObject();
        bi.close();
        oi.close();
    } catch (Exceptione) {
        System.out.println("translation"+e.getMessage());
        e.printStackTrace();
    }
    returnobj;
}
​
publicstaticbyte[] ObjectToByte(Objectobj) {
    byte[] bytes=null;
    try {
        // object to bytearray
        ByteArrayOutputStreambo=newByteArrayOutputStream();
        ObjectOutputStreamoo=newObjectOutputStream(bo);
        oo.writeObject(obj);
​
        bytes=bo.toByteArray();
​
        bo.close();
        oo.close();
    } catch (Exceptione) {
        System.out.println("translation"+e.getMessage());
        e.printStackTrace();
    }
​
    returnbytes;
}

但是这一套操作的性能比较堪忧,我又测试了一遍json序列化反序列化的性能.

json的性能明显要好于jdk的性能。

    private static void testJson() throwsIOException {
        //10w次 序列化 / 反序列化 耗时238
        Personperson=newPerson();
        person.setName("tom");
        person.setAge(17);
        ObjectMapperobjectMapper=newObjectMapper();
        longstart=System.currentTimeMillis();
        for (inti=0; i<100000; i++) {
            person.setAge(i);
            Strings=objectMapper.writeValueAsString(person);
            objectMapper.readValue(s, Person.class);
        }
        longend=System.currentTimeMillis();
        System.out.println("json / 耗时: "+(end-start));
​
    }
​
    private static void testJdk(){
        //10w次 序列化/反序列化耗时: 599ms
        Personperson=newPerson();
        person.setName("tom");
        person.setAge(17);
        longstart=System.currentTimeMillis();
​
        for (inti=0; i<100000; i++) {
            person.setAge(i+1);
            byte[] bys=BytesUtils.ObjectToByte(person);
            Objectp=BytesUtils.ByteToObject(bys);
        }
        longend=System.currentTimeMillis();
        System.out.println("jdk / 耗时: "+(end-start));
    }

  • 最终敲定,编解码采用protobuf+json的方式

  • 当然我还提供了Jdk的方式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值