纯手写实现一个高可用的RPC
在实际后台服务开发中,比如订单服务(开发者A负责)需要调用商品服务(开发者B负责),那么开发者B会和A约定调用API,以接口的形式提供给A。通常都是B把API上传到Maven私服,然后B开始写API的实现,A只需要引入API依赖进行开发即可。
订单服务调用商品服务
上图简单的描述了RPC在实际场景中的应用,我们在开发中当然是利用现有的RPC框架来快速实现业务需求,比如百度开源了baidu-rpc,阿里的Dubbo早已声名在外,腾讯自己玩TAF。本篇博客将实现一个迷你版的RPC,探索下RPC底层实现的奥秘!
商品服务工程
注意,我将商品服务的API以及实现分为Maven的2个模块来开发。这里,我们想给定一个商品ID,查询得到商品对象信息。
商品对象商品API
Product
要注意的是,Product是可以被序列化的,Why?
很显然,订单系统调用商品系统的时候,需要商品系统返回一个商品,必然涉及到发生网络传输,这就涉及对象的序列化和反序列化了。
商品查询API接口商品查询API
订单系统调用商品服务订单服务调用商品服务
在订单系统工程中需要引入商品服务API依赖。
在上图代码中,最重要的就是rpc方法了!
rpc实现方法rpc
第一,我们看到了Proxy.newProxyInstance,很显然在进行动态代理。也即是说,在订单服务调用商品服务的代码中,我们先是通过动态代理返回一个代理的IProductService类型对象,这意味着当代理对象调用queryById方法的时候,会自动调用invoke方法!
第二,我们看看invoke到底做了些什么?
它本质上就是进行Socket通信,那么它需要传递什么信息给到商品服务呢?
我们知道订单系统就是想调用商品服务的某个类的某个方法,然后把这个方法的返回结果传输给订单系统!
想一想,如何调用某个类的某个方法呢?
只要我们能确定这个类的全限定类名、确定方法名、确定方法的参数类型,给定方法需要的具体参数,通过反射就能实现。
商品服务调用后得到的结果,我们序列化写入Socket流中,在订单系统中反序列化得到对象即可。
第三,这里需要思考一个问题:在订单系统中我们只知道商品服务的API,并不知道这背后的API到底是如何实现的,所以我们需要有一个映射,就是商品服务的API到商品服务的实现的一个映射关系,其实这就是所谓的服务的注册!
商品API的具体实现商品服务
商品服务API实现
商品服务商品服务
从这里,可以清晰的看到,商品服务读取了订单系统调用商品系统时发送的数据,利用反射机制,进行方法调用,并把调用结果写入Socket输出流。
#运行结果
运行结果
启动商品服务后,通过订单系统发起对商品服务的调用。
以前总认为RPC是遥不可及的,感觉是个很神奇的东西,实际上它的底层实现不就是这样的么~
晚安!
原文发布时间为:2018-09-26
本文作者:java进阶架构师
本文来自云栖社区合作伙伴“java进阶架构师”,了解相关信息可以关注“java进阶架构师”。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
目标检测架构5年演进全盘点:从R-CNN到RFBNet
目标检测是计算机视觉领域的基本且重要的问题之一,而「一般目标检测」则更注重检测种类广泛的自然事物类别。近日,中国国防科技大学、芬兰奥卢大学、澳大利亚悉尼大学、香港中文大学、加拿大滑铁卢大学的研究者在 arXiv 发布了一篇综述论文,对用于一般目标检测的深度学习技术进行了全面系统的总结。机器之心选取了其中部分内容进行介绍,更详细的内容请参阅原论文。 此外,来自首尔国立大学的 Lee hoseong 在近期开源了「deep learning object detection」GitHub 项目,正是参考该论文开发的。该项目集合了从 2013 年 11 月提出的 R-CNN 至在近期举办的 ECCV2018 上发表的 RFBNet 等四十多篇关于目标检测的论文,相当全面。这些论文很多都曾发表在机器学习或人工智能顶会上,如 ICLR、NIPS、CVPR、ICCV、ECCV 等。正如图中红色字体标示的那样,其中也包含了很多代表性的成果,如从 R-CNN 到 Mask R-CNN 的 R-CNN 系列、YOLO 系列、RPN、SSD、FPN 以及 RetinaNet 等。无论对刚入门的机器学习新手...
- 下一篇
老司机也该掌握的MySQL优化指南
当MySQL单表记录数过大时,增删改查性能都会急剧下降,所以我们本文会提供一些优化参考,大家可以参考以下步骤来优化:一、单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度。一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的,而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量。字段 尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED; VARCHAR的长度只分配真正需要的空间; 使用枚举或整数代替字符串类型; 尽量使用TIMESTAMP而非DATETIME; 单表不要有太多字段,建议在20以内; 避免使用NULL字段,很难查询优化且占用额外索引空间; 用整型来存IP。 索引 索引并不是越多越好,要根据查询有针对性的创建,考虑在WHERE和ORDER BY命令上涉及的列建立索引,可根据EXPLAIN来查看是否用了索引还是全表扫描; 应尽量避免在WHERE子句中对字段进行NULL值判断,否则将导致引擎放弃使用...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- 设置Eclipse缩进为4个空格,增强代码规范