Apache Avro RPC 实例

Avro的模式主要由JSON对象来表示,Avro支持8种基本类型(Primitive Type)和6种复杂类型(Complex Type:records、enums、arrays、maps、unions 和fixed),基本类型可以由JSON字符串来表示。

Avro支持两种序列化编码方式:二进制编码和JSON编码,使用二进制编码会高效序列化,并且序列化后得到的结果会比较小。

  基本类型:

  1. null: no value
  2. boolean: a binary value
  3. int: 32-bit signed integer
  4. long: 64-bit signed integer
  5. float: single precision (32-bit) IEEE 754 floating-point number
  6. double: double precision (64-bit) IEEE 754 floating-point number
  7. bytes: sequence of 8-bit unsigned bytes
  8. string: unicode character sequence
1.定义一个消息结构
[plain]  view plain  copy
  1. {  
  2.     "namespace": "cn.slimsmart.avro.demo",  
  3.     "protocol": "messageProtocol",  
  4.     "doc": "This is a message.",  
  5.     "name": "Message",  
  6.     "types": [  
  7.         {"name":"message", "type":"record",  
  8.             "fields":[  
  9.                 {"name":"name", "type":"string"},  
  10.                 {"name":"type", "type":"int"},  
  11.                 {"name":"price", "type":"double"},  
  12.                 {"name":"valid", "type":"boolean"},  
  13.                 {"name":"content", "type":"string"}  
  14.                 ]  
  15.         }  
  16.     ],  
  17.     "messages":    {  
  18.         "sendMessage":{  
  19.             "doc" : "message test",  
  20.             "request" :[{"name":"message","type":"message" }],  
  21.             "response" :"message"  
  22.         }           
  23.     }     
  24. }  
其中定义了1种类型叫做message,有5个成员name、type、price、valid、content。还定义了1个消息服务叫做sendMessage,输入有一个参数,类型是message,返回message。

2.序列化

  Avro有两种序列化编码:binary和JSON。

3.rpc通信实现

Avro的RPC实现不需要定义服务接口,但需要从.avpr文件中解析协议,协议中定义了消息结构和消息服务。message.avpr中定义了一个类型叫message,定义了一个服务叫sendMessage。

添加依赖jar:

[html]  view plain  copy
  1. <dependency>  
  2.             <groupId>org.apache.avro</groupId>  
  3.             <artifactId>avro</artifactId>  
  4.             <version>1.7.7</version>  
  5.         </dependency>  
  6.         <dependency>  
  7.             <groupId>org.apache.avro</groupId>  
  8.             <artifactId>avro-ipc</artifactId>  
  9.             <version>1.7.7</version>  
  10.         </dependency>  

1)协议解析工具类

Utils.java

[java]  view plain  copy
  1. package cn.slimsmart.avro.demo;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.net.URL;  
  6.   
  7. import org.apache.avro.Protocol;  
  8.   
  9. public class Utils {  
  10.   
  11.     public static Protocol getProtocol() {  
  12.         Protocol protocol = null;  
  13.         try {  
  14.             URL url = Utils.class.getClassLoader().getResource("message.avpr");  
  15.             protocol = Protocol.parse(new File(url.getPath()));  
  16.         } catch (IOException e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.         return protocol;  
  20.     }  
  21. }  
2)服务端

