Avro RPC的两种实现方法:静态实现和动态实现
使用Avro可实现如下几种方式的轻量级RPC, 每种方式都可用动态编码和静态编码来实现:
HTTP:
HttpServer
HttpTransceiver
UDP
DatagramServer
DatagramTransceiver
Netty
NettyServer
NettyTransceiver
TCP
SocketServer
SocketTransceiver
安全TCP
SaslSocketServer
SaslSocketTransceiver
1. 添加maven依赖包
<dependency><groupId>org.apache.avro</groupId><artifactId>avro</artifactId><version>1.8.1</version></dependency><dependency><groupId>org.apache.avro</groupId><artifactId>avro-ipc</artifactId><version>1.8.1</version></dependency>
2. 静态方法实现Netty RPC
2.1 下载 avro-tools-1.8.1.jar
2.2 编译mail.avpr, 生成java代码Message.java 和 Mail.java
mail.avpr:
{"namespace": "org.hdp.practice.rpc.netty","protocol": "Mail","types": [{"name": "Message", "type": "record","fields": [{"name": "to", "type": "string"},{"name": "from", "type": "string"},{"name": "body", "type": "string"}]}],"messages": {"send": {"request": [{"name": "message", "type": "Message"}],"response": "string"}} }
运行命令: java -jar avro-tools-1.8.1.jar compile protocol mail.avpr .
2.3 java代码
public class MyServer {public static class MailImpl implements Mail{@Overridepublic Utf8 send(Message message) {System.out.println("Sending message");return new Utf8("Sending message to " + message.getTo().toString()+ " from " + message.getFrom().toString()+ " with body " + message.getBody().toString());}}public static void main(String[] args) throws IOException {System.out.println("Starting server");NettyServer server = new NettyServer(new SpecificResponder(Mail.class, new MailImpl()), new InetSocketAddress(65111));System.out.println("Server started");}
}public class MyClient {public static void main(String[] args) throws IOException {if (args.length != 3) {System.out.println("Usage: <to> <from> <body>");System.exit(1);}NettyTransceiver client = new NettyTransceiver(new InetSocketAddress(65111));Mail proxy = (Mail) SpecificRequestor.getClient(Mail.class, client);System.out.println("Client built, got proxy");Message message = new Message();message.setTo(new Utf8(args[0]));message.setFrom(new Utf8(args[1]));message.setBody(new Utf8(args[2]));System.out.println("Calling proxy.send with message: " + message.toString());System.out.println("Result: " + proxy.send(message));client.close();}
}
3. 动态方法实现HTTP RPC
3.1 message.avpr
{ "namespace": "cn.slimsmart.avro.demo", "protocol": "messageProtocol", "doc": "This is a message.", "name": "Message", "types": [ {"name":"message", "type":"record", "fields":[ {"name":"name", "type":"string"}, {"name":"type", "type":"int"}, {"name":"price", "type":"double"}, {"name":"valid", "type":"boolean"}, {"name":"content", "type":"string"} ] } ], "messages": { "sendMessage":{ "doc" : "message test", "request" :[{"name":"message","type":"message" }], "response" :"message" } } }
3.2 java 代码
public class Server extends GenericResponder { private Protocol protocol = null; private int port; public Server(Protocol protocol, int port) { super(protocol); this.protocol = protocol; this.port = port; } @Override public Object respond(Message message, Object request) throws Exception { GenericRecord req = (GenericRecord) request; GenericRecord reMessage = null; if (message.getName().equals("sendMessage")) { GenericRecord msg = (GenericRecord)req.get("message"); System.out.print("接收到数据:"); System.out.println(msg); //取得返回值的类型 reMessage = new GenericData.Record(protocol.getType("message")); //直接构造回复 reMessage.put("name", "苹果"); reMessage.put("type", 100); reMessage.put("price", 4.6); reMessage.put("valid", true); reMessage.put("content", "最新上架货物"); } return reMessage; } public void run() { try { HttpServer server = new HttpServer(this, port); server.start(); server.join(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new Server(Utils.getProtocol(), 9090).run(); }
}public class Client { private Protocol protocol = null; private String host = null; private int port = 0; private int count = 0; public Client(Protocol protocol, String host, int port, int count) { this.protocol = protocol; this.host = host; this.port = port; this.count = count; } public long sendMessage() throws Exception { GenericRecord requestData = new GenericData.Record(protocol.getType("message")); requestData.put("name", "香梨"); requestData.put("type", 36); requestData.put("price", 5.6); requestData.put("valid", true); requestData.put("content", "价钱便宜"); // 初始化请求数据 GenericRecord request = new GenericData.Record(protocol.getMessages().get("sendMessage").getRequest()); request.put("message", requestData); Transceiver t = new HttpTransceiver(new URL("http://" + host + ":" + port)); GenericRequestor requestor = new GenericRequestor(protocol, t); long start = System.currentTimeMillis(); for (int i = 0; i < count; i++) { Object result = requestor.request("sendMessage", request); if (result instanceof GenericData.Record) { GenericData.Record record = (GenericData.Record) result; System.out.println(record); } } long end = System.currentTimeMillis(); System.out.println((end - start)+"ms"); return end - start; } public long run() { long res = 0; try { res = sendMessage(); } catch (Exception e) { e.printStackTrace(); } return res; } public static void main(String[] args) throws Exception { new Client(Utils.getProtocol(), "127.0.0.1", 9090, 5).run(); }
} public class Utils {public static Protocol getProtocol() { Protocol protocol = null; try { String url = Utils.class.getResource("").getPath()+"message.avpr";protocol = Protocol.parse(new File(url)); } catch (IOException e) { e.printStackTrace(); } return protocol; }
}
参考:
https://github.com/phunt/avro-rpc-quickstart/
https://my.oschina.net/tearsky/blog/509610
http://blog.jobbole.com/92290/
Avro RPC的两种实现方法:静态实现和动态实现相关推荐
- golang rpc的两种调用方法
golang的rpc有两种方法进行调用,一种是rpc例子中给的: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 2 ...
- golang python rpc_golang rpc的两种调用方法
golang的rpc有两种方法进行调用,一种是rpc例子中给的:package main import ( "net/rpc" "net/http" " ...
- java静态路由_Linux添加静态路由两种实现方法解析
添加路由的命令: 1.route add route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0 #添加一条静态路由 route add d ...
- python ioc di_Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法
Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法 第一中方法:在xml文件中注入: (1)开源的轻量级的应用开发框架 特点:a.简化开发:b.解耦:c.集成: 原理对象与对象之 ...
- Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理
Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理 代理模式 JDK动态代理 CGLIB动态代理 代理模式 代理模式是23种设计模式的一种,指一个对象A通过持有另一个对象B,可以具有B ...
- day030进程的两种创建方法,验证进程的空间隔离,join等待子进程
本节内容: 1.操作系统的简单介绍 2.进程的两种创建方法 3.进程之间是空间隔离的, 参考文章: 一.操作系统的简单介绍 1.操作系统简单介绍 操作系统就是一个协调.管理和控制计算机硬件资源和软件资 ...
- 两个路由器连接的两种连接方法
两个路由器连接的两种连接方法 第一台为A路由器,第二台为B路由器.前提是A路由器已经设置好能正常上网 . 方法1:WAN口连接.任意一台电脑连接B路由的LAN口(二个路由先不要连接,因为你的TP-LI ...
- 邮件服务器arp攻击,服务器的ARP欺骗攻击的防范的两种解决方法
服务器的ARP欺骗攻击的防范的两种解决方法 更新时间:2008年01月10日 11:59:11 作者: 服务器的ARP欺骗攻击的防范的两种解决方法 服务器的ARP欺骗攻击的防范 这些天我的服务器几 ...
- c语言蓝屏代码大全,window_Win10系统出现蓝屏提示错误代码0x00000050两种解决方法, 刚刚升级Win10系统的一段 - phpStudy...
Win10系统出现蓝屏提示错误代码0x00000050两种解决方法 刚刚升级Win10系统的一段时间,容易出现蓝屏的问题.导致蓝屏故障的原因各不相同,我们需要根据错误代码来执行正确的解决方法.比如,最 ...
最新文章
- RESTful之自动生成接口文档
- 低版本不能使用php 命令,创建软链接
- 微服务架构 — 服务治理 — 服务监控与告警、服务日志与审计
- python中读取文件内容-Python读取文件内容与存储
- seo从入门到精通_SEO入门到精通(七):SEO工作的流程是什么?
- Flutter 制作漂亮的登录表单
- vim语法高亮的错误解决办法
- eval 函数 代替函数_eval()函数以及JavaScript中的示例
- 前端学习(1760):前端调试值之如何让浏览器阻止请求相关资源
- java上传kafka的方法_哪种方法是将所有数据从Kafka主题复制到接收器(文件或Hive表)的最佳方法?...
- HDU1874 畅通工程续【Dijkstra算法】
- 190509每日一句
- atitit.基于bat cli的插件管理系统.doc
- m 940 /vbulletin/_爱在当下 MM 伴你纵享别样万圣之夜
- 数学建模常用算法汇总及python,MATLAB实现(七) —— sklearn和SPSS实现主成分分析
- React-native学习-59:使用react-native-vector-icons图标库
- Android实现屏幕自动旋转功能
- matlab编写多目标测试函数SCH, ZDT, MOP, DTLZ
- 工厂如何选择一款合适的工业平板电脑?
- 【算法】妙不可言---算法复杂性