Thrift RPC Java、Go、PHP使用例子

文章目录

    • 1、Thrift RPC介绍
      • 1.1、Protocol 支持的数据传输协议
      • 1.2、Transport 支持的数据传输方式
      • 1.3、Server 支持的服务模型
      • 1.4、IDL语法数据类型
      • 1.5、开发步骤
    • 2、接口定义文件
      • 2.1、创建接口定义文件
      • 2.2、生成对应平台语言代码
        • 2.2.1、下载生成工具
        • 2.2.2、生成各平台语言代码
    • 3、使用Java实现服务器端
    • 4、客户端实现
      • 4.1、Java调用客户端实现
      • 4.2、Go调用客户端实现
      • 4.3、PHP调用客户端实现

1、Thrift RPC介绍

Thrift 是一个软件框架(远程过程调用框架),用来进行可扩展且跨语言的服务的开发,封装了数据传输格式(二进制、json)和网络通信的服务框架,提供多语言(C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml)的网络服务器端和客户端程序组件
适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输相对于 JSON 和 xml 无论在性能、传输大小上有明显的优势。

Thrift 开发的几个概念:
Server 服务模型
Handler 数据处理接口
Processor 数据处理对象
Protocol 数据传输协议
Transport 数据传输方式

1.1、Protocol 支持的数据传输协议

  1. TBinaryProtocol – 二进制格式.
  2. TCompactProtocol – 压缩格式
  3. TJSONProtocol – JSON 格式
  4. TSimpleJSONProtocol –提供 JSON 只写协议,生成的文件很容易通过脚本语言解析。
  5. TDebugProtocol – 使用易懂的可读的文本格式,以便于 debug

1.2、Transport 支持的数据传输方式

  1. TFileTransport:文件(日志)传输类,允许 client 将文件传给 server,允许 server 将收到的数据写到文件中。
  2. THttpTransport:采用 Http 传输协议进行数据传输
  3. TSocket:采用 TCP Socket 进行数据传输
  4. TZlibTransport:压缩后对数据进行传输,或者将收到的数据解压

下面几个类主要是对上面几个类地装饰(采用了装饰模式),以提高传输效率。

TBufferedTransport:对某个 Transport 对象操作的数据进行 buffer,即从 buffer 中读取数据进行传输,或者将数据直接写入 buffer

TFramedTransport:以 frame 为单位进行传输,非阻塞式服务中使用。同 TBufferedTransport 类似,也会对相关数据进行 buffer,同时,它支持定长数据发送和接收。

TMemoryBuffer:从一个缓冲区中读写数据

1.3、Server 支持的服务模型

TSimpleServer – 简单的单线程服务模型,常用于测试
TThreadedServer - 多线程服务模型,使用阻塞式 IO,每个请求创建一个线程。
TThreadPoolServer – 线程池服务模型,使用标准的阻塞式 IO,预先创建一组线程处理请求。
TNonblockingServer – 多线程服务模型,使用非阻塞式 IO(需使用 TFramedTransport 数据传输方式)

处理大量更新的话,主要是在 TThreadedServer 和 TNonblockingServer 中进行选择。TNonblockingServer 能够使用少量线程处理大量并发连接,但是延迟较高;TThreadedServer 的延迟较低。实际中,TThreadedServer 的吞吐量可能会比 TNonblockingServer 高,但是 TThreadedServer 的 CPU 占用要比 TNonblockingServer 高很多。

1.4、IDL语法数据类型

  • 基本类型
bool:布尔值(true或false)
byte:8位有符号整数
i16:16位有符号整数
i32:32位有符号整数
i64:64位有符号整数
double:64位浮点数
string:使用UTF-8编码编码的文本字符串
  • 容器类型
list<t1>:一系列t1类型的元素组成的有序列表,元素可以重复
set<t1>:一些t1类型的元素组成的无序集合,元素唯一不重复
map<t1,t2>:key/value对,key唯一

1.5、开发步骤

服务器端开发:

