<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 167,  comments - 30,  trackbacks - 0

               Thrift框架調(diào)研

    簡(jiǎn)介

    Thrift是一種開(kāi)源的跨語(yǔ)言的RPC服務(wù)框架。Thrift最初由facebook公司開(kāi)發(fā)的,在2007年facebook將其提交apache基金會(huì)開(kāi)源了。對(duì)于當(dāng)時(shí)的facebook來(lái)說(shuō)創(chuàng)造thrift是為了解決facebook系統(tǒng)中各系統(tǒng)間大數(shù)據(jù)量的傳輸通信以及系統(tǒng)之間語(yǔ)言環(huán)境不同需要跨平臺(tái)的特性。所以thrift可以支持多種程序語(yǔ)言,支持的語(yǔ)言如下: 


    在多種不同的語(yǔ)言之間通信thrift可以作為二進(jìn)制的高性能的通訊中間件,支持?jǐn)?shù)據(jù)(對(duì)象)序列化和多種類型的RPC服務(wù)。Thrift是IDL(interface definition language)描述性語(yǔ)言的一個(gè)具體實(shí)現(xiàn),Thrift適用于程序?qū)Τ绦蜢o態(tài)的數(shù)據(jù)交換,需要先確定好他的數(shù)據(jù)結(jié)構(gòu),他是完全靜態(tài)化的,當(dāng)數(shù)據(jù)結(jié)構(gòu)發(fā)生變化時(shí),必須重新編輯IDL文件,代碼生成,再編譯載入的流程,跟其他IDL工具相比較可以視為是Thrift的弱項(xiàng),Thrift適用于搭建大型數(shù)據(jù)交換及存儲(chǔ)的通用工具,對(duì)于大型系統(tǒng)中的子系統(tǒng)間數(shù)據(jù)傳輸相對(duì)于JSON和xml無(wú)論在性能、傳輸大小上有明顯的優(yōu)勢(shì)。

     

    基礎(chǔ)架構(gòu)

    如下圖所示是thrift的協(xié)議棧整體的架構(gòu),thrift是一個(gè)客戶端和服務(wù)器端的架構(gòu)體系(c/s),在最上層是用戶自行實(shí)現(xiàn)的業(yè)務(wù)邏輯代碼。    第二層是由thrift編譯器自動(dòng)生成的代碼,主要用于結(jié)構(gòu)化數(shù)據(jù)的解析,發(fā)送和接收。TServer主要任務(wù)是高效的接受客戶端請(qǐng)求,并將請(qǐng)求轉(zhuǎn)發(fā)給Processor處理。Processor負(fù)責(zé)對(duì)客戶端的請(qǐng)求做出響應(yīng),包括RPC請(qǐng)求轉(zhuǎn)發(fā),調(diào)用參數(shù)解析和用戶邏輯調(diào)用,返回值寫(xiě)回等處理。從TProtocol以下部分是thirft的傳輸協(xié)議和底層I/O通信。TProtocol是用于數(shù)據(jù)類型解析的,將結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)化為字節(jié)流給TTransport進(jìn)行傳輸。TTransport是與底層數(shù)據(jù)傳輸密切相關(guān)的傳輸層,負(fù)責(zé)以字節(jié)流方式接收和發(fā)送消息體,不關(guān)注是什么數(shù)據(jù)類型。底層IO負(fù)責(zé)實(shí)際的數(shù)據(jù)傳輸,包括socket、文件和壓縮數(shù)據(jù)流等。

    協(xié)議層TProtocol:

    在傳輸協(xié)議上總體上劃分為文本(text)和二進(jìn)制(binary)傳輸協(xié)議, 為節(jié)約帶寬,提供傳輸效率,一般情況下使用二進(jìn)制類型的傳輸協(xié)議為多數(shù)。

       1>TBinaryProtocol – 二進(jìn)制編碼格式進(jìn)行數(shù)據(jù)傳輸。 

       2>TCompactProtocol – 高效的編碼方式,使用類似于protobuffer的Variable-Length Quantity (VLQ) 編碼(可以節(jié)省傳輸空間,使數(shù)據(jù)的傳輸效率更高)對(duì)數(shù)據(jù)進(jìn)行壓縮。 關(guān)于VLQ了解更多(http://en.wikipedia.org/wiki/Variable-length_quantity

       3>TJSONProtocol – 使用JSON的數(shù)據(jù)編碼協(xié)議進(jìn)行數(shù)據(jù)傳輸。 

       4>TSimpleJSONProtocol – 這種節(jié)約只提供JSON只寫(xiě)的協(xié)議,適用于通過(guò)腳本語(yǔ)言解析    

       5>TDebugProtocol – 在開(kāi)發(fā)的過(guò)程中幫助開(kāi)發(fā)人員調(diào)試用的,以文本的形式展現(xiàn)方便閱讀。

     

    傳輸層TTransport

        1>TSocket- 使用阻塞式I/O進(jìn)行傳輸,也是最常見(jiàn)的模式。 

        2>TFramedTransport- 使用非阻塞方式,按塊的大小,進(jìn)行傳輸,類似于Java中的NIO。                

        3>TFileTransport- 顧名思義按照文件的方式進(jìn)程傳輸,雖然這種方式不提供Java的實(shí)現(xiàn),但是實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單。 

        4>TMemoryTransport- 使用內(nèi)存I/O,就好比Java中的ByteArrayOutputStream實(shí)現(xiàn)。 

        5>TZlibTransport- 使用執(zhí)行zlib壓縮,不提供Java的實(shí)現(xiàn)。

        6>TNonblockingTransport-使用非阻塞方式,用于構(gòu)建異步客戶端。



      服務(wù)端類型 :

        1>TSimpleServer -  單線程服務(wù)器端使用標(biāo)準(zhǔn)的阻塞式I/O。     

        2>TThreadPoolServer -  多線程服務(wù)器端使用標(biāo)準(zhǔn)的阻塞式I/O。 

        3>TNonblockingServer – 多線程服務(wù)器端使用非阻塞式I/O,并且實(shí)現(xiàn)了Java中的NIO通道。



    數(shù)據(jù)類型

    Thrift 腳本可定義的數(shù)據(jù)類型包括以下幾種類型:

    • 基本類型:
      • bool:布爾值,true 或 false,對(duì)應(yīng) Java 的 boolean
      • byte:8 位有符號(hào)整數(shù),對(duì)應(yīng) Java 的 byte
      • i16:16 位有符號(hào)整數(shù),對(duì)應(yīng) Java 的 short
      • i32:32 位有符號(hào)整數(shù),對(duì)應(yīng) Java 的 int
      • i64:64 位有符號(hào)整數(shù),對(duì)應(yīng) Java 的 long
      • double:64 位浮點(diǎn)數(shù),對(duì)應(yīng) Java 的 double
      • string:未知編碼文本或二進(jìn)制字符串,對(duì)應(yīng) Java 的 String
    • 結(jié)構(gòu)體類型:
      • struct:定義公共的對(duì)象,類似于 C 語(yǔ)言中的結(jié)構(gòu)體定義,在 Java 中是一個(gè) JavaBean
    • 容器類型:
      • list:對(duì)應(yīng) Java 的 ArrayList
      • set:對(duì)應(yīng) Java 的 HashSet
      • map:對(duì)應(yīng) Java 的 HashMap
    • 異常類型:
      • exception:對(duì)應(yīng) Java 的 Exception
    • 服務(wù)類型:service:對(duì)應(yīng)服務(wù)的類

    安裝使用

    在Windows下安裝前需要很多依賴包的安裝,比較麻煩。下面介紹了在Linux下的源碼安裝,直接wget或手動(dòng)下載最tar.gz安裝包編譯安裝:

    tar -xvf thrift-0.9.1.tar.gz

    cd thrift-0.9.1

    ./configure

    make 

    make install

    使用命令thrift -version,顯示Thrift version 0.9.1 則表示安裝成功。

    我們使用到了java,所以通過(guò)ant方式構(gòu)建thrift相關(guān)lib包,進(jìn)入$THRIFT_HOME/lib/java目錄下,在ant編譯libthrift出現(xiàn)了如下問(wèn)題

    Buildfile: /letv/apps_install/thrift-0.9.1/lib/java/build.xml 

    setup.init: 

    mvn.ant.tasks.check: 

    proxy: 

    mvn.ant.tasks.download: 
    [get] Getting: http://repo1.maven.org/maven2/org/apache/maven/maven-ant-tasks/2.1.3/maven-ant-tasks-2.1.3.jar 
    [get] To: /letv/apps_install/thrift-0.9.1/lib/java/build/tools/maven-ant-tasks-2.1.3.jar 
    [get] Not modified - so not downloaded 

    mvn.init: 
    Unable to obtain resource from /letv/apps_install/thrift-0.9.1/lib/java/build/tools/maven-ant-tasks-2.1.3.jar: java.util.zip.ZipException: error in opening zip file
    [typedef] Unable to obtain resource from /letv/apps_install/thrift-0.9.1/lib/java/build/tools/maven-ant-tasks-2.1.3.jar: 
    [typedef] java.util.zip.ZipException: error in opening zip file 
    [typedef] at java.util.zip.ZipFile.open(Native Method) 
    [typedef] at java.util.zip.ZipFile.<init>(ZipFile.java:214) 
    [typedef] at java.util.zip.ZipFile.<init>(ZipFile.java:144) 
    [typedef] at java.util.jar.JarFile.<init>(JarFile.java:153) 
    [typedef] at java.util.jar.JarFile.<init>(JarFile.java:117) 
    [typedef] at org.apache.tools.ant.AntClassLoader.getResourceURL(AntClassLoader.java:1014) 
    [typedef] at org.apache.tools.ant.AntClassLoader$ResourceEnumeration.findNextResource(AntClassLoader.java:150) 
    [typedef] at org.apache.tools.ant.AntClassLoader$ResourceEnumeration.<init>(AntClassLoader.java:111) 
    [typedef] at org.apache.tools.ant.AntClassLoader.findResources(AntClassLoader.java:954) 
    [typedef] at org.apache.tools.ant.AntClassLoader.getNamedResources(AntClassLoader.java:923) 
    [typedef] at org.apache.tools.ant.loader.AntClassLoader5.getResources(AntClassLoader5.java:58) 
    [typedef] at org.apache.tools.ant.taskdefs.Definer.resourceToURLs(Definer.java:360) 
    [typedef] at org.apache.tools.ant.taskdefs.Definer.execute(Definer.java:246) 
    [typedef] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) 
    [typedef] at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) 
    [typedef] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    [typedef] at java.lang.reflect.Method.invoke(Method.java:601) 
    [typedef] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) 
    [typedef] at org.apache.tools.ant.Task.perform(Task.java:348) 
    [typedef] at org.apache.tools.ant.Target.execute(Target.java:435) 
    [typedef] at org.apache.tools.ant.Target.performTasks(Target.java:456) 
    [typedef] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) 
    [typedef] at org.apache.tools.ant.Project.executeTarget(Project.java:1364) 
    [typedef] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) 
    [typedef] at org.apache.tools.ant.Project.executeTargets(Project.java:1248) 
    [typedef] at org.apache.tools.ant.Main.runBuild(Main.java:851) 
    [typedef] at org.apache.tools.ant.Main.startAnt(Main.java:235) 
    [typedef] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) 
    [typedef] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) 
    [typedef] Could not load definitions from resource org/apache/maven/artifact/ant/antlib.xml. It could not be found. 

    BUILD FAILED 
    /letv/apps_install/thrift-0.9.1/lib/java/build.xml:279: Problem: failed to create task or type antlib:org.apache.maven.artifact.ant:remoteRepository 
    Cause: The name is undefined. 
    Action: Check the spelling. 
    Action: Check that any custom tasks/types have been declared. 
    Action: Check that any <presetdef>/<macrodef> declarations have taken place. 
    No types or tasks have been defined in this namespace yet 

    This appears to be an antlib declaration. 
    Action: Check that the implementing library exists in one of: 
    -/letv/apps_install/apache-ant-1.9.4/lib 
    -/root/.ant/lib 
    -a directory added on the command line with the -lib argument 


    Total time: 2 seconds

    解決方法:ant通過(guò)yum方式安裝,默認(rèn)版本1.7.1,自行安裝最新版本1.9.4,成功編譯后在當(dāng)前目錄生成了build文件夾,包括libthrift-0.9.1.jar以及依賴的lib:

    commons-codec-1.6.jar
    commons-lang3-3.1.jar
    commons-logging-1.1.1.jar
    httpclient-4.2.5.jar
    httpcore-4.2.4.jar
    junit-4.4.jar
    log4j-1.2.14.jar
    servlet-api-2.5.jar
    slf4j-api-1.5.8.jar
    slf4j-log4j12-1.5.8.jar

    u 開(kāi)發(fā)流程及代碼示例

    1,編寫(xiě)IDL文件helloService.thrift,如下:

    /**

     * Hello world Testing

     *

     */

    namespace java com.le.mms

    service HelloService {

        i32 sayInt(1:i32 param)

        string sayString(1:string param)

        bool sayBoolean(1:bool param)

        void sayVoid()

    }

    2. 使用thrift編譯器生成所需語(yǔ)言的代碼

    thrift --gen java helloService.thrift

    在當(dāng)前目錄下生成gen-java目錄,里面生成了HelloService.java文件。

    Thrift --gen py helloService.thrift 可以生成python相關(guān)代碼。

     

    3. 新建Java工程或maven工程,java工程引入ant生成的lib,maven工程pom.xml中引入依賴。

       <dependency>

          <groupId>org.apache.thrift</groupId>

          <artifactId>libthrift</artifactId>

          <version>0.9.1</version>

        </dependency>

    自動(dòng)會(huì)將依賴的lib下載下來(lái)。

    4. 編寫(xiě)HelloServiceImpl.java業(yè)務(wù)實(shí)現(xiàn)類. 需要實(shí)現(xiàn)HelloService.Iface接口,由thrift自動(dòng)生成的代碼。 

    package com.le.mms.thrift; 

    import org.apache.thrift.TException;

    public class HelloServiceImpl implements HelloService.Iface{

        @Override

        public int sayInt(int param) throws TException {

            System.out.println("say int :" + param);

            return param;

        }

        @Override

        public String sayString(String param) throws TException {

            System.out.println("say string :" + param);

            return param;

        }

        @Override

        public boolean sayBoolean(boolean param) throws TException {

            System.out.println("say boolean :" + param);

            return param;

        }

        @Override

        public void sayVoid() throws TException {

            System.out.println("say void ...");

        }

    }

     

    5. 編寫(xiě)thrift-java服務(wù)器端,監(jiān)聽(tīng)端口9090

    package com.le.mms.thrift.server;

    import org.apache.thrift.protocol.TBinaryProtocol;

    import org.apache.thrift.protocol.TBinaryProtocol.Factory;

    import org.apache.thrift.server.TServer;

    import org.apache.thrift.server.TSimpleServer;

    import org.apache.thrift.transport.TServerSocket;

    import org.apache.thrift.transport.TTransportException;

    import com.le.mms.thrift.HelloService;

    import com.le.mms.thrift.HelloServiceImpl;

    import com.le.mms.thrift.HelloService.Processor;

    /**

     * 啟動(dòng)thrift的java服務(wù)器端

     *

     * @author david

     *

     */

    public class HelloServiceServer {

       

        public static void main(String[] args) {

            try {

                // 設(shè)置服務(wù)器端口

                TServerSocket serverTransport = new TServerSocket(9090);

                // 設(shè)置二進(jìn)制協(xié)議工廠

                Factory protocolFactory = new TBinaryProtocol.Factory();

                //處理器關(guān)聯(lián)業(yè)務(wù)實(shí)現(xiàn)

                Processor<HelloService.Iface> processor = new HelloService.Processor<HelloService.Iface>(new HelloServiceImpl());

                // 1. 使用單線程標(biāo)準(zhǔn)阻塞I/O模型

                TServer.Args simpleArgs = new TServer.Args(serverTransport);

                simpleArgs.processor(processor);

                simpleArgs.protocolFactory(protocolFactory);

                TServer server = new TSimpleServer(simpleArgs);

                // 2. 使用線程池服務(wù)模型

    //            TThreadPoolServer.Args poolArgs = new TThreadPoolServer.Args(serverTransport);

    //            poolArgs.processor(processor);

    //            poolArgs.protocolFactory(protocolFactory);

    //            TServer poolServer = new TThreadPoolServer(poolArgs);

    //            poolServer.serve();

                System.out.println("開(kāi)啟thrift服務(wù)器,監(jiān)聽(tīng)端口:9090");

                server.serve();

            } catch (TTransportException e) {

                e.printStackTrace();

            }

        }

    }

     

    6.編寫(xiě)thrift-java客戶端,發(fā)出請(qǐng)求。

    package com.le.mms.thrift.client;

    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 org.apache.thrift.transport.TTransportException;

    import com.le.mms.thrift.HelloService; 

    /**

     * 調(diào)用thrift的java客戶端

     *

     * @author david

     *

     */

    public class HelloServiceClient {

       

        public static void main(String[] args) {

            try {

                // 設(shè)置調(diào)用的服務(wù)地址-端口

                TTransport transport = new TSocket("localhost", 9090);

                //  使用二進(jìn)制協(xié)議

                TProtocol protocol = new TBinaryProtocol(transport);

                // 使用的接口

                HelloService.Client client = new HelloService.Client(protocol);

                //打開(kāi)socket

                transport.open();

                client.sayBoolean(true);

                client.sayString("Hello world");

                client.sayInt(20141111);

                client.sayVoid();

                transport.close();

            } catch (TTransportException e) {

                e.printStackTrace();

            } catch (TException te) {

                te.printStackTrace();

            }

        }

    }

    以上編寫(xiě)完了server和client端代碼,運(yùn)行server開(kāi)啟監(jiān)聽(tīng)。然后運(yùn)行client就能夠與server端進(jìn)行rpc調(diào)用方式的通訊了。


    posted on 2014-12-03 23:56 David1228 閱讀(28338) 評(píng)論(0)  編輯  收藏 所屬分類: JAVAJ2EE

    <2014年12月>
    30123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    文章檔案

    新聞分類

    新聞檔案

    相冊(cè)

    收藏夾

    Java

    Linux知識(shí)相關(guān)

    Spring相關(guān)

    云計(jì)算/Linux/虛擬化技術(shù)/

    友情博客

    多線程并發(fā)編程

    開(kāi)源技術(shù)

    持久層技術(shù)相關(guān)

    搜索

    •  

    積分與排名

    • 積分 - 358542
    • 排名 - 154

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 84pao强力永久免费高清| 成年女人男人免费视频播放| 性色av免费观看| 伊人久久大香线蕉亚洲| 中文字幕在线观看亚洲视频| www.xxxx.com日本免费| 日本一区二区三区免费高清| 亚洲精品一品区二品区三品区| 亚洲人成电影网站久久| 国产啪精品视频网站免费尤物| 免费无码又爽又刺激高潮的视频| 久久精品国产精品亚洲色婷婷 | 久久精品国产精品亚洲色婷婷| 亚洲人成人伊人成综合网无码| 毛片在线全部免费观看| 国产免费av一区二区三区| 91亚洲国产在人线播放午夜 | 一边摸一边桶一边脱免费视频| 五月婷婷综合免费| 亚洲精品蜜桃久久久久久| 亚洲av成人片在线观看| 亚洲人成免费电影| 亚洲码国产精品高潮在线| 蜜臀亚洲AV无码精品国产午夜.| 亚洲啪啪免费视频| 亚洲精品一品区二品区三品区| 久久精品国产亚洲av瑜伽| 最近在线2018视频免费观看| 亚洲乱码精品久久久久..| 色九月亚洲综合网| 免费看国产成年无码AV片| 亚洲另类激情综合偷自拍| 国产精品午夜免费观看网站| 麻豆国产人免费人成免费视频| 亚洲精品韩国美女在线| 免费人成激情视频在线观看冫| 波多野结衣中文一区二区免费| 亚洲自偷自偷在线成人网站传媒 | 亚洲一卡二卡三卡四卡无卡麻豆| 成人无码a级毛片免费| 亚洲欧洲久久av|