- 浏览: 1704493 次
- 性别:
- 来自: 杭州699号
文章分类
最新评论
-
莫莫摸:
为什么不用dubbo
RCP数据传输模型回顾 -
大胡子爸爸:
String, Class 都实现了Serializable接 ...
RPC框架几行代码就够了 -
lss598018587:
谢谢大神分享,比起新手看复杂的dubbo框架还不如看大神的这一 ...
RPC框架几行代码就够了 -
15606915740:
你好,请问一下。<dubbo:consumer filt ...
Dubbo文档 -
joqk12345:
...
一些设计上的基本常识
转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/experience_1330/simple-rpc-framework.html
因为要给百技上实训课,让新同学们自行实现一个简易RPC框架,在准备PPT时,就想写个示例,发现原来一个RPC框架只要一个类,10来分钟就可以写完了,虽然简陋,也晒晒:
用起来也像模像样:
(1) 定义服务接口
(2) 实现服务
(3) 暴露服务
(4) 引用服务
正解
第一个问题,
是类似的用法
第二个问题.
服务器端有 Interface 和 Implement 类,
客户端只有 Interface .
原理,
服务器启动了一个线程监听 Socket 端口,
有Socket访问了, 反序列化解析出
调用哪个Service 哪个 方法, 以及传入的 参数,
再用Socket 写回去.
客户端 利用 Jdk 的Proxy 生成了一个代理类,
在创建 Proxy 时建立与服务器的Socket连接.
调用 Proxy 的方法时, 向服务器发送数据, 等待结果返回.
RpcFramework 第100行
http://pt.alibaba-inc.com/wp/experience_1330/simple-rpc-framework.html
因为要给百技上实训课,让新同学们自行实现一个简易RPC框架,在准备PPT时,就想写个示例,发现原来一个RPC框架只要一个类,10来分钟就可以写完了,虽然简陋,也晒晒:
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.framework; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.ServerSocket; import java.net.Socket; /** * RpcFramework * * @author william.liangf */ public class RpcFramework { /** * 暴露服务 * * @param service 服务实现 * @param port 服务端口 * @throws Exception */ public static void export(final Object service, int port) throws Exception { if (service == null) throw new IllegalArgumentException("service instance == null"); if (port <= 0 || port > 65535) throw new IllegalArgumentException("Invalid port " + port); System.out.println("Export service " + service.getClass().getName() + " on port " + port); ServerSocket server = new ServerSocket(port); for(;;) { try { final Socket socket = server.accept(); new Thread(new Runnable() { @Override public void run() { try { try { ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); try { String methodName = input.readUTF(); Class<?>[] parameterTypes = (Class<?>[])input.readObject(); Object[] arguments = (Object[])input.readObject(); ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); try { Method method = service.getClass().getMethod(methodName, parameterTypes); Object result = method.invoke(service, arguments); output.writeObject(result); } catch (Throwable t) { output.writeObject(t); } finally { output.close(); } } finally { input.close(); } } finally { socket.close(); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } catch (Exception e) { e.printStackTrace(); } } } /** * 引用服务 * * @param <T> 接口泛型 * @param interfaceClass 接口类型 * @param host 服务器主机名 * @param port 服务器端口 * @return 远程服务 * @throws Exception */ @SuppressWarnings("unchecked") public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception { if (interfaceClass == null) throw new IllegalArgumentException("Interface class == null"); if (! interfaceClass.isInterface()) throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!"); if (host == null || host.length() == 0) throw new IllegalArgumentException("Host == null!"); if (port <= 0 || port > 65535) throw new IllegalArgumentException("Invalid port " + port); System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port); return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable { Socket socket = new Socket(host, port); try { ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); try { output.writeUTF(method.getName()); output.writeObject(method.getParameterTypes()); output.writeObject(arguments); ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); try { Object result = input.readObject(); if (result instanceof Throwable) { throw (Throwable) result; } return result; } finally { input.close(); } } finally { output.close(); } } finally { socket.close(); } } }); } }
用起来也像模像样:
(1) 定义服务接口
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; /** * HelloService * * @author william.liangf */ public interface HelloService { String hello(String name); }
(2) 实现服务
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; /** * HelloServiceImpl * * @author william.liangf */ public class HelloServiceImpl implements HelloService { public String hello(String name) { return "Hello " + name; } }
(3) 暴露服务
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; import com.alibaba.study.rpc.framework.RpcFramework; /** * RpcProvider * * @author william.liangf */ public class RpcProvider { public static void main(String[] args) throws Exception { HelloService service = new HelloServiceImpl(); RpcFramework.export(service, 1234); } }
(4) 引用服务
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; import com.alibaba.study.rpc.framework.RpcFramework; /** * RpcConsumer * * @author william.liangf */ public class RpcConsumer { public static void main(String[] args) throws Exception { HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234); for (int i = 0; i < Integer.MAX_VALUE; i ++) { String hello = service.hello("World" + i); System.out.println(hello); Thread.sleep(1000); } } }
评论
13 楼
evans_he
2014-06-05
核心就是socket和动态代理
12 楼
mojianpo
2014-04-09
demo 写的很不错,支持支持支持
11 楼
leixbo
2014-02-28
jyjava 写道
说白了就是Socket编程,传输Object
正解
10 楼
id.alex
2013-11-13
有个地方说错了, LZ的 RPC 例子是短连接,在调用方法时才创建连接,
9 楼
id.alex
2013-11-13
yymn_love 写道
Hi,我在这个方面比较无知,我只是觉得RPC应该是远程调用的,就像webservice。我的疑问是:
1 RPC是否是类似webservice的服务?
(如果是或者类似的话看第二个,否则就不要看了)
2 服务器端有代码,是提供其他的客户端访问的。那么肯定客户端不是和服务器是同一套代码,客户端肯定不能使用服务器的类了。这个RPC是怎么工作的?
希望得到您的回复。谢谢!
1 RPC是否是类似webservice的服务?
(如果是或者类似的话看第二个,否则就不要看了)
2 服务器端有代码,是提供其他的客户端访问的。那么肯定客户端不是和服务器是同一套代码,客户端肯定不能使用服务器的类了。这个RPC是怎么工作的?
希望得到您的回复。谢谢!
第一个问题,
是类似的用法
第二个问题.
服务器端有 Interface 和 Implement 类,
客户端只有 Interface .
原理,
服务器启动了一个线程监听 Socket 端口,
有Socket访问了, 反序列化解析出
调用哪个Service 哪个 方法, 以及传入的 参数,
再用Socket 写回去.
客户端 利用 Jdk 的Proxy 生成了一个代理类,
在创建 Proxy 时建立与服务器的Socket连接.
调用 Proxy 的方法时, 向服务器发送数据, 等待结果返回.
8 楼
id.alex
2013-11-13
rxin2009 写道
能帮忙解释下
HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234); 中的service是怎么生成的吗(看了下代码,在实例HelloServiceImpl生成前是没有socket连接的)?
HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234); 中的service是怎么生成的吗(看了下代码,在实例HelloServiceImpl生成前是没有socket连接的)?
RpcFramework 第100行
return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {... ...})
7 楼
chenfuzhao
2013-08-18
有学习研究精神很好,但希望能把RPC的真正概念搞清楚!!!
6 楼
rxin2009
2013-05-27
能帮忙解释下
HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234); 中的service是怎么生成的吗(看了下代码,在实例HelloServiceImpl生成前是没有socket连接的)?
HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234); 中的service是怎么生成的吗(看了下代码,在实例HelloServiceImpl生成前是没有socket连接的)?
5 楼
guojch
2013-04-29
Very simple but very useful to understand the RPC working principle.Thanks for sharing!
4 楼
jyjava
2013-01-26
说白了就是Socket编程,传输Object
3 楼
melin
2011-12-19
this is great!!!
2 楼
yymn_love
2011-10-22
Hi,我在这个方面比较无知,我只是觉得RPC应该是远程调用的,就像webservice。我的疑问是:
1 RPC是否是类似webservice的服务?
(如果是或者类似的话看第二个,否则就不要看了)
2 服务器端有代码,是提供其他的客户端访问的。那么肯定客户端不是和服务器是同一套代码,客户端肯定不能使用服务器的类了。这个RPC是怎么工作的?
希望得到您的回复。谢谢!
1 RPC是否是类似webservice的服务?
(如果是或者类似的话看第二个,否则就不要看了)
2 服务器端有代码,是提供其他的客户端访问的。那么肯定客户端不是和服务器是同一套代码,客户端肯定不能使用服务器的类了。这个RPC是怎么工作的?
希望得到您的回复。谢谢!
1 楼
liyebing
2011-09-16
好!学习了。。希望看到您更多更精彩的分享
发表评论
-
能力成长模型
2012-05-09 00:28 23013最近看了温伯格1986年出版的《技术领导之路》, 很老的书,讲 ... -
以HTTL为例讲讲模块分包&领域模型&扩展框架
2011-10-09 20:08 16814注:该博客内容已加入 ... -
使用Map参数的Webx3扩展
2011-08-28 02:10 5934因Webx3是开源的,所以把这个简单的Webx3扩展发在博客上 ... -
Netty内存泄露
2011-08-02 20:09 24979转于自己在公司的Blog: ... -
Grizzly和Netty以及Mina简单性能对比
2011-07-17 02:48 29766转于自己在公司的Blog: http://pt.alibaba ... -
魔鬼在细节中
2011-05-24 14:50 32255转于自己在公司的Blog: ... -
Dubbo扩展点重构
2011-05-12 22:09 38912转于自己在公司的Blog: http://pt.alibaba ... -
配置设计
2011-03-09 23:41 23610转于自己在公司的Blog: ... -
[转]HTML5设计原理
2011-03-09 22:57 7839Jeremy Keith在 Fronteers 2010 ... -
Hessian序列化不设SerializerFactory性能问题
2010-12-27 11:38 6490转于自己在公司的Blog: http://pt.alibaba ... -
动态代理方案性能对比
2010-11-17 21:38 46249转于自己在公司的Blog: http://pt.alibaba ... -
防痴呆设计
2010-11-05 18:58 17703转于自己在公司的Blog: ... -
负载均衡扩展接口重构
2010-11-05 18:53 8768转于自己在公司的Blog: ... -
分布式服务框架常被质疑的价值
2010-11-05 18:52 5743转于自己在公司的Blog: http://pt.alibaba ... -
Hessian3.2.1在序列化32.5k字符串时的问题
2010-11-05 18:49 7288转于自己在公司的Blog: http://pt.alibaba ... -
一些设计上的基本常识
2010-07-05 19:28 27803转于自己在公司的Blog: ... -
谈谈扩充式扩展与增量式扩展
2010-06-12 19:46 19427转于自己在公司的Blog: http://pt.alibaba ... -
Scaling Architecture
2010-02-25 10:31 4129Scaling Second Life: http://p ... -
EBay SOA
2010-02-23 18:23 4811EBay SOA PPT -
服务化基础设施
2009-11-15 23:11 6290服务化,也可以叫SOA, ...
相关推荐
RpcFramework类的Java代码实现了RPC框架的核心逻辑。代码中使用了Java反射机制和代理模式来实现服务暴露和服务调用。代码还使用了ServerSocket和Socket对象来实现服务端口的监听和服务请求的处理。 知识点8:RPC...
rest_rpc c++11, high performance, cross platform, ...rest_rpc为用户提供了非常简单易用的接口,几行代码就可以实现rpc通信了,来看第一个例子 一个加法的rpc服务 //服务端注册加法rpc服务 struct dummy{ int add(r
RPC框架使得应用程序能够调用远程服务器上的函数或方法,就像它们是本地调用一样,极大地简化了分布式系统开发。HprosePHP在提供高效性能的同时,还具有轻量级、跨平台、易用性强的特点。 1. **Hprose工作原理**: ...
3. **易于使用**:Kryonet的API设计简洁明了,只需几行代码就可以建立服务器和客户端,并进行数据交换。 4. **高效性能**:由于Kryo的高性能特性,Kryonet在网络通信中表现出色,特别是在大数据量或者高并发场景下...
分布式(多进程)架构,几行代码实现一个功能服务器的搭建 多线程设计,注解方式配置,轻松管理所有消息流 强大的RPC功能,调用远程RPC近似于调用本地函数,无需手工定义内部协议 支持插件功能,轻松实现功能插件 框架...
通过几行代码,一个应用就可以生成一个高度可扩展的逐出器来高效地管理持久对象。 ICE 框架的优势之一是支持多语言分布式互联。服务端可以采用 C++/Java/Python/C# 等实现,客户端可以采用 C++/Java/Python/C#/VB/...
它简化了日志配置,只需几行代码就可以启用基本的日志功能。与`org.slf4j.api_1.6.4.jar`一起使用,可以为Thrift应用程序提供基础的日志支持。 综上所述,这个“thriftDependencyJar”压缩包为使用Java进行Thrift...
编写和使用RMI服务和客户端程序相对简单,服务程序只需几行代码就可以声明为远程服务,其余部分与普通Java对象相似。RMI还能够与现有系统集成,如通过Java Native Interface (JNI) 与非Java服务器通信,或者利用JDBC...
在Java应用中,只需几行代码,就可以实现Groovy脚本的编译和执行: ```java GroovyShell shell = new GroovyShell(); Script script = shell.parse(new File("path/to/your/groovy/script.groovy")); script.run();...
`gradio`的使用非常简单,只需要几行代码即可创建一个交互式UI。例如,如果你有一个预测温度的模型,可以这样使用: ```python import gradio as gr def predict_temperature(temp): # 这里是你的模型预测代码 ...
例如,只需几行代码就能创建一个简单的服务器或客户端。 9. **社区活跃与文档完善**:Netty拥有活跃的社区,不断更新版本并修复问题。同时,官方提供了详尽的文档和丰富的示例,帮助开发者快速上手和解决问题。 10...
Hprose,全称“High Performance Remote Object Service Engine”,是一种轻量级、跨语言、跨平台的RPC(Remote Procedure Call)框架,适用于移动端和服务器端的分布式应用开发。在移动端,尤其是在Android和iOS...