1. 创建 Handler
2. 基于 Handler 创建 Processor
3. 创建 Transport(通信方式)
4. 创建 Protocol 方式(设定传输格式)
5. 基于 Processor, Transport 和 Protocol 创建 Server
6. 运行 Server

客户端开发:

1. 创建 Transport
2. 创建 Protocol 方式
3. 基于 Transport 和 Protocol 创建 Client
4. 运行 Client 的方法

2、接口定义文件

2.1、创建接口定义文件

test.thrift

/*** The first thing to know about are types. The available types in Thrift are:**  bool        Boolean, one byte*  byte        Signed byte*  i16         Signed 16-bit integer*  i32         Signed 32-bit integer*  i64         Signed 64-bit integer*  double      64-bit floating point value*  string      String*  binary      Blob (byte array)*  map<t1,t2>  Map from one type to another*  list<t1>    Ordered list of one type*  set<t1>     Set of unique elements of one type** Did you also notice that Thrift supports C style comments?*/// 命名空间,Java中的package
namespace java com.penngo.thrift
namespace php com.penngo
namespace go com.penngo// 结构体
struct User {1: i64 id,2: string name,3: string password
}// 服务,Java中创建Interface一样
service LoginService{// service中定义的函数,相当于Java interface中定义的函数User login(1:string name, 2:string psw);
}service RegisterService{User createUser(1:string name, 2:string psw);
}

2.2、生成对应平台语言代码

2.2.1、下载生成工具

下载地址:https://thrift.apache.org/download
当前最新版本为:thrift-0.19.0.exe
thrift-0.19.0.exe重命名为thrift.exe,与test.thrift在同一目录。

2.2.2、生成各平台语言代码

执行以下命令分别生成Java、Go、PHP平台的代码

thrift -gen java test.thrift
thrift -gen go test.thrift
thrift -gen php:classmap test.thrift # 支持PSR-4 loader 
# thrift -gen php test.thrift

生成后的目录文件结构
在这里插入图片描述

3、使用Java实现服务器端

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.penngo</groupId><artifactId>thrift-java</artifactId><version>1.0</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.19.0</version></dependency><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.17.2</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.36</version></dependency></dependencies><repositories><repository><id>alimaven</id><name>Maven Aliyun Mirror</name><url>https://maven.aliyun.com/repository/central</url></repository></repositories><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/nexus/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories>
</project>

实现LoginService服务LoginServiceImpl.java

package com.penngo.service;import com.penngo.thrift.LoginService;
import com.penngo.thrift.User;public class LoginServiceImpl implements LoginService.Iface{public LoginServiceImpl(){}public User login(String name, String psw){User user = null;if(name.equals("penngo") && psw.equals("123")){user = new User();user.setId(1);user.setName("penngo");}return user;}
}

实现RegisterService服务RegisterServiceImpl.java

package com.penngo.service;
import com.penngo.thrift.RegisterService;
import com.penngo.thrift.User;public class RegisterServiceImpl implements RegisterService.Iface{public RegisterServiceImpl(){}public User createUser(String name, String psw){User user = new User();user.setId(2);user.setName(name);user.setPassword(psw);return user;}
}

实现LoginService和RegisterService注册,完成服务启动。

