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,一经查实,立即删除!

相关文章

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

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

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端口公有云修改安全组策略及防火墙端口设置登录失败次数锁定用户及…

RabbitMQ消息模型之Routing-Direct

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

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;以实现项目框架的…

Ubuntu Linux玩童年小霸王插卡游戏

1.下载安装模拟器 在Windows平台模拟器非常多&#xff0c;而且效果也很优秀&#xff0c;Linux平台的用户常常很羡慕&#xff0c;却因为系统的缘故&#xff0c;无法使用这样的模拟器&#xff0c;但是随着时代的发展&#xff0c;Linux平台也出现了许多优秀的模拟器&#xff0c;现…

navigator.clipboard is undefined in JavaScript issue [Fixed]

navigator.clipboard 在不安全的网站是无法访问的。 在本地开发使用localhost或127.0.0.1没有这个问题。因为它不是不安全网站。 在现实开发中&#xff0c;可能遇到测试环境为不安全网站。 遇到这个问题&#xff0c;就需要将不安全网站标记为非不安全网站即可。 外网提供了3…

【HTML】VScode不打开浏览器实时预览html

1. 问题描述 预览HTML时&#xff0c;不想打开浏览器&#xff0c;想在VScode中直接实时预览 2. 解决方案 下载Microsoft官方的Live Preview 点击预览按钮即可预览

Unity中Shader优化通用规则

文章目录 前言一、精度优化1、三种精度 fixed / half / float2、位置坐标、物理坐标类使用float3、HDR颜色、方向向量类使用half4、普通纹理、颜色类使用 fixed5、实际上&#xff0c;使用的精度取决于 平台 和 GPU6、现在桌面级GPU都是直接采用 float , Shader中的 fixed / hal…

J2EE征程——第一个纯servletCURD

第一个纯servletCURD 前言在此之前 一&#xff0c;概述二、CURD1介绍2查询并列表显示准备实体类country编写 CountryListServlet配置web.xml为web应用导入mysql-jdbc的jar包 3增加准备增加的页面addc.html编写 CAddServlet配置web.xml测试 4删除修改CountryListServlet&#xf…

RabbitMQ消息模型之Routing-Topic

Routing Topic Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key的时候使用通配符&#xff01;这种模型Routingkey一般都是由一个或多个单词组成&#xff0c;多个单词之间以”…

ESP32-Web-Server编程- WebSocket 编程

ESP32-Web-Server编程- WebSocket 编程 概述 在前述 ESP32-Web-Server 实战编程-通过网页控制设备的 GPIO 中&#xff0c;我们创建了一个基于 HTTP 协议的 ESP32 Web 服务器&#xff0c;每当浏览器向 Web 服务器发送请求&#xff0c;我们将 HTML/CSS 文件提供给浏览器。 使用…

智能手表上的音频(四):语音通话

上篇讲了智能手表上音频文件播放。本篇开始讲语音通话。同音频播放一样有两种case&#xff1a;内置codec和BT。先看这两种case下audio data path&#xff0c;分别如下图&#xff1a; 内置codec下的语音通话audio data path 蓝牙下的语音通话audio data path 从上面两张图可以看…

纯js实现录屏并保存视频到本地的尝试

前言&#xff1a;先了解下&#xff1a;navigator.mediaDevices&#xff0c;mediaDevices 是 Navigator 只读属性&#xff0c;返回一个 MediaDevices 对象&#xff0c;该对象可提供对相机和麦克风等媒体输入设备的连接访问&#xff0c;也包括屏幕共享。 const media navigator…

【刷题】DFS

DFS 递归&#xff1a; 1.判断是否失败终止 2.判断是否成功终止&#xff0c;如果成功的&#xff0c;记录一个成果 3.遍历各种选择&#xff0c;在这部分可以进行剪枝 4.在每种情况下进行DFS&#xff0c;并进行回退。 199. 二叉树的右视图 给定一个二叉树的 根节点 root&#x…

深度学习之十二(图像翻译AI算法--UNIT(Unified Neural Translation))

概念 UNIT(Unified Neural Translation)是一种用于图像翻译的 AI 模型。它是一种基于生成对抗网络(GAN)的框架,用于将图像从一个域转换到另一个域。在图像翻译中,这意味着将一个风格或内容的图像转换为另一个风格或内容的图像,而不改变图像的内容或语义。 UNIT 的核心…

IDEA2022 Git 回滚及回滚内容恢复

IDEA2022 Git 回滚 ①选择要回滚的地方&#xff0c;右键选择 ②选择要回滚的模式 ③开始回滚 ④soft模式回滚的内容会保留在暂存区 ⑤输入git push -f &#xff0c;然后重新提交&#xff0c;即可同步远程 注意观察IDEA右下角分支的标记&#xff0c;蓝色代表远程内容未同步到本…