前言java
目前流行的服務調用方式有不少種,例如基於 SOAP 消息格式的 Web Service,基於 JSON 消息格式的 RESTful 服務等。其中所用到的數據傳輸方式包括 XML,JSON 等,然而 XML 相對體積太大,傳輸效率低,JSON 體積較小,新穎,但還不夠完善。本文將介紹由 Facebook 開發的遠程服務調用框架 Apache Thrift,它採用接口描述語言定義並建立服務,支持可擴展的跨語言服務開發,所包含的代碼生成引擎能夠在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等建立高效的、無縫的服務,其傳輸數據採用二進制格式,相對 XML 和 JSON 體積更小,對於高併發、大數據量和多語言的環境更有優點。本文將詳細介紹 Thrift 的使用,而且提供豐富的實例代碼加以解釋說明,幫助使用者快速構建服務。apache
Thrift是一個跨語言的RPC框架,在公司工做的時候Thrift是至關重要的,這裏實驗了一個Thrift的小例子,以供學習和記錄。服務器
安裝Thrift0.11.0併發
安裝環境是MAC OS,version 10.13.4框架
參考官網上的安裝教程:http://thrift.apache.org/docs/install/os_xsocket
在安裝thrift的過程當中可能會報一些奇怪的錯誤,好比bison版本太低等問題,你們能夠網上參考解決。maven
一個簡單的Thrift服務ide
首先建立一個簡單的服務Hello.thrift高併發
namespace java com.thrift.demo.service service Hello{ string helloString(1:string para) i32 helloInt(1:i32 para) bool helloBoolean(1:bool para) void helloVoid() string helloNull() }
編譯爲java類學習
thrift -gen java Hello.thrift
會生成Hello.java文件
構建Maven項目thrifttest,編輯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>thrift-test</groupId> <artifactId>thrift-test</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.11.0</version> </dependency> </dependencies> </project>
把剛纔生成的Hello class文件拷貝到Maven項目中:
新建HelloServiceImpl類,實現Hello中Iface接口以下:
package com.thrift.demo.service; import org.apache.thrift.TException; public class HelloServiceImpl implements Hello.Iface { @Override public boolean helloBoolean(boolean para) throws TException { return para; } @Override public int helloInt(int para) throws TException { try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } return para; } @Override public String helloNull() throws TException { return null; } @Override public String helloString(String para) throws TException { return para; } @Override public void helloVoid() throws TException { System.out.println("Hello World"); } }
新建HelloServiceServer類,代碼以下:
package com.thrift.demo.service; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TNonblockingServer; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TTransportException; public class HelloServiceServer { /** * 啓動 Thrift 服務器 * @param args */ public static void main(String[] args) { try { TNonblockingServerSocket socket = new TNonblockingServerSocket(7911); Hello.Processor processor = new Hello.Processor(new HelloServiceImpl()); TNonblockingServer.Args arg = new TNonblockingServer.Args(socket); arg.protocolFactory(new TBinaryProtocol.Factory()); arg.transportFactory(new TFramedTransport.Factory()); arg.processorFactory(new TProcessorFactory(processor)); TServer server = new TNonblockingServer(arg); server.serve(); } catch (TTransportException e) { e.printStackTrace(); } } }
新建HelloServiceClient類,代碼以下:
package com.thrift.demo.service; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; public class HelloServiceClient { public static void main(String[] args){ try { TTransport tTransport = getTTransport(); TProtocol protocol = new TBinaryProtocol(tTransport); Hello.Client client = new Hello.Client(protocol); String result = client.helloString("hello"); System.out.println("The result is: " + result); }catch (Exception e) { e.printStackTrace(); } } private static TTransport getTTransport() throws Exception{ try{ TTransport tTransport = getTTransport("127.0.0.1", 7911, 5000); if(!tTransport.isOpen()){ tTransport.open(); } return tTransport; }catch(Exception e){ e.printStackTrace(); } return null; } private static TTransport getTTransport(String host, int port, int timeout) { final TSocket tSocket = new TSocket(host, port, timeout); final TTransport transport = new TFramedTransport(tSocket); return transport; } }
測試
啓動HelloServiceServer,而後啓動HelloServiceClient,會獲得以下結果:
可能遇到的問題:
Intellij IDEA可能會對Hello文件中的@override報錯:
解決方案以下:
1. 保證編譯thrift和Maven中添加的依賴版本相同;
2. 參考下面的解決辦法:https://blog.csdn.net/shenya2/article/details/50460447
a、在project/module上,右鍵選擇菜單「Open Module Settings」 ;
b、選擇Modules,修改「Language Level」 爲 「8-Lambdas,......」;
c、選擇Project, 修改「Project language level」 爲 「SDK default」。
d、保存,重啓。
謝謝你們~