package com.penngo;import com.penngo.service.LoginServiceImpl;
import com.penngo.service.RegisterServiceImpl;
import com.penngo.thrift.LoginService;
import com.penngo.thrift.RegisterService;
import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;public class HelloServer {private void start() {try {TServerSocket serverTransport = new TServerSocket(7911);// 用户登录LoginService.Processor loginProcessor = new LoginService.Processor(new LoginServiceImpl());// 用户注册RegisterService.Processor registerProcessor = new RegisterService.Processor(new RegisterServiceImpl());TMultiplexedProcessor processor = new TMultiplexedProcessor();processor.registerProcessor("LoginService", loginProcessor);processor.registerProcessor("RegisterService", registerProcessor);TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));System.out.println("Starting server on port 7911 ...");server.serve();} catch (TTransportException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}public static void main(String args[]) {HelloServer srv = new HelloServer();srv.start();}
}

项目文件结构
在这里插入图片描述

4、客户端实现

4.1、Java调用客户端实现

package com.penngo;import com.penngo.thrift.LoginService;
import com.penngo.thrift.RegisterService;
import com.penngo.thrift.User;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TMultiplexedProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;public class HelloClient {public static void main(String[] args) {try {TTransport transport = new TSocket("localhost", 7911);TProtocol protocol = new TBinaryProtocol(transport);TMultiplexedProtocol mp1 = new TMultiplexedProtocol(protocol,"LoginService");LoginService.Client loginClient = new LoginService.Client(mp1);TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol,"RegisterService");RegisterService.Client registerClient = new RegisterService.Client(mp2);transport.open();User user = loginClient.login("penngo", "123");if (user != null) {System.out.println("登录成功:" + user.getId() + " "+ user.getName());} else {System.out.println("登录失败");}User user2 = registerClient.createUser("test", "123456");if (user2 != null) {System.out.println("创建用户成功:" + user2.getId() + " "+ user2.getName());} else {System.out.println("创建用户失败");}transport.close();} catch (TException x) {x.printStackTrace();}}
}

4.2、Go调用客户端实现

安装Thrift依赖

go get github.com/apache/thrift

go客户端实现

package mainimport ("context""crypto/tls""fmt""github.com/apache/thrift/lib/go/thrift""net""os""thrifttest/com/penngo"
)const (HOST = "127.0.0.1"PORT = "7911"
)var ctx = context.Background()func main() {cfg := &thrift.TConfiguration{TLSConfig: &tls.Config{InsecureSkipVerify: true,}}// 网络接口var transport thrift.TTransportvar err errortransport = thrift.NewTSocketConf(net.JoinHostPort(HOST, PORT), cfg)protocol := thrift.NewTBinaryProtocolConf(transport, cfg)// 客户端iprot := thrift.NewTMultiplexedProtocol(protocol, "LoginService")oprot := thrift.NewTMultiplexedProtocol(protocol, "LoginService")c := thrift.NewTStandardClient(iprot, oprot)loginClient := penngo.NewLoginServiceClient(c)// 客户端iprot2 := thrift.NewTMultiplexedProtocol(protocol, "RegisterService")oprot2 := thrift.NewTMultiplexedProtocol(protocol, "RegisterService")c2 := thrift.NewTStandardClient(iprot2, oprot2)registerClient := penngo.NewRegisterServiceClient(c2)if err := transport.Open(); err != nil {fmt.Fprintln(os.Stderr, "open transport error: ", err)os.Exit(1)}defer transport.Close()res, err := loginClient.Login(ctx, "penngo", "123")if err != nil {fmt.Fprintln(os.Stderr, "======error: ", err)os.Exit(1)}fmt.Fprintln(os.Stderr, "Login=====: ", res)res2, err2 := registerClient.CreateUser(ctx, "test", "123456")if err2 != nil {fmt.Fprintln(os.Stderr, "======error: ", err2)os.Exit(1)}fmt.Fprintln(os.Stderr, "CreateUser=====: ", res2)
}

项目文件结构
在这里插入图片描述

官方例子:https://thrift.apache.org/tutorial/go.html

4.3、PHP调用客户端实现

创建composer.json

{"require": {"apache/thrift": "^0.19.0"},"autoload": {"files": ["com/penngo/LoginService.php","com/penngo/RegisterService.php","com/penngo/Types.php"]}
}

使用composer安装依赖

composer install

php客户端实现代码

<?php
require_once 'vendor/autoload.php';use Thrift\Transport\TSocket;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TBufferedTransport;
use Thrift\Protocol\TMultiplexedProtocol;
use com\penngo\LoginServiceClient;
use com\penngo\RegisterServiceClient;// 传输方式(需与服务端一致)
$socket = new TSocket("localhost", 7911);
// 传输协议(需与服务端一致)
$transport = new TBufferedTransport($socket, 1024, 1024);
$protocol = new TBinaryProtocol($transport);
$loginProtocol = new TMultiplexedProtocol($protocol, "LoginService");
$registerProtocol = new TMultiplexedProtocol($protocol, "RegisterService");
$loginClient = new LoginServiceClient($loginProtocol);
$registerClient = new RegisterServiceClient($registerProtocol);
$transport->open();
$user = $loginClient->login('penngo', '123');
print "login====".json_encode($user);$user = $registerClient->createUser('test', '123456');
print "\ncreateUser====".json_encode($user);
$transport->close();

项目文件结构
在这里插入图片描述

php官方例子:https://thrift.apache.org/lib/php.html

附件源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/183335.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android系统分析

Android工程师进阶第八课 AMS、WMS和PMS 一、Binder通信 【Android Framework系列】第2章 Binder机制大全_android binder-CSDN博客 Android Binder机制浅谈以及使用Binder进行跨进程通信的俩种方式&#xff08;AIDL以及直接利用Binder的transact方法实现&#xff09;_bind…

基于web宠颐生宠物医院系统设计与实现

基于web宠颐生医院系统开发与实现 摘要&#xff1a;时代飞速发展&#xff0c;网络也飞速发展&#xff0c;互联网许多的行业都可以用互联网实现了&#xff0c;互联网已经成为了人们生活中重要的一部分&#xff0c;或多或少的影响着我们的生活&#xff0c;互联网在给我带了方便的…

【Node.js】笔记整理 2 - 常用模块

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

Linux mesg命令详解:如何设置终端机的写入权限并阻止或允许其他用户的信息显示(附实例教程和注意事项)

Linux mesg命令介绍 Linux mesg命令用于设置终端机的写入权限。当mesg设置为y时&#xff0c;其他用户可以利用write指令将信息直接显示在您的屏幕上。如果设置为n&#xff0c;则不允许其他用户将信息直接显示在你的屏幕上。 Linux mesg命令适用的Linux版本 mesg命令在大多数…

ESP32通过IIC同时驱动mpu6050和OLED

mpu6050 //安装库MPU6050_tockn1.5.2 //接线 供电3.3V scl--引脚22 sda----引脚21 #include <MPU6050_tockn.h> #include <Wire.h>MPU6050 mpu6050(Wire);void setup() {Serial.begin(115200);Wire.begin();mpu6050.begin();mpu6050.calcGyroOffsets(true);de…

Bert-VITS2本地部署遇到的错误

关于Bert-VITS2本地部署遇到的错误 1、在下载python中相关依赖时报错 building ‘hdbscan._hdbscan_tree’ extension error: Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools”: https://visualstudio.microsoft.com/visual-cpp-bu…

【安全-SSH】SSH安全设置

今天发现自己的公有云服务器被攻击了 然后查看了登录日志&#xff0c;如上图 ls -sh /var/log/secure vim /var/log/secure然后增加了安全相关的设置 具体可以从以下方面增加安全性&#xff1a; 修改默认SSH端口公有云修改安全组策略及防火墙端口设置登录失败次数锁定用户及…

SH文件介绍

SH文件介绍 介绍SH文件示例执行SH文件具体用法 介绍 SH文件通常指的是 Shell 脚本文件&#xff0c;文件后缀名为.sh&#xff0c;其中包含一系列要由操作系统的命令解释器执行的命令。 在 Unix 和类 Unix 操作系统中&#xff0c;通常使用 Bourne Shell&#xff08;sh&#xff…

RabbitMQ消息模型之Routing-Direct

Routing Direct 在Fanout模式中&#xff0c;一条消息&#xff0c;会被所有订阅的队列都消费。但是在某些场景下&#xff0c;我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。 在Direct模型下&#xff1a; 队列与交换机的绑定&#xff0c;不能是任意…

刷题笔记(第九天)

1. 求最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”]输出&#xff1a;“fl” 示例 2&#xff1a; 输入&#xff1a;strs [“…

