文档章节

netty实战--手写rpc框架

xpbob
 xpbob
发布于 06/27 13:43
字数 1151
阅读 2339
收藏 73
点赞 2
评论 0

在看此篇内容时需要浏览下面内容
从零开始学netty——如何面对粘包和拆包
从零开始学netty——自定义协议

rpc简介

rpc大家大概都听说过,远程过程调用。简单来说,就是我的一个操作是远程操作的给的结果,举个例子,考试作弊,你把考题发出去了,你同学帮你做好把答案传输给你,然后你就把答案写上,那么在判卷老师眼里,你回答的还不错,但是,其实你是做了远程过程调用的。

rpc的好处也在上面的例子中体现了,当自身能力不行的时候,可以依靠强大的远程力量来做到结果。如果自己有能力回答卷子,那就没必要走rpc了。换句话说就是

自身执行的消耗 > 别人执行的消耗+传输的消耗

借助netty手写rpc

rpc的要点

  1. 消息传给远程
  2. 看起来和本地调用差不多
  3. 服务注册

消息传给远程

这里就是建立连接的过程,代码都比较套路,这里不列举。最后会贴出代码地址的,这里先通思路。序列化没有选择pb,而是选择了protostuff,这里得解释一下原因。

rpc传递的是什么

既然是方法调用,一个方法的唯一标志是类名,方法名,参数类型。你还得把方法参数也传递走。

	private String id;
	private String className;
	private String methodName;
	private Object[] args;
	private Class<?>[] parameterTypes; 

这里还有传输一个id,是为了做标志,例如我发了题目出去,最希望的就是回到我的是第4题答案是什么,而不是xxxx问题的答案是什么。id就是唯一表示一次问题的。

大家也发现了里面有Object类型和Class类型,这些类型是pb里没有的,所以此时pb就不适合作为序列化的选择了。

收到的就比较简单了,就是唯一的id以及结果

	private String id;
	private Object result;

netty异步如何准确的返回结果

netty的返回的结果是在handler里,而不是我们的业务线程,如何传递就成为了一个问题。上面的唯一的id就是解决的关键点,我选择了SynchronousQueue来作为传递的媒介,如果不了解这个类的可以先查看一下,他主要就是作为传递媒介的,有点类似阻塞队列。

	private static ConcurrentHashMap<String, SynchronousQueue> mapInfo = new ConcurrentHashMap<>();

使用一个map来保存id,和传递媒介,业务线程只要拿着SynchronousQueue就好,等消息收到,就把结果放入SynchronousQueue中,业务线程就可以拿到结果了,与此同时,要把id从map里移除。

看起来和本地调用差不多

想做到方法调用,还扩充了部分功能,这个是装饰者或者代理模式的效果。因为这里只做一层包装,所以选择代理模式,如果是不断的扩充功能的情况,装饰者会更好一些。因为我们是java编写,动态代理就是一个不错的选择。

	public static <T> T getProxy(final Class<T> clazz) {
		return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				RpcRequest request = new RpcRequest();
				request.setMethodName(method.getName());
				request.setClassName(clazz.getName());
				Class<?>[] parameterTypes = method.getParameterTypes();
				request.setArgs(args);
				String id = UUID.randomUUID().toString();
				request.setId(id);
				SynchronousQueue queue = new SynchronousQueue();
				ResultInfo.putSunchronousQuee(id, queue);
				Client.write(request);
				return queue.take();
			}
		});
	}

服务注册

这里使用了比较简单的方法,就是手动把服务加入。

	public static void put(Object value) {
		Class<?>[] interfaces = value.getClass().getInterfaces();
		for(Class<?> interfaceTmp:interfaces){
			services.put(interfaceTmp.getName(), value);
		}
		
	}

这里选择把接口作为key,对象作为value。如果结合spring就可以更简单一些,通过注解来做,不用自己手动写了。

rpc实现总结

这里实现的rpc的基础功能,就是远程调用。技术点就在动态代理和消息通讯上。动态代理的目的是为了让rpc在调用的时候更简单,通讯部分才是rpc的主要点,通过反射等方式,让远程的机器进行运算,并且返回结果。所有的代码如下:https://github.com/xpbob/lightrpc

© 著作权归作者所有

共有 人打赏支持
xpbob
粉丝 86
博文 73
码字总数 58759
作品 0
有经验JAVA程序员如何提升自己?

具有一到五年开发经验 需要学习内容很多 JVM/分布式/高并发/性能优化/Spring MVC/Spring Boot/Spring Cloud/MyBatis/Netty源码分析等等等 01、透彻理解Tomcat原理手写动静态资源的实现 02、分...