[java]  view plain  copy
  1. package cn.slimsmart.avro.demo;  
  2.   
  3. import org.apache.avro.Protocol;  
  4. import org.apache.avro.Protocol.Message;  
  5. import org.apache.avro.generic.GenericData;  
  6. import org.apache.avro.generic.GenericRecord;  
  7. import org.apache.avro.ipc.HttpServer;  
  8. import org.apache.avro.ipc.generic.GenericResponder;  
  9.   
  10. public class Server extends GenericResponder {  
  11.   
  12.     private Protocol protocol = null;  
  13.     private int port;  
  14.   
  15.     public Server(Protocol protocol, int port) {  
  16.         super(protocol);  
  17.         this.protocol = protocol;  
  18.         this.port = port;  
  19.     }  
  20.   
  21.     @Override  
  22.     public Object respond(Message message, Object request) throws Exception {  
  23.         GenericRecord req = (GenericRecord) request;  
  24.         GenericRecord reMessage = null;  
  25.         if (message.getName().equals("sendMessage")) {  
  26.             GenericRecord msg = (GenericRecord)req.get("message");  
  27.             System.out.print("接收到数据:");  
  28.             System.out.println(msg);  
  29.             //取得返回值的类型  
  30.             reMessage =  new GenericData.Record(protocol.getType("message"));   
  31.             //直接构造回复  
  32.             reMessage.put("name""苹果");  
  33.             reMessage.put("type"100);  
  34.             reMessage.put("price"4.6);  
  35.             reMessage.put("valid"true);  
  36.             reMessage.put("content""最新上架货物");  
  37.         }  
  38.         return reMessage;  
  39.     }  
  40.   
  41.     public void run() {  
  42.         try {  
  43.             HttpServer server = new HttpServer(this, port);  
  44.             server.start();  
  45.             server.join();  
  46.         } catch (Exception e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.     }  
  50.   
  51.     public static void main(String[] args) {  
  52.         new Server(Utils.getProtocol(), 9090).run();  
  53.     }  
  54. }  

3)客户端

[java]  view plain  copy
  1. package cn.slimsmart.avro.demo;  
  2.   
  3. import java.net.URL;  
  4.   
  5. import org.apache.avro.Protocol;  
  6. import org.apache.avro.generic.GenericData;  
  7. import org.apache.avro.generic.GenericRecord;  
  8. import org.apache.avro.ipc.HttpTransceiver;  
  9. import org.apache.avro.ipc.Transceiver;  
  10. import org.apache.avro.ipc.generic.GenericRequestor;  
  11.   
  12. public class Client {  
  13.   
  14.     private Protocol protocol = null;  
  15.     private String host = null;  
  16.     private int port = 0;  
  17.     private int count = 0;  
  18.   
  19.     public Client(Protocol protocol, String host, int port, int count) {  
  20.         this.protocol = protocol;  
  21.         this.host = host;  
  22.         this.port = port;  
  23.         this.count = count;  
  24.     }  
  25.   
  26.     public long sendMessage() throws Exception {  
  27.         GenericRecord requestData = new GenericData.Record(protocol.getType("message"));  
  28.         requestData.put("name""香梨");  
  29.         requestData.put("type"36);  
  30.         requestData.put("price"5.6);  
  31.         requestData.put("valid"true);  
  32.         requestData.put("content""价钱便宜");  
  33.           
  34.         // 初始化请求数据  
  35.         GenericRecord request = new GenericData.Record(protocol.getMessages().get("sendMessage").getRequest());  
  36.         request.put("message", requestData);  
  37.   
  38.         Transceiver t = new HttpTransceiver(new URL("http://" + host + ":" + port));  
  39.         GenericRequestor requestor = new GenericRequestor(protocol, t);  
  40.           
  41.         long start = System.currentTimeMillis();  
  42.         for (int i = 0; i < count; i++) {  
  43.               Object result = requestor.request("sendMessage", request);  
  44.               if (result instanceof GenericData.Record) {  
  45.                   GenericData.Record record = (GenericData.Record) result;  
  46.                   System.out.println(record);  
  47.               }  
  48.         }  
  49.         long end = System.currentTimeMillis();  
  50.         System.out.println((end - start)+"ms");  
  51.         return end - start;  
  52.     }  
  53.   
  54.     public long run() {  
  55.         long res = 0;  
  56.         try {  
  57.             res = sendMessage();  
  58.         } catch (Exception e) {  
  59.             e.printStackTrace();  
  60.         }  
  61.         return res;  
  62.     }  
  63.   
  64.     public static void main(String[] args) throws Exception {  
  65.         new Client(Utils.getProtocol(), "127.0.0.1"90905).run();  
  66.     }  
  67. }  
Avro IPC提供了如下几种服务端和客户端实现:

1.基于jetty的http实现

HttpServer 和HttpTransceiver

2.基于netty的实现

NettyServer和NettyTransceiver

3.基于TCP的实现

SocketServer和SocketTransceiver

4.基于UDP的实现

DatagramServer和DatagramTransceiver

5.基于加密的TCP实现

SaslSocketServer和SaslSocketTransceiver

猜你喜欢

转载自blog.csdn.net/u010670689/article/details/80560648
今日推荐