欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

RPC框架之Thrift的入門教程

 更新時(shí)間:2023年10月07日 09:57:09   作者:愛音斯坦牛  
Thrift是一個(gè)跨語言的服務(wù)部署框架,主要用于各個(gè)服務(wù)之間的RPC通信,支持跨語言,下面小編就來和大家講講Thrift框架的具體使用,希望對大家有所幫助

前言

隨著近些年微服務(wù)的盛行,使得服務(wù)逐漸模塊化,功能化,單個(gè)服務(wù)僅僅實(shí)現(xiàn)某個(gè)特定的功能或者模塊,因此服務(wù)間的調(diào)用變得常見且頻繁,所以高性能且快速響應(yīng)的服務(wù)調(diào)用成了必須去面對的問題,傳統(tǒng)的http請求能面對跨語言的問題,但是性能遠(yuǎn)遠(yuǎn)無法達(dá)到高并發(fā)的要求,因此更偏向底層的RPC框架越來越受到青睞,像阿里的Dubbo,谷歌的gRPC,facebook的Thrift等等!本節(jié)將學(xué)習(xí)Thrift這個(gè)跨語言的Thrift RPC框架!

Thrift簡介

Thrift是一個(gè)跨語言的服務(wù)部署框架,最初由Facebook于2007年開發(fā),2008年進(jìn)入Apache開源項(xiàng)目,主要用于各個(gè)服務(wù)之間的RPC通信,支持跨語言,常用的語言比如C++, Java, Python, PHP, Ruby, Erlang, Perl, C#, JavaScript, Node.js等都支持。(博主也是一名多語言愛好者,因此對Thrift也比較感興趣,所以在后面,我也會(huì)寫java,python 的這兩種語言的RPC調(diào)用。)

IDL介紹

Thrift是一個(gè)典型的CS(客戶端/服務(wù)端)結(jié)構(gòu),客戶端和服務(wù)端可以使用不同的語言開發(fā)。既然客戶端和服務(wù)端能使用不同的語言開發(fā),那么一定就要有一種中間語言來關(guān)聯(lián)客戶端和服務(wù)端的語言,沒錯(cuò),這種語言就是IDL(Interface Description Language)。

IDL 是一種用于定義接口和數(shù)據(jù)結(jié)構(gòu)的語言,用于描述 Thrift 的服務(wù)接口和數(shù)據(jù)類型。在 Thrift 中使用的是 Thrift 自定義的 IDL 語言,它具有類似于其他接口描述語言的特性。

因此我們需要寫IDL,然后使用Thrift編譯器將IDL轉(zhuǎn)換為對應(yīng)的語言,我們開發(fā)者只需要實(shí)現(xiàn)具體的業(yè)務(wù)邏輯,無需關(guān)注底層邏輯!

IDL語法學(xué)習(xí)

在學(xué)習(xí)thrift之前,我們需要先簡單的學(xué)習(xí)一下IDL的語法,很簡單,和其他語言結(jié)構(gòu)差不多。

1.基本類型

類型解釋
bool布爾值
byte8位有符號整數(shù)
i1616位有符號整數(shù)
i3232位有符號整數(shù)
i6464位有符號整數(shù)
double64位浮點(diǎn)數(shù)
stringUTF-8編碼的字符串
binary二進(jìn)制值

2.struct結(jié)構(gòu)體

先看例子:

struct Person {  // 定義 Person 結(jié)構(gòu)體
    1: required string name;   // 姓名,必選字段
    2: required i32 age;       // 年齡,必選字段
    3: optional string sex;    // 性別,可選字段
}

如上面所示,它類似C語言的結(jié)構(gòu)體,對應(yīng)java中的Bean,其中 required 修飾的他的值初始化是必傳項(xiàng)。

3.container容器

有三種可用的容器類型:

list

元素類型為t的有序列表,允許重復(fù)。類似于java中的ArrayList。

set

元素類型為t的無序表,不允許重復(fù)。類似于java中的HashSet。

map

<t, t>鍵類型為t,值類型為t的鍵值對,鍵不允許重復(fù)。類似于java中的HashMap。

例如:

struct Test {
    1: map<string, User> usermap,
    2: set<i32> intset,
    3: list<double> doublelist
}

4.service服務(wù)

服務(wù)的定義方法在語義上等同于面向?qū)ο笳Z言中的接口。

service PersonService {  // 定義 PersonService 服務(wù)接口
    Person getByName(1: string name);  // 根據(jù)姓名獲取 Person 信息
    bool save(1: Person person);       // 保存 Person 信息
}

5.枚舉(enum)

枚舉的定義形式和Java的Enum定義差不多,例如:

enum Sex {
    MALE,
    FEMALE
}

6.異常(exception)

thrift支持自定義exception,規(guī)則和struct一樣,如下:

exception RequestException {
    1: i32 code;
    2: string reason;
}

7.命名空間

thrift的命名空間相當(dāng)于Java中的package的意思,主要目的是組織代碼。thrift使用關(guān)鍵字namespace定義命名空間,例如:

namespace java com.aniu.service
namespace py example

namespace 后跟的是你要轉(zhuǎn)化的語言以及生成的文件所在的包!

Thrift 編譯器安裝

寫完IDL文件后,我們需要將其轉(zhuǎn)換成對應(yīng)語言!因此,我們需要先安裝Thrift編譯器!這里博主用的Windows,macos和Linux自行下載!

