RPC我还是第一次使用,而且Avro更是第一次学习。
1.编写Schema文件
新建user.avsc文件,内容如下,这里的namespace就是生成代码后的类的包路径:
1 2 3 4 5 6 7 8 9
| {"namespace": "com.example", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "favorite_number", "type": ["int", "null"]}, {"name": "favorite_color", "type": ["string", "null"]} ] }
|
2.编写avdl文件,生成接口
新建avdl接口说明文件,内容如下,这里的namespace就是生成代码后的类的包路径:
1 2 3 4 5 6 7 8 9 10
| @namespace("com.example.protocol") protocol HelloProtocol { import schema "user.avsc"; record Message { string id; string msg; } string hello(com.example.User user); }
|
管网下载,就不说了。
4.命令行执行生成rpc调用方法和序列化类
先执行idl命令,根据avdl文件生成json文件,然后执行compile protocol,生成接口文件。
1 2 3 4
| java -jar .\avro-tools-1.9.1.jar idl .\helloprotocol.avdl .\helloprotocol.json
java -jar .\avro-tools-1.9.1.jar compile protocol .\helloprotocol.json .
|
avro_tool工具将自动生成类文件夹:
文件夹中包括了序列化和反序列的User类:
以及供远程调用的远程接口及远程方法:
注意
执行protocol命令时,最后的点,是表示在当前目录下生成类和方法,否则会出现错误:
5.新建maven工程avro-rpc的服务端
在maven的pom.xml文件中添加如下内容:
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId> <artifactId>AvroRPCServer</artifactId> <version>1.0-SNAPSHOT</version>
<name>AvroRPCServer</name> <url>http://www.example.com</url>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties>
<dependencies> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.9.1</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-ipc</artifactId> <version>1.9.1</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-ipc-netty</artifactId> <version>1.9.1</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.apache.avro</groupId> <artifactId>avro-maven-plugin</artifactId> <version>1.9.1</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>schema</goal> </goals> <configuration> <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory> <outputDirectory>${project.basedir}/src/main/java/</outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project>
|
注意添加ipc支持,否则idea会报错:
6.实现协议接口
将第四章生成的HelloProtocol.java接口以及数据类User.java复制到工程目录中(注意你的类中包的名字)。然后新建类HelloService,并实现HelloProtocol接口,这里的user.getName()等方法根据自己写的属性进行替换,接口方法也需要适当的调整。
1 2 3 4 5 6 7 8 9 10
| import org.apache.avro.AvroRemoteException;
public class HelloService implements HelloProtocol { @Override public CharSequence hello(User user) { System.out.println(user.getName() + "," + user.getFavoriteNumber() + "," + user.getFavoriteColor()); return "hai i`m from avro service"; } }
|
7.发布服务
实现了HelloService,就可以在主程序中发布服务了,监听了端口号65111。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import org.apache.avro.ipc.Responder; import org.apache.avro.ipc.Server; import org.apache.avro.ipc.netty.NettyServer; import org.apache.avro.ipc.specific.SpecificResponder;
import java.net.InetSocketAddress;
public class App { @SuppressWarnings("unused") private static Server server; public static void main( String[] args ) { System.out.println( "Hello World!" ); Responder responder=new SpecificResponder(HelloProtocol.class, new HelloService()); server=new NettyServer(responder, new InetSocketAddress(65111)); } }
|
运行main程序,等待连接:
注意添加NettyServer的maven,否则报错:
8.新建RPC的客户端工程
新建AvroRPCClient的maven工程,pom.xml参考服务端。
9.复制类文件
同服务端一样,将avro-tool生成的User.java和HelloProtocol.java复制到工程目录中,注意包路径。
10.编写Main函数,调用远程接口
在main函数中,添加如下代码:
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 26 27 28 29 30 31
| package com.proheng;
import org.apache.avro.ipc.netty.NettyTransceiver; import org.apache.avro.ipc.specific.SpecificRequestor;
import java.net.InetSocketAddress;
public class App { public static void main( String[] args ) { System.out.println( "Hello World!" );
try{ NettyTransceiver client = new NettyTransceiver(new InetSocketAddress(65111)); HelloProtocol proxy = SpecificRequestor.getClient(HelloProtocol.class, client); User user = new User(); user.setName("xiaofen"); user.setFavoriteNumber(1); user.setFavoriteColor("dsf"); System.out.println(proxy.hello(user)); }catch (Exception e){ System.out.println(e); }
} }
|
运行客户端main,输出如下:
查看服务端输出:
测试成功!!!