阿阳啊啊
2017/11/29
0
0
三流程序员与一流程序员之间的区别,看看你是属于哪一类?

源码系列 手写spring mvc框架 基于Spring JDBC手写ORM框架 实现自己的MyBatis Spring AOP实战之源码分析 Spring IOC高级特性应用分析 ORM框架底层实现原理剖析 手写Spring MVC框架实现 手把手...

茶轴的青春
04/17
0
0
RPC如何提高响应速度

手写了一个rpc 1.zookeeper注册发现服务; 2.common-pool管理netty-client链接; 3.netty nio异步通讯,通过notify实现同步调用 问题来了,上述RPC本地调用耗时400ms/100次,对比另一款rpc耗时...

许雪里
2015/11/06
191
0
Java开发者不会这些永远都只能是三流程序员,细数一下你是不是?

源码系列 手写spring mvc框架 基于Spring JDBC手写ORM框架 实现自己的MyBatis Spring AOP实战之源码分析 Spring IOC高级特性应用分析 ORM框架底层实现原理剖析 手写Spring MVC框架实现 手把手...

美的让人心动
04/16
0
0
如何使用Netty开发实现高性能的RPC服务器

RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议。说的再直白一点,就是客户端在不必知道调用细节的...

vshcxl
2017/10/20
0
0
Java架构师如何冲击年薪40w

有人回答说这只能是大企业或者互联网企业工程师才能拿到。也许是的,小公司或者非互联网企业拿两万的不太可能是码农了,应该已经转管理。还有区域问题,这个不在我的考虑范围内,因为除了北上...

阿阳啊啊
2017/10/16
0
0
百度、阿里、腾讯、京东、大型互联网分布式架构必备技能

分布式架构 迎接高并发大数据的挑战,从深度到广度完善知识体系,成为下一个互联网高薪人才。 理论结合实战,透彻理解分布式架构及其解决方案。 面向人群 1、工作1-5年需要突破瓶颈; 2、传统...

Java高级架构
2017/12/21
0
0
消息中间件—RocketMQ的RPC通信(二)

文章摘要:如何设计RPC通信层模型是任何一款性能强劲的MQ所要重点考虑的问题 在(一)篇中主要介绍了RocketMQ的协议格式,消息编解码,通信方式(同步/异步/单向)、消息发送/接收以及异步回调...

癫狂侠
07/01
0
0
Dubbo 升级扩展 --Dubbo-G

Dubbo-G 详细介绍 Dubbo是一个被国内很多互联网公司广泛使用的开源分布式服务框架,即使从国际视野来看应该也是一个非常全面的SOA基础框架。作为一个重要的技术研究课题,在联想电商我们根据...

技术专家
2017/05/26
5.5K
23
一个基于Netty的RPC框架

利用netty写了一个简单的RPC框架,纯粹是为了理解RPC框架。 使用protostuff 1.07 序列化,以netty 3.2.1 网络框架。 下载地址:https://github.com/stefzhlg/snrpc ##How to use e.g. 1,ser...

stefanzhlg
2014/12/05
0
2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

shell中的函数、shell中的数组、告警系统需求分析

shell中的函数 格式: 格式: function f_name() { command } 函数必须要放在最前面 示例1(用来打印参数) 示例2(用于定义加法) 示例3(用于显示IP) shell中的数组 shell中的数组1 定义数...

Zhouliang6
今天
2
0
用 Scikit-Learn 和 Pandas 学习线性回归

      对于想深入了解线性回归的童鞋,这里给出一个完整的例子,详细学完这个例子,对用scikit-learn来运行线性回归,评估模型不会有什么问题了。 1. 获取数据,定义问题     没有...

wangxuwei
今天
1
0
MAC安装MAVEN

一:下载maven压缩包(Zip或tar可选),解压压缩包 二:打开终端输入:vim ~/.bash_profile(如果找不到该文件新建一个:touch ./bash_profile) 三:输入i 四:输入maven环境变量配置 MAVEN_HO...

WALK_MAN
今天
0
0
33.iptables备份与恢复 firewalld的9个zone以及操作 service的操作

10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21 firewalld关于zone的操作 10.22 firewalld关于service的操作 10.19 iptables规则备份和恢复: ~1. 保存和备份iptables规则 ~2...

王鑫linux
今天
2
0
大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
今天
1
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
今天
2
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
今天
1
0
Java IO类库之BufferedInputStream

一、BufferedInputStream介绍 /** * A <code>BufferedInputStream</code> adds * functionality to another input stream-namely, * the ability to buffer the input and to * sup......

老韭菜
今天
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
1
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部