問題導讀:
什麼是Thrift?
Thrift的官方網站在哪裏?
Golang、Java、Python、PHP之間如何經過Thrift實現跨語言調用?

1、什麼是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
2、Thrift的官方網站在哪裏?
http://thrift.apache.org/
3、在哪裏下載?須要哪些組件的支持?
Thrift的官方下載地址在這裏:http://www.apache.org/dyn/closer ... 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
4、如何安裝?
1) 安裝依賴插件
php
- 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服務端的交互)html
- #先添加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 Sury」已導入
- 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版本java
- 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) 編譯安裝python
- 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的時候帶上如下參數git
- ./configure --without-php --without-ruby --without-haskell --without-python --without-perl
複製代碼
繼續安裝這個時間會長一點github
- root@m2:/home/hadoop/thrift-git# make
- root@m2:/home/hadoop/thrift-git# make install
複製代碼
咱們能夠看到thrift已經安裝完成,當前版本是0.9.1golang
- root@m1:/home/hadoop/thrift-git# thrift -version
- Thrift version 0.9.1
複製代碼
5、Golang、Java、Python、PHP之間經過Thrift實現跨語言調用
在寫代碼以前,咱們先來配置Thrift的協議庫IDL文件:數據庫
- 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文件,生成相關代碼apache
- 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選項,以下:編程
- root@m1:/home/hadoop/thrift-git/tutorial# thrift -r --gen php:server idoall.org.thrift
複製代碼
1) Golang 客戶端和服務端的實現及交互
Golang1.3的安裝,請參考這篇文章《ubuntu12.04 64bit基於源碼安裝golang1.3》,默認使用apt-get安裝不是最新版。
#安裝golang的Thrift包:
- root@m1:/home/hadoop/thrift-git/tutorial# go get git.apache.org/thrift.git/lib/go/thrift
複製代碼
#將Thrift生成的開發庫也複製到GOPATH中
- 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目錄中進行演示)
- root@m1:/home/hadoop# mkdir thrift_demo
- root@m1:/home/hadoop# cd thrift_demo/
- root@m1:/home/hadoop/thrift_demo# vi s.go
複製代碼
- 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端代碼
- 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端口)
- root@m1:/home/hadoop/thrift_demo# go run s.go
- thrift server in 0.0.0.0:10086
複製代碼
#運行go客戶端
- 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服務端,能夠看到數據的交互
- 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裏面
- 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代碼
- 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服務端
- root@m1:/home/hadoop/thrift_demo# go run s.go
- thrift server in 0.0.0.0:10086
複製代碼
#運行python客戶端
- 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服務端,能夠看到數據的交互
- 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擴展
- 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,保存退出。
- 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
- 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裏面
- 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端代碼
- 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服務端
- root@m1:/home/hadoop/thrift_demo# go run s.go
- thrift server in 0.0.0.0:10086
複製代碼
#運行php客戶端
- 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服務端,能夠看到數據的交互
- 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項目管理工具
- root@m1:/home/hadoop/thrift_demo# apt-get install maven
複製代碼
#將java用到的Thrift包複製到thrift_demo裏面
- 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端代碼
- 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文件
- 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
- 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
- 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服務端
- root@m1:/home/hadoop/thrift_demo# go run s.go
- thrift server in 0.0.0.0:10086
複製代碼
#運行打包後的java客戶端
- 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服務端,能夠看到數據的交互
- 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
複製代碼
<ignore_js_op>
thrift_demo.tar.gz (1.18 MB, 下載次數: 1)