C++面试的一些总结day1:指针和引用的区别

文章目录 指针和引用的区别和作用定义区别作用 指针和引用的区别和作用 定义 指针&#xff1a;指针是一个变量&#xff0c;其值为指向对象的内存地址&#xff0c;而不是值本身。引用&#xff1a;可以理解为对象的别名&#xff0c;是另外一个变量的直接别名&#xff0c;用于创…

Spring不再支持Java8了

在今天新建模块的时候发现了没有java8的选项了&#xff0c;结果一查发现在11月24日&#xff0c;Spring不再支持8了&#xff0c;这可怎么办呢&#xff1f;我们可以设置来源为阿里云https://start.aliyun.com/ 。 java8没了 设置URL为阿里云的地址

【Vue3】源码解析-虚拟DOM

【Vue3】源码解析 系列文章什么是虚拟DOMVue 3虚拟DOM获取<template>内容生成AST语法树生成render方法字符串得到最终VNode对象 系列文章 【Vue3】源码解析-前置 【Vue3】源码解析-响应式原理 【Vue3】源码解析-虚拟DOM 什么是虚拟DOM 在浏览器中&#xff0c;HTML页面…

vue实现左侧固定菜单栏锚点及滚动高亮(组件封装)

vue实现左侧固定菜单栏锚点及滚动高亮 先上总代码&#xff1a; 子组件&#xff1a; <!-- LeftSidebar.vue --> <template><div class"left-sidebar"><a v-for"(item, index) in sidebarItems" :key"index" click"s…