網(wǎng)址:https://dlcdn.apache.org/thrift/0.19.0/thrift-0.19.0.exe

下載安裝完成后,配置完環(huán)境變量,如下圖,可查看版本!后續(xù)在其他語言例如java中引入maven包時(shí),需要對應(yīng)版本!

入門案例

這里編寫一個(gè)簡單的入門案例,實(shí)現(xiàn)rpc遠(yuǎn)程過程調(diào)用!定義thrift 文件 person.thrift

namespace java com.aniu.service
struct Person {  // 定義 Person 結(jié)構(gòu)體
    1: required string name;   // 姓名,必選字段
    2: required i32 age;       // 年齡,必選字段
    3: optional string sex;    // 性別,可選字段
}
service PersonService {  // 定義 PersonService 服務(wù)接口
    Person getByName(1: string name);  // 根據(jù)姓名獲取 Person 信息
    bool save(1: Person person);       // 保存 Person 信息
}

使用

thrift --gen java person.thrift

命令,即可在當(dāng)前目錄下生成gen-java目錄,里面即是生成的java代碼!

引入對應(yīng)版本的Maven包

<dependency>
    <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.19.0</version>
</dependency>

目錄結(jié)構(gòu)如下:

如上圖,Person和PersonService即為thrift編譯器將IDL轉(zhuǎn)換后生成的java代碼。

業(yè)務(wù)邏輯

PersonService里面有兩個(gè)接口,我們需要實(shí)現(xiàn)接口,在實(shí)現(xiàn)類里面寫業(yè)務(wù)邏輯。

package com.aniu.service.impl;
import com.aniu.service.Person;
import com.aniu.service.PersonService;
import org.apache.thrift.TException;
public class PersonServiceImpl implements PersonService.Iface {
    @Override
    public Person getByName(String name) throws TException {
        return new Person(name,18);
    }
    @Override
    public boolean save(Person person) throws TException {
        return false;
    }
}

服務(wù)端

package com.aniu.server;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import com.aniu.service.PersonService;
import com.aniu.service.impl.PersonServiceImpl;
public class Server {
    public static void main(String[] args) {
        try{
            // 創(chuàng)建一個(gè)新的 Thrift 服務(wù)端套接字,監(jiān)聽在端口 9000 上
            TServerSocket socket = new TServerSocket(9000);
            // 創(chuàng)建一個(gè) PersonService 的 Processor。Processor 是 Thrift 中用于處理請求的接口,它需要一個(gè)實(shí)現(xiàn)了 PersonService 接口的對象作為參數(shù)。
            PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl());
            // 創(chuàng)建一個(gè)二進(jìn)制協(xié)議工廠對象。Thrift 支持多種協(xié)議,如 TBinaryProtocol、TCompactProtocol、TJSONProtocol 等,這里選擇的是二進(jìn)制協(xié)議。
            TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
            // 創(chuàng)建一個(gè) TSimpleServer 的參數(shù)對象 args1,并將之前創(chuàng)建的套接字、Processor 和協(xié)議工廠設(shè)置為其屬性。
            TServer.Args args1 = new TSimpleServer.Args(socket);
            args1.processor(processor);
            args1.protocolFactory(factory);
            // 使用之前設(shè)置好的參數(shù)創(chuàng)建 TSimpleServer 對象
            TSimpleServer tSimpleServer = new TSimpleServer(args1);
            // 開始執(zhí)行 TSimpleServer,開始監(jiān)聽并處理客戶端的請求。
            tSimpleServer.serve();
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

客戶端

import com.aniu.service.PersonService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
public class Client {
    public static void main(String[] args) {
        try{
            // 創(chuàng)建一個(gè) Thrift 的套接字對象,連接到在本地主機(jī)(localhost)的9000端口上運(yùn)行的 Thrift 服務(wù)。
            TSocket socket = new TSocket("localhost", 9000);
            // 創(chuàng)建一個(gè)使用二進(jìn)制協(xié)議的實(shí)例,該協(xié)議用于在客戶端和服務(wù)器之間傳輸數(shù)據(jù)。
            TBinaryProtocol protocol = new TBinaryProtocol(socket);
            // 創(chuàng)建一個(gè)Thrift 客戶端實(shí)例,它使用前面創(chuàng)建的二進(jìn)制協(xié)議實(shí)例進(jìn)行通信。
            PersonService.Client client = new PersonService.Client(protocol);
            // 打開與服務(wù)器端的連接,通過客戶端對象(client)進(jìn)行遠(yuǎn)程過程調(diào)用(RPC)或其他通信操作
            socket.open();
            // RPC 調(diào)用
            Person person = client.getByName("aniu");
            System.out.println(person);
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

pom.xml

<dependencies>
    <dependency>
      <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.19.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.5</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.annotation</groupId>
      <artifactId>jakarta.annotation-api</artifactId>
      <version>1.3.5</version>
      <scope>compile</scope>
    </dependency>
</dependencies>

運(yùn)行

先啟動(dòng)服務(wù)端,再啟動(dòng)客戶端,即可實(shí)現(xiàn)RPC調(diào)用!

到此這篇關(guān)于RPC框架之Thrift的入門教程的文章就介紹到這了,更多相關(guān)RPC Thrift內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論