目錄:
一、什麼是Thrift?
1) Thrift內部框架一瞥
2) 支援的資料傳輸格式、資料傳輸方式和服務模型
3) Thrift IDL
二、Thrift的官方網站在哪裡?
三、在哪裡下載?需要哪些元件的支援?
四、如何安裝?
五、Golang、Java、Python、PHP之間通過Thrift實現跨語言呼叫
1) Golang 客戶端和服務端的實現及互動
2) python 客戶端的實現與golang 服務端的互動
3) php 客戶端的實現與golang 服務端的互動
4) java 客戶端的實現與golang 服務端的互動
六、擴充套件閱讀
一、什麼是Thrift
Thrift是一種可伸縮的跨語言服務的發展軟體框架。它結合了功能強大的軟體堆疊的程式碼生成引擎,以建設服務。
Thrift是facebook開發的,07年4月開放原始碼,08年5月進入apache孵化器。創造Thrift是為了解決facebook系統中各系統間大資料量的傳 輸通訊以及系統之間語言環境不同需要跨平臺的特性。所以thrift可以支援多種程式語言,例如: C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml. (目前0.9.1版本已經開始支援golang語言)在多種不同的語言之間通訊thrift可以作為二進位制的高效能的通訊中介軟體,支援資料(物件)序列化和多種型別的RPC服務。
Thrift允許你定義一個簡單的定義檔案中的資料型別和服務介面。以作為輸入檔案,編譯器生成程式碼用來方便地生成RPC客戶端和伺服器通訊的無縫跨程式語言。簡而言之,開發者只需準備一份thrift指令碼,通過thrift code generator(像gcc那樣輸入一個命令)就能生成所要求的開發語言程式碼。
類似Thrift的工具,還有Avro、protocol buffer,但相對於Thrift來講,都沒有Thrift支援全面和使用廣泛。
1) thrift內部框架一瞥
按照官方文件給出的整體框架,Thrift自下到上可以分為4層:
+-------------------------------------------+
| Server | -- 伺服器程式排程
| (single-threaded, event-driven etc) |
+-------------------------------------------+
| Processor | -- RPC介面處理函式分發,IDL定義介面的實現將掛接到這裡面
| (compiler generated) |
+-------------------------------------------+
| Protocol | -- 協議
| (JSON, compact etc) |
+-------------------------------------------+
| Transport | -- 網路傳輸
| (raw TCP, HTTP etc) |
+-------------------------------------------+
Thrift實際上是實現了C/S模式,通過程式碼生成工具將介面定義檔案生成伺服器端和客戶端程式碼(可以為不同語言),從而實現服務端和客戶端跨語言的支援。使用者在Thirft描述檔案中宣告自己的服務,這些服務經過編譯後會生成相應語言的程式碼檔案,然後使用者實現服務(客戶端呼叫服務,伺服器端提服務)便可以了。其中protocol(協議層, 定義資料傳輸格式,可以為二進位制或者XML等)和transport(傳輸層,定義資料傳輸方式,可以為TCP/IP傳輸,記憶體共享或者檔案共享等)被用作執行時庫。
2)支援的資料傳輸格式、資料傳輸方式和服務模型
(a)支援的傳輸格式
TBinaryProtocol – 二進位制格式.
TCompactProtocol – 壓縮格式
TJSONProtocol – JSON格式
TSimpleJSONProtocol –提供JSON只寫協議, 生成的檔案很容易通過指令碼語言解析。
TDebugProtocol – 使用易懂的可讀的文字格式,以便於debug
(b) 支援的資料傳輸方式
TSocket -阻塞式socker
TFramedTransport – 以frame為單位進行傳輸,非阻塞式服務中使用。
TFileTransport – 以檔案形式進行傳輸。
TMemoryTransport – 將記憶體用於I/O. java實現時內部實際使用了簡單的ByteArrayOutputStream。
TZlibTransport – 使用zlib進行壓縮, 與其他傳輸方式聯合使用。當前無java實現。
(c)支援的服務模型
TSimpleServer – 簡單的單執行緒服務模型,常用於測試
TThreadPoolServer – 多執行緒服務模型,使用標準的阻塞式IO。
TNonblockingServer – 多執行緒服務模型,使用非阻塞式IO(需使用TFramedTransport資料傳輸方式)
3) Thrift IDL
Thrift定義一套IDL(Interface Definition Language)用於描述介面,通常字尾名為.thrift,通過thrift程式把.thrift檔案匯出成各種不一樣的程式碼的協議定義。IDL支援的型別可以參考這裡:http://thrift.apache.org/docs/types
二、Thrift的官方網站在哪裡?
三、在哪裡下載?需要哪些元件的支援?
Thrift的官方下載地址在這裡:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.1/thrift-0.9.1.tar.gz
(現在官網打包後的0.9.1版本在make的時候會出各種問題,後文會介紹不建議使用官網提供的0.9.1包)
Thrift的安裝依賴,以及相關語言支援所需要的庫,以下是來自官方文件的介紹:
Basic requirements
A relatively POSIX-compliant *NIX system
Cygwin or MinGW can be used on Windows
g++ 4.2
boost 1.53.0
Runtime libraries for lex and yacc might be needed for the compiler.
Requirements for building from source
GNU build tools:
autoconf 2.65
automake 1.9
libtool 1.5.24
pkg-config autoconf macros (pkg.m4)
lex and yacc (developed primarily with flex and bison)
libssl-dev
Language requirements
These are only required if you choose to build the libraries for the given language
C++
Boost 1.53.0
libevent (optional, to build the nonblocking server)
zlib (optional)
Java
Java 1.7
Apache Ant
C#: Mono 1.2.4 (and pkg-config to detect it) or Visual Studio 2005+
Python 2.6 (including header files for extension modules)
PHP 5.0 (optionally including header files for extension modules)
Ruby 1.8
bundler gem
Erlang R12 (R11 works but not recommended)
Perl 5
Bit::Vector
Class::Accessor
四、如何安裝?
1) 安裝依賴外掛
1
|
root@m1: /home/hadoop #sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev |
2) 安裝最新版PHP5(因為後文會使用PHP來測試客戶端與Golang服務端的互動)
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
|
#先新增phpkey root@m2: /home/hadoop/thrift-git # add-apt-repository ppa:ondrej/php5 You are about to add the following PPA to your system: This branch follows latest PHP packages as maintained by me & rest of the Debian pkg-php team. You can get more information about the packages at https: //sury .org If you need to stay with PHP 5.4 you can use the oldstable PHP repository: ppa:ondrej /php5-oldstable BUGS&FEATURES: This PPA now has a issue tracker: https: //deb .sury.org /pages/bugreporting .html PLEASE READ: If you like my work and want to give me a little motivation, please consider donating: https: //deb .sury.org /pages/donate .html More info: https: //launchpad .net/~ondrej/+archive /ubuntu/php5 Press [ENTER] to continue or ctrl-c to cancel adding it gpg: 鑰匙環‘ /tmp/tmpZ7PZIy/secring .gpg’已建立 gpg: 鑰匙環‘ /tmp/tmpZ7PZIy/pubring .gpg’已建立 gpg: 下載金鑰‘E5267A6C’,從 hkp 伺服器 keyserver.ubuntu.com gpg: /tmp/tmpZ7PZIy/trustdb .gpg:建立了信任度資料庫 gpg: 金鑰 E5267A6C:公鑰“Launchpad PPA for Ondřej Surý”已匯入 gpg: 合計被處理的數量:1 gpg: 已匯入:1 (RSA: 1) OK root@m2: /home/hadoop/thrift-git # apt-get update root@m1: /home/hadoop/thrift-git # apt-get install php5-dev php5-cli phpunit |
3) 下載thirft0.9.1版本
1
2
3
4
5
6
7
8
9
10
11
|
root@m2: /home/hadoop # git clone https://github.com/apache/thrift.git thrift-git Cloning into 'thrift-git' ... remote: Counting objects: 37193, done . remote: Compressing objects: 100% (216 /216 ), done . remote: Total 37193 (delta 319), reused 407 (delta 272) Receiving objects: 100% (37193 /37193 ), 9.62 MiB | 50 KiB /s , done . Resolving deltas: 100% (25794 /25794 ), done . root@m1: /home/hadoop #cd thrift-git root@m2: /home/hadoop/thrift-git # git checkout -b 0.9.1 Switched to a new branch '0.9.1' |
4) 編譯安裝
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
|
root@m1: /home/hadoop/thrift-git #./bootstrap.sh root@m1: /home/hadoop/thrift-git # ./configure --enable-thrift_protocol #下面是擷取部分執行成功後的資訊 thrift 0.9.1 Building C++ Library ......... : yes Building C (GLib) Library .... : yes Building Java Library ........ : no Building C # Library .......... : no Building Python Library ...... : yes Building Ruby Library ........ : no Building Haskell Library ..... : no Building Perl Library ........ : no Building PHP Library ......... : yes Building Erlang Library ...... : no Building Go Library .......... : no Building D Library ........... : no C++ Library: Build TZlibTransport ...... : yes Build TNonblockingServer .. : yes Build TQTcpServer (Qt) .... : no Python Library: Using Python .............. : /usr/bin/python PHP Library: Using php-config .......... : /usr/bin/php-config If something is missing that you think should be present, please skim the output of configure to find the missing component. Details are present in config.log. |
如果在安裝Thrift時,不需要支援的擴充套件,可以在使用./configure的時候帶上以下引數
1
|
. /configure --without-php --without-ruby --without-haskell --without-python --without-perl |
繼續安裝這個時間會長一點
1
2
|
root@m2: /home/hadoop/thrift-git # make root@m2: /home/hadoop/thrift-git # make install |
我們可以看到thrift已經安裝完成,當前版本是0.9.1
1
2
|
root@m1: /home/hadoop/thrift-git # thrift -version Thrift version 0.9.1 |
五、Golang、Java、Python、PHP之間通過Thrift實現跨語言呼叫
在寫程式碼之前,我們先來配置Thrift的協議庫IDL檔案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@m1: /home/hadoop/thrift-git/tutorial # vi idoall.org.thrift namespace go idoall.org.demo namespace java idoall.org.demo namespace php idoall.org.demo namespace py idoall.org.demo struct Student{ 1: i32 sid, 2: string sname, 3: bool ssex=0, 4: i16 sage, } const map<string,string> MAPCONSTANT = { 'hello' : 'world' , 'goodnight' : 'moon' } service idoallThrift { list<string> CallBack(1:i64 callTime, 2:string name, 3:map<string, string> paramMap), void put(1: Student s), } |
編譯IDL檔案,生成相關程式碼
1
2
3
4
|
root@m1: /home/hadoop/thrift-git/tutorial # thrift -r --gen go idoall.org.thrift root@m1: /home/hadoop/thrift-git/tutorial # thrift -r --gen py idoall.org.thrift root@m1: /home/hadoop/thrift-git/tutorial # thrift -r --gen php idoall.org.thrift root@m1: /home/hadoop/thrift-git/tutorial # thrift -r --gen java idoall.org.thrift |
如果編譯IDL的PHP包要生成server端程式碼,和其他語言不太一樣,可以使用thrift --help檢視使用說明,需要加上server選項,如下:
1
|
root@m1: /home/hadoop/thrift-git/tutorial # thrift -r --gen php:server idoall.org.thrift |
1) Golang 客戶端和服務端的實現及互動
1
|
root@m1: /home/hadoop/thrift-git/tutorial # go get git.apache.org/thrift.git/lib/go/thrift |
#將Thrift生成的開發庫也複製到GOPATH中
1
|
root@m1: /home/hadoop/thrift-git/tutorial # cp -r /home/hadoop/thrift-git/tutorial/gen-go/idoall $GOPATH/src |
#編寫go server端程式碼(後面的程式碼,我們都放在/home/hadoop/thrift_demo目錄中進行演示)
1
2
3
|
root@m1: /home/hadoop # mkdir thrift_demo root@m1: /home/hadoop # cd thrift_demo/ root@m1: /home/hadoop/thrift_demo # vi s.go |
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
|
package main import ( "idoall/org/demo" "fmt" "git.apache.org/thrift.git/lib/go/thrift" "os" ) const ( NetworkAddr = "0.0.0.0:10086" ) type idoallThrift struct { } func (this * idoallThrift) CallBack(callTime int64, name string, paramMap map [string]string) (r []string, err error) { fmt.Println( "-->from client Call:" , callTime, name, paramMap) r = append(r, "key:" + paramMap[ "a" ] + " value:" + paramMap[ "b" ]) return } func (this * idoallThrift) Put(s * demo.Student) (err error){ fmt.Printf( "Stduent--->id: %d\tname:%s\tsex:%t\tage:%d\n" , s.Sid, s.Sname, s.Ssex, s.Sage) return nil } func main() { transportFactory : = thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) protocolFactory : = thrift.NewTBinaryProtocolFactoryDefault() / / protocolFactory : = thrift.NewTCompactProtocolFactory() serverTransport, err : = thrift.NewTServerSocket(NetworkAddr) if err ! = nil { fmt.Println( "Error!" , err) os.Exit( 1 ) } handler : = &idoallThrift{} processor : = demo.NewIdoallThriftProcessor(handler) server : = thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) fmt.Println( "thrift server in" , NetworkAddr) server.Serve() } |
#編寫go client端程式碼
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
|
root@m1: / home / hadoop / thrift_demo # vi c.go package main import ( "idoall/org/demo" "fmt" "git.apache.org/thrift.git/lib/go/thrift" "net" "os" "time" "strconv" ) const ( HOST = "127.0.0.1" PORT = "10086" ) func main() { startTime : = currentTimeMillis() transportFactory : = thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) protocolFactory : = thrift.NewTBinaryProtocolFactoryDefault() transport, err : = thrift.NewTSocket(net.JoinHostPort(HOST, PORT)) if err ! = nil { fmt.Fprintln(os.Stderr, "error resolving address:" , err) os.Exit( 1 ) } useTransport : = transportFactory.GetTransport(transport) client : = demo.NewIdoallThriftClientFactory(useTransport, protocolFactory) if err : = transport. Open (); err ! = nil { fmt.Fprintln(os.Stderr, "Error opening socket to " + HOST + ":" + PORT, " " , err) os.Exit( 1 ) } defer transport.Close() for i : = 0 ; i < 5 ; i + + { paramMap : = make( map [string]string) paramMap[ "a" ] = "idoall" paramMap[ "b" ] = "org" + strconv.Itoa(i + 1 ) r1, _ : = client.CallBack(time.Now().UnixNano() / 1000000 , "go client" , paramMap) fmt.Println( "GOClient Call->" , r1) } model : = demo.Student{ 11 , "student-idoall-go" ,true, 20 } client.Put(&model) endTime : = currentTimeMillis() fmt.Printf( "本次呼叫用時:%d-%d=%d毫秒\n" ,endTime,startTime, (endTime - startTime)) } func currentTimeMillis() int64 { return time.Now().UnixNano() / 1000000 } |
#執行go服務端(可以看到服務端已經在監聽本機的10086埠)
1
2
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 |
#執行go客戶端
1
2
3
4
5
6
7
8
|
root@m1: /home/hadoop/thrift_demo # go run c.go GOClient Call-> [key:idoall value:org1] GOClient Call-> [key:idoall value:org2] GOClient Call-> [key:idoall value:org3] GOClient Call-> [key:idoall value:org4] GOClient Call-> [key:idoall value:org5] 本次呼叫用時:1408267333489-1408267333486=3毫秒 root@m1: /home/hadoop/thrift_demo # |
#檢視go服務端,可以看到資料的互動
1
2
3
4
5
6
7
8
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 -->from client Call: 1408267333487 go client map[a:idoall b:org1] -->from client Call: 1408267333487 go client map[a:idoall b:org2] -->from client Call: 1408267333488 go client map[b:org3 a:idoall] -->from client Call: 1408267333488 go client map[a:idoall b:org4] -->from client Call: 1408267333488 go client map[a:idoall b:org5] Stduent---> id : 11 name:student-idoall-go sex: true age:20 |
2) python 客戶端的實現與golang 服務端的互動
#將python用到的Thrift包複製到thrift_demo裡面
1
2
|
root@m1: /home/hadoop/thrift_demo # cp -r /home/hadoop/thrift-git/lib/py/build /home/hadoop/thrift_demo/libpy root@m1: /home/hadoop/thrift_demo # cp -r /home/hadoop/thrift-git/tutorial/gen-py /home/hadoop/thrift_demo/gen-py |
#編寫python client程式碼
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
|
root@m1: / home / hadoop / thrift_demo # vi c.py #!/usr/bin/env python # -*- coding: utf-8 -*- import sys, glob, time,datetime sys.path.append( 'gen-py' ) sys.path.insert( 0 , glob.glob( 'libpy/lib.*' )[ 0 ]) from idoall.org.demo import idoallThrift from idoall.org.demo.ttypes import * from thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol try : startTime = time.time() * 1000 # Make socket transport = TSocket.TSocket( '127.0.0.1' , 10086 ) # Framed is critical. Raw sockets are very slow transport = TTransport.TFramedTransport(transport) # Wrap in a protocol protocol = TBinaryProtocol.TBinaryProtocol(transport) # Create a client to use the protocol encoder client = idoallThrift.Client(protocol) # Connect! transport. open () for i in range ( 1 , 6 ): r = client.CallBack(time.time() * 1000 , "python client" ,{ "a" : "idoall" , "b" : "org" + str (i)}) print "PythonClient Call->%s" % (r) u1 = Student() u1.sid = 111 u1.sname = 'student-idoall-python' u1.ssex = False u1.sage = 200 client.put(u1) endTime = time.time() * 1000 print "本次呼叫用時:%d-%d=%d毫秒" % (endTime,startTime, (endTime - startTime)) # Close! transport.close() except Thrift.TException, tx: print 'ERROR:%s' % (tx.message) |
#執行go服務端
1
2
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 |
#執行python客戶端
1
2
3
4
5
6
7
8
|
root@m1: /home/hadoop/thrift_demo # python c.py PythonClient Call->[ 'key:idoall value:org1' ] PythonClient Call->[ 'key:idoall value:org2' ] PythonClient Call->[ 'key:idoall value:org3' ] PythonClient Call->[ 'key:idoall value:org4' ] PythonClient Call->[ 'key:idoall value:org5' ] 本次呼叫用時:1408268651648-1408268651646=2毫秒 root@m1: /home/hadoop/thrift_demo # |
#檢視go服務端,可以看到資料的互動
1
2
3
4
5
6
7
8
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 -->from client Call: 1408268651646 python client map[b:org1 a:idoall] -->from client Call: 1408268651646 python client map[a:idoall b:org2] -->from client Call: 1408268651647 python client map[a:idoall b:org3] -->from client Call: 1408268651647 python client map[a:idoall b:org4] -->from client Call: 1408268651647 python client map[a:idoall b:org5] Stduent---> id : 111 name:student-idoall-python sex: false age:200 |
3) php 客戶端的實現與golang 服務端的互動
#編譯php的Thrift擴充套件
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
|
root@m1: /home/hadoop/thrift_demo # cd /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # ls acinclude.m4 build config.h. in config. nice configure include ltmain.sh Makefile.global mkinstalldirs php_thrift_protocol.h thrift_protocol.la aclocal.m4 config.guess config.log config.status configure. in install -sh Makefile Makefile.objects modules php_thrift_protocol.lo autom4te.cache config.h config.m4 config.sub config.w32 libtool Makefile.fragments missing php_thrift_protocol.cpp run-tests.php root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # phpize Configuring for : PHP Api Version: 20121113 Zend Module Api No: 20121212 Zend Extension Api No: 220121212 root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # ./configure ##以下只給出部分輸出資訊 checking for grep that handles long lines and -e... /bin/grep checking for egrep ... /bin/grep -E checking for a sed that does not truncate output... /bin/sed checking for cc… cc … … config.status: creating config.h config.status: config.h is unchanged config.status: executing libtool commands #執行make命令後,我們可以看到擴充套件檔案放到了/usr/lib/php5/20121212/目錄 root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # make && make install Build complete. Don 't forget to run ' make test '. Installing shared extensions: /usr/lib/php5/20121212/ |
#讓PHP支援thrift,編輯php.ini檔案,搜尋extension_dir,然後在下面加上extension=thrift_protocol.so,儲存退出。
1
2
3
4
5
6
7
|
root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # vi /etc/php5/fpm/php.ini ; Directory in which the loadable extensions (modules) reside. ; http: //php .net /extension-dir ; extension_dir = "./" ; On windows: ; extension_dir = "ext" extension=thrift_protocol.so |
#重啟php5-fpm
1
2
3
4
|
root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # service php5-fpm restart php5-fpm stop /waiting php5-fpm start /running , process 16522 root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # |
#將php用到的Thrift包複製到thrift_demo裡面
1
2
3
4
5
|
root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # mkdir -p /home/hadoop/thrift_demo/libphp/ root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # cp -r /home/hadoop/thrift-git/lib/php/src/* /home/hadoop/thrift_demo/libphp/ root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # cp -r /home/hadoop/thrift-git/lib/php/lib/Thrift /home/hadoop/thrift_demo/libphp root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # cp -r /home/hadoop/thrift-git/tutorial/gen-php /home/hadoop/thrift_demo/gen-php root@m1: /home/hadoop/thrift-git/lib/php/src/ext/thrift_protocol # cd /home/hadoop/thrift_demo |
#編寫php client端程式碼
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
|
root@m1:/home/hadoop/thrift_demo# vi c.php <?php $startTime = getMillisecond(); $GLOBALS [ 'THRIFT_ROOT' ] = './libphp' ; # 指定庫目錄,可以是絕對路徑或是相對路徑 require_once $GLOBALS [ 'THRIFT_ROOT' ]. '/Thrift/ClassLoader/ThriftClassLoader.php' ; use Thrift\ClassLoader\ThriftClassLoader; use Thrift\Protocol\TBinaryProtocol; use Thrift\Transport\TSocket; use Thrift\Transport\TSocketPool; use Thrift\Transport\TFramedTransport; use Thrift\Transport\TBufferedTransport; $GEN_DIR = realpath (dirname( __FILE__ )). '/gen-php' ; $loader = new ThriftClassLoader(); $loader ->registerNamespace( 'Thrift' , $GLOBALS [ 'THRIFT_ROOT' ]); # 載入thrift $loader ->registerDefinition( 'idoall\org\demo' , $GEN_DIR ); # 載入自己寫的thrift檔案編譯的類檔案和資料定義 $loader ->register(); $socket = new TSocket( '127.0.0.1' , 10086); # 建立socket $socket ->setDebug(TRUE); $framedSocket = new TFramedTransport( $socket ); #這個要和伺服器使用的一致 $transport = $framedSocket ; $protocol = new TBinaryProtocol( $transport ); # 這裡也要和伺服器使用的協議一致 $transport ->open(); $client = new \idoall\org\demo\idoallThriftClient( $protocol ); # 構造客戶端 for ( $i =1; $i <6; $i ++) { $item = array (); $item [ "a" ] = "idoall" ; $item [ "b" ] = "org" + $i ; $result = $client ->CallBack(getMillisecond(), "php client" , $item ); # 對伺服器發起rpc呼叫 echo "PHPClient Call->" .implode( '' , $result ). "\n" ; } $s = new \idoall\org\demo\Student(); $s ->sid=1111; $s ->sname= "student-idoall-php" ; $s ->ssex = false; $s ->sage = 2000; $client ->put( $s ); $endTime = getMillisecond(); echo "本次呼叫用時:" . $endTime . "-" . $startTime . "=" .( $endTime - $startTime ). "毫秒\n" ; function getMillisecond() { list( $t1 , $t2 ) = explode ( ' ' , microtime()); return (float)sprintf( '%.0f' , ( floatval ( $t1 ) + floatval ( $t2 )) * 1000); } $transport ->close(); # 關閉連結 |
#執行go服務端
1
2
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 |
#執行php客戶端
1
2
3
4
5
6
7
|
root@m1: /home/hadoop/thrift_demo # php c.php PHPClient Call->key:idoall value:1 PHPClient Call->key:idoall value:2 PHPClient Call->key:idoall value:3 PHPClient Call->key:idoall value:4 PHPClient Call->key:idoall value:5 本次呼叫用時:1408268739277-1408268739269=8毫秒 |
#檢視go服務端,可以看到資料的互動
1
2
3
4
5
6
7
8
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 -->from client Call: 1408268739272 php client map[a:idoall b:1] -->from client Call: 1408268739273 php client map[a:idoall b:2] -->from client Call: 1408268739274 php client map[a:idoall b:3] -->from client Call: 1408268739275 php client map[a:idoall b:4] -->from client Call: 1408268739275 php client map[a:idoall b:5] Stduent---> id : 1111 name:student-idoall-php sex: false age:2000 |
4) java 客戶端的實現與golang 服務端的互動
#安裝maven專案管理工具
1
|
root@m1: /home/hadoop/thrift_demo # apt-get install maven |
#將java用到的Thrift包複製到thrift_demo裡面
1
2
3
4
5
6
|
root@m1: /home/hadoop/thrift_demo # cp -r /home/hadoop/thrift-git/tutorial/gen-java . root@m1: /home/hadoop/thrift_demo # cd gen-java root@m1: /home/hadoop/thrift_demo/gen-java # mkdir -p src/main/java root@m1: /home/hadoop/thrift_demo/gen-java # mkdir META-INF root@m1: /home/hadoop/thrift_demo/gen-java # mkdir lib root@m1: /home/hadoop/thrift_demo/gen-java # cp -r /home/hadoop/thrift-git/lib/java/build/libthrift-0.9.1.jar ./lib/ |
#編寫java client端程式碼
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
|
root @m1 :/home/hadoop/thrift_demo/gen-java# vi idoall/org/demo/c.java package idoall.org.demo; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.thrift.TException; 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; import org.apache.thrift.transport.TTransportException; public class c { public static final String SERVER_IP = "m1" ; public static final int SERVER_PORT = 10086 ; public static final int TIMEOUT = 30000 ; /** * @param args */ public static void main(String[] args) { long startTime=System.currentTimeMillis(); //獲取開始時間 TTransport transport = null ; try { transport = new TFramedTransport( new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT)); // 協議要和服務端一致 TProtocol protocol = new TBinaryProtocol(transport); idoallThrift.Client client = new idoallThrift.Client( protocol); transport.open(); for ( int i= 1 ;i< 6 ;i++) { Map<String,String> m = new HashMap<String,String>(); m.put( "a" , "idoall" ); m.put( "b" , "org" +i); List<String> result = client.CallBack(System.currentTimeMillis(), "java client" ,m); System.out.println( "JAVAClient Call->" + result); } Student s = new Student(); s.sid= 1111 ; s.sname= "student-idoall-java" ; s.ssex = true ; s.sage = 20000 ; client.put(s); long endTime = System.currentTimeMillis(); System.out.println( "本次呼叫用時:" + endTime + "-" + startTime + "=" + (endTime - startTime)+ "毫秒" ); } catch (TTransportException e) { e.printStackTrace(); } catch (TException e) { e.printStackTrace(); } finally { if ( null != transport) { transport.close(); } } } } |
#配置jar包的MANIFEST檔案
1
2
3
4
|
root@m1: /home/hadoop/thrift_demo/gen-java # vi META-INF/MANIFEST.MF Manifest-Version: 1.0 Main-Class: idoall.org.demo.c Class-Path: lib/**.jar |
#製作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
|
root@m1:/home/hadoop/thrift_demo/gen-java# vi pom.xml < 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 >idoall.org.demo</ groupId > < artifactId >idoall.org.demo</ artifactId > < version >0.0.1-SNAPSHOT</ version > < packaging >jar</ packaging > < name >idoall.org.demo</ name > < url >http://maven.apache.org</ url > < properties > < project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding > </ properties > < dependencies > < dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < version >3.8.1</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >org.apache.thrift</ groupId > < artifactId >libthrift</ artifactId > < version >0.9.1</ version > </ dependency > < dependency > < groupId >org.slf4j</ groupId > < artifactId >slf4j-log4j12</ artifactId > < version >1.5.8</ version > </ dependency > </ dependencies > < build > < plugins > < plugin > < artifactId >maven-assembly-plugin</ artifactId > < configuration > < archive > < manifest > < mainClass >idoall.org.demo.c</ mainClass > </ manifest > </ archive > < descriptorRefs > < descriptorRef >jar-with-dependencies</ descriptorRef > </ descriptorRefs > </ configuration > </ 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 > |
#使用maven工具,將相關依賴打包到當前目錄的target目錄中,並生成idoall.org.demo-0.0.1-SNAPSHOT-jar-with-dependencies.jar
1
2
3
4
5
6
7
8
9
10
|
root@m1: /home/hadoop/thrift_demo/gen-java # mv idoall src/main/java/ root@m1: /home/hadoop/thrift_demo/gen-java # mvn assembly:assembly #以下只給出部分提示資訊 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time : 7.618s [INFO] Finished at: Sun Aug 17 09:36:48 CST 2014 [INFO] Final Memory: 12M /29M [INFO] ------------------------------------------------------------------------ |
#執行go服務端
1
2
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 |
#執行打包後的java客戶端
1
2
3
4
5
6
7
|
root@m1: /home/hadoop/thrift_demo/gen-java # java -jar target/idoall.org.demo-0.0.1-SNAPSHOT-jar-with-dependencies.jar JAVAClient Call->[key:idoall value:org1] JAVAClient Call->[key:idoall value:org2] JAVAClient Call->[key:idoall value:org3] JAVAClient Call->[key:idoall value:org4] JAVAClient Call->[key:idoall value:org5] 本次呼叫用時:1408268973582-1408268973477=105毫秒 |
#檢視go服務端,可以看到資料的互動
1
2
3
4
5
6
7
8
|
root@m1: /home/hadoop/thrift_demo # go run s.go thrift server in 0.0.0.0:10086 -->from client Call: 1408268973547 java client map[a:idoall b:org1] -->from client Call: 1408268973568 java client map[b:org2 a:idoall] -->from client Call: 1408268973568 java client map[b:org3 a:idoall] -->from client Call: 1408268973568 java client map[b:org4 a:idoall] -->from client Call: 1408268973569 java client map[b:org5 a:idoall] Stduent---> id : 1111 name:student-idoall-java sex: true age:20000 |
六、擴充套件閱讀
文章中使用的程式碼提供下載,在這裡:http://pan.baidu.com/s/1dDF1rRr
---------------------------------------
博文作者:迦壹
轉載宣告:可以轉載, 但必須以超連結形式標明文章原始出處和作者資訊及版權宣告,謝謝合作!
---------------------------------------