Thrift入門及Java實例(一)

一、前言

公司一直用thrift作爲服務化端的編寫,實現java與php的對接,一直以來都用覺得還是可以,這裏分享給大家希望大家喜歡這個工具。

Thrift是一個軟件框架,用來進行可擴展且跨語言的服務的開發。它結合了功能強大的軟件堆棧和代碼生成引擎,以構建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等編程語言間無縫結合的、高效的服務。

二、Thrift基礎

我們使用thrift需要的思路爲如下圖

我們建立thrift定義服務化接口,作爲服務端與客戶端都需要引入jar或者文件,通過thrift特點的服務與客戶端即可以完成接口調用。

2.1 Thrift項目搭建

2.1.1 引入jar包

搭建項目第一步在pom文件,如果還沒使用maven的同學估計可以掛了,現在基本已經沒得用原生jar文件的了。
其中只有lib thrift的包爲官方,下面的日誌包爲搭配。
<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>com.ycy</groupId>
    <artifactId>thriftTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>thriftTest</name>
    <url>http://maven.apache.org</url>

    <dependencies>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.12</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
</project>

2.1.2 寫thrift 文件


整個項目文件:
1、defin目錄:自己定義專門存放我們的thrift文件
2、src文件:專門存放java文件
3、php文件:專門存放php文件(未建立)
我們首先看看thrift文件:HelloWorldService.thrift
namespace * com.ycy.interfaces
/**
* 測試接口sayhello
**/
service  HelloWorldService {
  /**
  * sayhello
  * Parmas:
  * username:用戶名
    **/
  string sayHello(1:string username),
}
註釋:編寫thrift文件之簡單,我們可以看到。例子裏面我寫了一個藉口爲sayHello的接口。
爲防止不會寫thrift的小夥伴我把thrift的基本類型寫一下:很少的哦,如果會使用其他編程語言一眼就該知道是什麼意思
1.基本類型(括號內爲對應的Java類型):
bool(boolean): 布爾類型(TRUE or FALSE)
byte(byte): 8位帶符號整數
i16(short): 16位帶符號整數
i32(int): 32位帶符號整數
i64(long): 64位帶符號整數
double(double): 64位浮點數
string(String): 採用UTF-8編碼的字符串

2.特殊類型(括號內爲對應的Java類型):
binary(ByteBuffer):未經過編碼的字節流

3.Structs(結構):
struct定義了一個很普通的OOP對象,但是沒有繼承特性。

2.1.3 生成java文件

生成java文件與php文件都一眼,我們例子裏面只展示使用java文件。
首先我們需要下載好thrift文件的執行程序:
windows:下載exe 
mac:brewhome裏面下載thrift   
linux:下載thrift(不懂得進入羣諮詢我,謝謝!)
window環境具體步驟
<pre name="code" class="plain">  1)安裝thrift:到thrift官網下載exe文件,然後將文件重命名爲thrift.exe,拷貝到c:\windows目錄下(或者任何目錄下),然後就可以在dos環境下使用了
c:\windows>thrift -gen java D:\mywork\javaProject\thriftTest\test.thrift ,輸出的java文件默認輸出到當前目錄下c:\windows,也可以使用-o參數指定輸出路徑
    1,首先得有一個thrift.exe (必須下載)
    2,其次寫一個協議文件:helloWorldService.thrift(上面已經編寫) 
    3,將<span style="font-family: Arial, Helvetica, sans-serif;">helloWorldService.thrift</span>文件放到有thrift.exe的目錄下 
    4,運行命令:thrift -r -gen java <span style="font-family: Arial, Helvetica, sans-serif;">helloWorldService.thrift</span>, 生成gen-java目錄 
    5,將生成的java代碼,拷貝到java項目中,注意:包名必須一致。 
    6,在java代碼中,寫一個類,繼承生成的Thrift服務監聽類。 
    7,向繼承的監聽類發送Thrift請求。



mac環境具體步驟
brew install thrift
然後進入我們項目定義define目錄執行命令 
    1,運行命令:thrift -r -gen java helloWorldService.thrift, 生成gen-java目錄 
    2,將生成的java代碼,拷貝到java項目中,注意:包名必須一致。 
    3,在java代碼中,寫一個類,繼承生成的Thrift服務監聽類。 
    4,向繼承的監聽類發送Thrift請求。

2.1.4 生成項目

執行thrift命令之後,我們的項目如下。然後執行mvn clean install 將項目打包即可生成jar包,以供其他項目使用。


2.2 java端調用

java項目需要引入如上jar包,php項目需要引入上面生成文件。
項目整體

2.2.1 實現接口

package com.ycy;

import com.ycy.interfaces.HelloWorldService;

/**
 * Created by ycy on 16/3/3.
 */
public class HelloWorldServiceImpl implements HelloWorldService.Iface {

    public String sayHello(String s) {
        return "hello" + s;
    }
}

2.2.1 服務端

package com.ycy.server;

import com.ycy.HelloWorldServiceImpl;
import com.ycy.interfaces.HelloWorldService;
import org.apache.thrift.TProcessor;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.protocol.TBinaryProtocol;


/**
 * Created by ycy on 16/3/3.
 */
public class ServerMain {
    public static void main(String[] args) {
        try {
            TProcessor processor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());
            //設置服務器端口爲7911
            TServerSocket serverTransport = new TServerSocket(7911);
            //設置協議工廠爲TBinaryProtocol.Factory
            Factory proFactory = new TBinaryProtocol.Factory();
            TServer.Args tArgs = new TServer.Args(serverTransport);
            tArgs.processor(processor);
            tArgs.protocolFactory(proFactory);
            //使用TSimpleServer
            TServer server = new TSimpleServer(tArgs);
            System.out.println("Start server on port 7911....");
            server.serve();


        } catch (Exception x) {
            x.printStackTrace();
        }
        System.out.println("done.");
    }
}

2.2.2 客戶端

package com.ycy.client;

/**
 * Created by ycy on 16/3/3.
 */
import com.ycy.interfaces.HelloWorldService;
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;

public class ClientMain {
    /**
     * 調用Hello服務
     * @param args
     */
    public static void main(String[] args) {
        try {
            //設置調用的服務器爲本地,端口爲7911
            TTransport transport = new TSocket("localhost", 7911);
            transport.open();
            //設置傳輸協議爲TBinaryProtocol
            TProtocol protocol = new TBinaryProtocol(transport);
            HelloWorldService.Client client = new HelloWorldService.Client(protocol);
            System.out.println(client.sayHello("mnin"));  ;
            transport.close();

        } catch (TTransportException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}


2.2.3 測試結果




三、總結與序章


這一篇我們講訴了使用thrift的基本用法,其實很簡單,原理更簡單。thrift就是使用thrift作爲媒介,各個調用的接口都可以讀取socket的數據,或者監控客戶端以供數據。
但是很多人會發現,就這個客戶端與服務端起雞毛作用啊,根本就是socket的嘛。在項目實際運用中怎麼玩耍呢,接下來我將會講解怎麼正在封裝使用thrift,作爲接口使用。一般互聯網公司都這麼玩耍。下一章節,講訴。
兩個項目的代碼在git上面可以下載::  https://github.com/yangchangyong0


發佈了81 篇原創文章 · 獲贊 47 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章