Thrift(一)——基本使用与概念

Apache Thrift是一个由Facebook开发的RPC框架,它提供了跨语言的通信能力。通过IDL语言定义接口,Thrift能生成不同语言的代码,简化网络通信。本文介绍了Thrift的基本使用,包括RPC概念、协议栈结构以及一个简单的Demo,涉及HelloService的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Apache Thrift是一个由Facebook开发的RPC框架,目标是尽可能高效、无缝地跨语言进行可靠、高性能的通信和数据序列化。

RPC

RPC全称为Remote Procedure Call,意为远程过程调用。
假设有两个应用A和B分别部署在两台服务器上,当应用A要调用应用B的某个方法时,因为两个应用不在同一进程中,不能够直接进行调用,那就涉及到网络传输。在A和B之间搭建一条网络通道,A将参数传给B,B接收到参数后再将方法执行结果返回给A。这个过程中涉及到很多东西,比如说Socket、多线程、网络I/O等, Thrift就是一个封装了这些技术的框架,以便开发人员进行快速开发。

跨语言

Thrift通过IDL语言(Interface Description Language,接口描述语言)来实现跨语言技术。在.thrift文件中定义接口和属性数据类型,然后利用thrift提供编译器将其生成为不同开发语言的类,以满足不同种语言的开发者。如Java、C++等。生成的类中不仅包含类的属性、接口,还有RPC协议层和传输层的实现代码。

协议栈结构

这里写图片描述
Thrift是一种C/S架构体系。code层是开发者自行实现的业务逻辑的代码,第二层是由thrift编译器自动生成的代码,主要用于数据的接收、解析、发送。
Server端接收到Client的请求之后,将请求转发给Processor进行处理。Processor负责对Client的请求进行响应,主要包括RPC请求转发、调用参数解析、业务逻辑调用、返回值写回等处理。Tprotocal及其以下是thrift的传输协议及底层I/O通信。TProtocol负责解析结构化数据,将结构化数据转化为字节流给TTransport进行传输。TTransport是与底层数据传输密切相关的传输层,负责以字节流方式接收和发送消息体,不关注是什么数据类型。底层IO负责实际的数据传输,包括socket、文件和压缩数据流等。

Demo

项目结构

这里写图片描述
Async类是异步调用,暂不用关注

Hello.thrift文件

namespace java xxx
service Hello{
    string helloString(1:string para);
    i32 helloInt(1:i32 para);
    bool helloBoolean(1:bool para);
    void helloVoid();
    string helloNull();
}

写好Hello.thrift文件后,在Hello.thrift所在目录下执行thrift命令生成相关类文件:thrift -r -gen java Hello.thrift (默认已经安装thrift环境,如要生成其他语言的类,将java换为其他语言,如c++)。然后将生成的类文件移至项目目录下。

相关依赖

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

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</dependency>

HelloServiceImpl类

package com.service;

import com.xxx.Hello;
import org.apache.thrift.TException;


public class HelloServiceImpl implements Hello.Iface {

    @Override
    public String helloString(String para) throws TException {
        System.out.println("helloString is called......");
        return "Hi," + para + "! Welcome to thrift.";
    }

    @Override
    public int helloInt(int para) throws TException {
        System.out.println("helloInt is called......");
        return para;
    }

    @Override
    public boolean helloBoolean(boolean para) throws TException {
        System.out.println("helloBoolean is called......");
        return para;
    }

    @Override
    public void helloVoid() throws TException {
        System.out.println("helloVoid is called......");
        System.out.println("Hello World!");
    }

    @Override
    public String helloNull() throws TException {
        System.out.println("helloNull is called......");
        return null;
    }
}

HelloServer类

package com.server;

import com.xxx.Hello;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import com.service.HelloServiceImpl;

public class HelloServer {

    public static void main(String[] args) {
        try {
            // 设置服务端口
            TServerSocket socket = new TServerSocket(8090);
            // 设置通信协议为二进制格式
            TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
            // 关联处理器与Hello服务的实现
            TProcessor tProcessor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());
            TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(socket);
            tArgs.processor(tProcessor);
            tArgs.protocolFactory(new TBinaryProtocol.Factory());

            // 线程池服务模型, 使用标准的阻塞式IO,预先创建一组线程处理请求
            TServer tServer = new TThreadPoolServer(tArgs);
            System.out.println("Server starting......");
            tServer.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }
    }
}

HelloClient类

package com.client;

import com.xxx.Hello;
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 HelloClient {
    public static void main(String[] args) {
        try {
            // 设置调用的服务地址为本地,端口是8090
            TTransport tTransport = new TSocket("localhost", 8090);
            tTransport.open();
            // 设置传输协议为二进制
            TProtocol protocol = new TBinaryProtocol(tTransport);
            Hello.Client client = new Hello.Client(protocol);
            // 调用服务的方法
            System.out.println(client.helloBoolean(false));
            System.out.println(client.helloInt(3));
            System.out.println(client.helloString("vi"));
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        }
    }
}

Thrift系列博客:
Thrift(一)——基本使用与概念
Thrift(二)——数据类型
Thrift(三)——传输层、协议、处理器、服务端
Thrift(四)——几种服务端类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vi_NSN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值