RPC 之 windows上使用thrift

2024-04-17 21:58
文章标签 使用 windows rpc thrift

本文主要是介绍RPC 之 windows上使用thrift,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘要:apache thrift作为著名的跨语言,跨平台的RPC框架已经得到了大量应用,比如Hadoop, Cassandra等。与早期的CORBA, DCOM, 以致传统的WebService如基于XML-RPC的 SOAP协议和基于http的restfull ws相比较,其强大的功能和性能以及开发效率都让人侧目。本文目的在于在windows上使用thrift编译一个RPC的java客户端和服务器来体验其使用。

关键字
: RPC , thrift

1.下载和安装thrift
到 http://apache.fayea.com/thrift/0.9.2/thrift-0.9.2.exe 下载,可直接将下载目录加到Windows环境变量,以便可以随时敲thrift-0.9.2命令。

2.编译tutorial.thrift文件为java 代码:
 到 https://git1-us-west.apache.org/repos/asf?p=thrift.git;a=tree;f=tutorial;hb=HEAD 下载tutorial.thrift和shared.thrift 2个文件 ,  先执行   thrift-0.9.2 -gen java  tutorial\shared.thrift  然后执行  thrift-0.9.2 -gen java  tutorial\tutorial.thrift , 可以发现生成了gen-java目录,
 将生成的java 类 进行编译会报错,放于eclipse工程中会发现很多包缺失,比如org.apache.thrift.* ;
 org.apache.thrift报缺失是因为thrift的java类库需要构建出来。如果我们只下载了thrift-0.9.2.exe 那么是不带thrift-0.9.2.jar这个类库的。
 可以下载thrift的源码 (http://mirrors.hust.edu.cn/apache/thrift/0.9.2/thrift-0.9.2.tar.gz)将其解压,到目录lib\java下执行ant (需要之前安装java和ant,并将ant folder\bin加到环境变量).会生成lib\java\build,其下有thrift-0.9.2.jar

3. 写自己的客户端和服务器程序:
添加CalculatorHandler.java :

import java.util.HashMap;
import tutorial.Calculator;
import tutorial.InvalidOperation;
import tutorial.SharedStruct;
import tutorial.Work;public class CalculatorHandler implements Calculator.Iface {private HashMap<Integer, SharedStruct> log;public CalculatorHandler() {log = new HashMap<Integer, SharedStruct>();}public void ping() {System.out.println("ping()");}public int add(int n1, int n2) {System.out.println("add(" + n1 + "," + n2 + ")");return n1 + n2;}public int calculate(int logid, Work work) throws InvalidOperation {System.out.println("calculate(" + logid + ", {" + work.op + ","+ work.num1 + "," + work.num2 + "})");int val = 0;switch (work.op) {case ADD:val = work.num1 + work.num2;break;case SUBTRACT:val = work.num1 - work.num2;break;case MULTIPLY:val = work.num1 * work.num2;break;case DIVIDE:if (work.num2 == 0) {InvalidOperation io = new InvalidOperation();io.what = work.op.getValue();io.why = "Cannot divide by 0";throw io;}val = work.num1 / work.num2;break;default:InvalidOperation io = new InvalidOperation();io.what = work.op.getValue();io.why = "Unknown operation";throw io;}SharedStruct entry = new SharedStruct();entry.key = logid;entry.value = Integer.toString(val);log.put(logid, entry);return val;}public SharedStruct getStruct(int key) {System.out.println("getStruct(" + key + ")");return log.get(key);}public void zip() {System.out.println("zip()");}}
<strong>
</strong>
添加client.java :
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;import tutorial.Calculator;
import tutorial.InvalidOperation;
import tutorial.Operation;
import tutorial.SharedStruct;
import tutorial.Work;public class Client {static void simple() throws Exception {TTransport transport =  new TSocket("localhost", 9090);transport.open();TProtocol protocol = new  TBinaryProtocol(transport);Calculator.Client client = new Calculator.Client(protocol);perform(client);transport.close();}private static void perform(Calculator.Client client) throws TException{client.ping();System.out.println("ping()");int sum = client.add(1,1);System.out.println("1+1=" + sum);Work work = new Work();work.op = Operation.DIVIDE;work.num1 = 1;work.num2 = 0;try {int quotient = client.calculate(1, work);System.out.println("Whoa we can divide by 0");} catch (InvalidOperation io) {System.out.println("Invalid operation: " + io.why);}work.op = Operation.SUBTRACT;work.num1 = 15;work.num2 = 10;try {int diff = client.calculate(1, work);System.out.println("15-10=" + diff);} catch (InvalidOperation io) {System.out.println("Invalid operation: " + io.why);}SharedStruct log = client.getStruct(1);System.out.println("Check log: " + log.value);}/*** @param args* @throws Exception*/public static void main(String[] args) throws Exception {simple();}}
添加server.java :

import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.server.TSimpleServer;import tutorial.Calculator;public class Server {static final int port_Simple = 9090;public static void simple(Calculator.Processor processor) {try {// Args arg = null;TServerTransport serverTransport = new TServerSocket(port_Simple);TServer server = new TSimpleServer(    new Args(serverTransport).processor(processor));// Use this for a multithreaded server// TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));System.out.println("Starting the simple server...");server.serve();} catch (Exception e) {e.printStackTrace();}}/*** @param args*/public static void main(String[] args) {CalculatorHandler handler = new CalculatorHandler();Calculator.Processor processor = new Calculator.Processor(handler);simple(processor);}}

---引用jar: libthrift-0.9.2.jar, slf4j-*.jar

4.启动 server,再运行client可以看到客户端输出:

ping()
1+1=2
Invalid operation: Cannot divide by 0
15-10=5
Check log: 5


总结:
1. thrift缺点:

  1)文档少,初学者要花较长时间来琢磨如何写出第一个基于thrift RPC的C/S程序.
  2)文档bug多,文档描述与实际运行的行为不符。比如根据文档的tutorial/tutorial.thrift来生成Java代码时 并没有生成shared.SharedService类。
  3)windows上的thrift编译器(比如thrift-0.9.2.exe)有bug,对于thrift文件中的include指示符支持不好。

2. thrift优点:

  1)跨平台,跨/多语言的支持非常好。比如一个运行在Windows上的c#客户端完全可以访问一个运行在Linux机器上的用Java实现的服务器端。
    thrift编译器可以根据thrift文件编译出针对当下几乎所有流行语言的代码()。
  2)性能好。 如果服务端代码用c/c++则性能更是杠杠的。
  3)开发效率高,手工代码量小。  thrift编译器所生成的代码基本上拿来即可使用,(需要增加服务端代码来实现自己的业务逻辑,但是协议实现,数据类型实现都已经自动生成)。
  4)兼容性好。如果thrift文件更改,那么之前基于老thrift文件的程序仍能良好运行。
 
参考资料:

1. Apache thrift网站:http://thrift.apache.org/
2. RPC性能比较: http://www.useopen.net/blog/2015/rpc-performance.html
3. 董西城的博客: http://dongxicheng.org/search-engine/thrift-rpc/


这篇关于RPC 之 windows上使用thrift的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912966

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他