Avro实现RPC
Posted it_ch
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Avro实现RPC相关的知识,希望对你有一定的参考价值。
RPC是什么?
- RPC是指远程过程调用【是一种进程间的通信方式】
- 例如两台服务器A,B,一个应用部署在A上面,A想要调B服务器上的函数或者方法,由于不在一个内存空间,不能直接调用,需要通过网络来传达调用的数据
RPC的特点?
- 简单:语义清晰简单,建立分布式计算更加容易
- 高效:远程调用简单高效
- 通用:RPC把远程调用做的和本地调用完全类似,那么就容易被接受,使用起来也没有障碍
RPC架构?
1)用户(User)
2)用户存根(User-Stub)
3)RPC通信包(被称为RPCRuntime)
4)服务器存根(Server)
5)服务器(Server)
当用户发起一个远程CALL的时候,远程如下:
- 服务消费方(User)调用以本地方式调用服务;
- User-stub(存根)接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体,并交给RPCRuntime模块
- RPCRuntime找到服务地址,并将消息发送到服务端
- 服务端的RPCRuntime收到消息后,传给Server-stub
- Server-stub根据解码结果调用本地的服务
- 本地服务执行并将结果返回给Server-stub
- server stub将返回结果打包成消息并发送至消费方
- client stub接收到消息,并进行解码
- 服务消费方得到最终结果
实现步骤
1.创建maven工程,导入pom依赖
<?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.blb</groupId> <artifactId>Avro_RPC</artifactId> <version>1.0-SNAPSHOT</version> <name>Avro_RPC</name> <!-- FIXME change it to the project‘s website --> <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>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.avro/avro --> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.8.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.avro/avro-tools --> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-tools</artifactId> <version>1.8.2</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-maven-plugin</artifactId> <version>1.8.2</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-compiler</artifactId> <version>1.8.2</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-ipc</artifactId> <version>1.8.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.avro</groupId> <artifactId>avro-maven-plugin</artifactId> <version>1.8.2</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.8</source> <target>1.8</target> </configuration> </plugin> </plugins> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --> <plugin> <artifactId>maven-site-plugin</artifactId> <version>3.7.1</version> </plugin> <plugin> <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.0.0</version> </plugin> </plugins> </pluginManagement> </build> </project>
2.在指定目录下编辑acdl文件
a. 如果传递的是基本类型,则示例格式如下:
@namespace("rpc.service") protocol AddService{ int add(int i,int y); }
b. 如果传递的是对象,则示例格式如下:
@namespace("rpc.service") protocol TransferService{ import schema "User.avsc"; void parseUser(avro.domain.User user); }
c. 如果传递的是map,并且map中包含对象,则示例格式如下:
@namespace("rpc.service") protocol MapService{ import schema "User.avsc"; void parseUserMap(map<avro.domain.User> userMap); }
d.这个是我们的User.avdl文件
@namespace("com.service") protocol AddService{ import schema "user.avsc"; int add(int x , int y); void parseUser(com.domain.User user); }
3.根据avro插件生成文件对应的接口类
4.实现服务器端接口
package com.blb.service; import com.blb.pojo.User; import org.apache.avro.AvroRemoteException; public class AddServiceImpl implements AddService { @Override public int add(int x, int y) throws AvroRemoteException { System.out.println(x+y); return x+y; } @Override public Void parseUser(User user) throws AvroRemoteException { System.out.println(user); return null; } }
5.实现服务器端
package com.blb.server; import com.blb.service.AddService; import com.blb.service.AddServiceImpl; import org.apache.avro.ipc.NettyServer; import org.apache.avro.ipc.specific.SpecificResponder; import java.net.InetSocketAddress; public class RPC_Server { public static void main(String[] args) { NettyServer server = new NettyServer( new SpecificResponder(AddService.class,new AddServiceImpl()), new InetSocketAddress(9999) ); System.out.println("服务端启动"); } }
6.实现客户端
package com.blb.client; import com.blb.service.AddService; import org.apache.avro.ipc.NettyTransceiver; import org.apache.avro.ipc.specific.SpecificRequestor; import java.io.IOException; import java.net.InetSocketAddress; public class RPC_Client { public static void main(String[] args) throws IOException { NettyTransceiver client = new NettyTransceiver( new InetSocketAddress("127.0.0.1",9999) ); //--因为接口不能直接使用,avro底层是通过jdk动态代理生成接口的代理对象 AddService proxy = SpecificRequestor.getClient(AddService.class,client); int result = proxy.add(2,3); System.out.println("客户端收到结果:"+result); } }
7.运行结果
以上是关于Avro实现RPC的主要内容,如果未能解决你的问题,请参考以下文章
从 BigQuery 读取数据并将其写入云存储上的 avro 文件格式