文档章节

netty实战--手写rpc框架

xpbob
 xpbob
发布于 2018/06/27 13:43
字数 1151
阅读 8.3K
收藏 73

「深度学习福利」大神带你进阶工程师,立即查看>>>

在看此篇内容时需要浏览下面内容
从零开始学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

xpbob

粉丝 99
博文 114
码字总数 91206
作品 0
高级程序员
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
【opencv】图形的绘制

1.矩形图像的绘制: 原函数:void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8,int shift=0) img就是需要绘制的图像 pt1 and pt......

其实我是兔子
2014/10/08
1.2K
1
TDD的测试框架--Machine.Specification

Machine.Specification 是一个 TDD 测试驱动开发的测试框架,简化了测试,无需关心语言本身特性。 Machine.Specifications 带来的好处是不需要在代码里有注释,但同时阅读代码的人可以一目了...

匿名
2013/01/22
1.2K
0
Go-node

Go-node 是一个用 Go 语言实现的 Erlang/OTP node 已支持的功能: Publish listen port via EPMD Handle incoming connection from other node using Erlang Distribution Protocol Spawn E......

匿名
2013/01/25
1.5K
1
mvc框架--Razor

Razor 是一个轻巧而优雅的servlet mvc框架 # 又一个轮子? no,写就她是为了证实我个人的某些想法,并在这个过程中练练手,这两种冲动碰撞在一起,自然而然地产生了Razor # Razor的现在和未来...

dtubest
2013/01/25
3.2K
0

没有更多内容

加载失败,请刷新页面

加载更多

旋转子段 (思维stl)

题目: 大概意思就是给你一个序列,你可以选择一段区间使它左右翻折一遍,然后呢,从1到n找一遍,看a[i]==i的数最多是多少。 其实刚才我已经把暴力思路说出来了,枚举每一个区间长度,枚举每...

osc_npw5uz1o
17分钟前
0
0
回忆录

前言? 果然退役的蒟蒻不仅没有留下有价值的学习资料,甚至连能看的颓废资料都没有。 其实这一年时间里一直想写一篇像样的回忆录。 想把高三也写进去?现在高三结束了。没时间写?现在有了。...

osc_z9ptnny9
19分钟前
9
0
mysql启动失败,unit not found

1 mysql启动 Failed to start mysqld.service: Unit not found. 2 查询/etc/init.d/下是否存在mysqld ll /etc/init.d/ | grep mysqld 发现该目录下并没有mysqld的文件,若存在,请备份一下 ...

osc_um3gbrdm
21分钟前
5
0
域名解析到底应该肿么破——详解域名解析类型

原文地址:https://www.wjcms.net/archives/%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90%E5%88%B0%E5%BA%95%E5%BA%94%E8%AF%A5%E8%82%BF%E4%B9%88%E7%A0%B4%E8%AF%A6%E8%A7%A3%E5%9F%9F%E5%90%8D%......

神兵小将
21分钟前
0
0
Java并发编程:volatile关键字解析

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

osc_3r4js8qy
22分钟前
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部