WordPress(9)宝塔配置Redis

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、宝塔安装Redis2、安装好先关闭Redis1、Redis密码默认是没有的二、安装php、Redis扩展1.启动Redis三.WordPress 安装Redis1.安装Redis插件2.启动Redis前言 提示:这里可以添加本文要记录的…

Linux ubuntu20.04 安装使用 Intel sgx

文章目录 前言一、简介二、安装Intel SGX Software Stack2.1 安装Intel SGX driver2.2 Build the Intel SGX SDK and Inte SGX PSW Package2.3 Build the Intel SGX SDK and Intel SGX SDK Installer2.4 Install the Intel(R) SGX SDK2.5 Build the Intel SGX PSW and Intel SG…

5 面试题--redis

伪客户端&#xff1a; 伪客户端的 fd 属性值为 -1&#xff1b;伪客户端处理的命令请求来源于 AOF ⽂件或者 Lua 脚本&#xff0c;⽽不是⽹络&#xff0c;所以这种客户端不需要套接字连接&#xff0c;⾃然也不需要记录套接字描述符。⽬前 Redis 服务器会在两个地⽅ ⽤到伪客户端…

ThermalLabel SDK for .NET 13.0.23.1113 Crack

ThermalLabel SDK for .NET 是一个 .NET 典型类库&#xff0c;它允许用户和开发人员创建非常创新的条码标签并将其发布在 zebra ZPL、EPL、EPSON ESC、POS 以及 Honeywell intermec 指纹中通过在 VB.NET 或 C# 上编写 .NET 纯代码来实现热敏打印机&#xff0c;以实现项目框架的…

BiLSTM-CRF的中文命名实体识别

项目地址&#xff1a;NLP-Application-and-Practice/11_BiLSTM-ner-bilstm-crf/11.3-BiLSTM-CRF的中文命名实体识别/ner_bilstm_crf at master zz-zik/NLP-Application-and-Practice (github.com) 读取renmindata.pkl文件 read_file_pkl.py # encoding:utf-8import pickle# …

分享一些基于php商城案例

案例1&#xff1a; ​​​​​​http://www.9520.xin/ 案例2&#xff1a; http://ptll.hasbuy.com/ 案例3&#xff1a; http://likeshop.9520.xin/mobile 案例4&#xff1a; http://www.hasbuy.com/