Thrift IDL使用方式
I.背景
众所周知,Thrift
是一个RPC的框架,其可用于不同语言之间的服务相互调用。比如最近接触到的一个运用环境:
*前端使用Node.Js重构了部分我们的老旧代码(前后端未分离的SpringBoot项目),我们后端使用zookeeper+Thrift为新的Node.Js前端项目提供基本的DAO层服务支持*
所以基于这个项目,我大概了解了一下Thrift,该文章则均以Java
为基础语言。
II.如何入门
因为后端已经有一套服务注册和暴露机制,所以服务已经是RPC的形式,所以我们仅需要使用Thrift IDL
来重写一遍我们需要暴露的方法即可,Thrift IDL
有两个比较好的参考选择:
- Thrift 类型说明可以参考官方文档: Thrift Type,简单来说,
thrift
基本支持所有的Java基本类型以及引用类型:bool(boolean)、byte(byte)、i16(short)、i32(int)、i64(long)、double(double)、string(String)、binary(byte[])以及一些常用容器和自建类型(Struct); - Thrift IDL的书写规范则可以参考Thrift: The Missing Guide,这个文档相较于官方文档有更多的例子可以参考。
III.TIPS
- 很多参考和学习文档,都将
services
和struct
放在一个.thrift
文件中,这种方式将service
和其所需的struct
绑定在一起,会导致个别struct
重复出现在多个.thrift
文件中,导致大量的代码重复。所以,应该与Java的编码风格保持一致,采用POJO类(struct)
+接口(services)
的方案,利用include
关键字,将struct引进services中使用。 - Thrift支持基本所有的
Java基本类型
,但是注意是基本类型,类似于Java中的Integer、Boolean、Long、Double等基本类型包装类是不支持的,或许你可以使用struct
实现一个类似的包装类结构进行数据承载。 - Thrift支持
enum
枚举类型,但是如果没有description
的枚举类型也可以直接使用string
来承接。 - Thrift是通过序列化和反序列化来获取对应
struct
结构体的数据的,所以struct
中的数据顺序一定要和java
文件中的一致,否则可能会出现数据对应关系错乱或者数据丢失。 - 在编写
struct
体时,要注意java对象
的父级,如果父级中含有变量,不要忘记其变量的书写,且顺序一定在前面。 - 如非必要,
java对象
中的常量可以不出现在thrift idl
的struct
结构体中。 - 时间
Date
我们固定使用timestamp
时间戳的形式传递,即long
型。
IV. 例子
我们现在有一个Account
对象,需要将其变为thrift
文件,Account
的结构如下:
public class Account extends BaseEntity implements SecurityUser{private static final long serialVersionUID = 1L;public static final String PASSWORD_TIME = "passwordTime";private String password; // 密码private Date createTime; // 创建时间private Date lastLoginTime; // 最后登录时间private int loginCount = 0; // 登录次数private boolean enabled = true;private Date passwordTime; //密码修改时间private boolean freeze; //账户是否被冻结//该账户的绑定信息,非持久化字段@Transientprivate Set<Binding> bindings = new HashSet();@Transientprivate String name;//保存登录时用的用户名,非持久化字段//省略getter和setter}
根据上述结构我们可以书写如下的Account.thrift
:
/*** 账户信息*/
struct Account{1: string password, //密码2: i64 createTime, //创建时间3: i64 lastLoginTime, //最后登录时间4: i32 loginCount, //登陆次数5: bool enabled=true,6: i64 passwordTime, //密码修改时间7: bool freeze, //账户是否被冻结
}
但是经过测试前端调用接口获取到的Account
信息,要么数据错位,要么数据丢失,问题出在哪里呢?这时,我们发现Account
对象继承了BaseEntity
,实现了SecurityUser
,我们去查看一下继承的BaseEntity
对象:
public abstract class BaseEntity extends IdEntity implements Cacheable, TypeAliases{private static final long serialVersionUID = 1L;private static final String CACHE_NAMESPACE = "entity" ;public BaseEntity() {super();}public BaseEntity(Long id) {super(id);}//省略下方代码
}
我们发现其中并没有非常量变量,但是BaseEntity
又继承了IdEntity
,所以我们得再去看一看IdEntity
:
public abstract class IdEntity implements Serializable{private static final long serialVersionUID = -1L;/*** Hibernate JPA环境中使用@GenericGenerator注解生成主键*/@Id@GeneratedValue(generator = "longIdGenerator")@GenericGenerator(name = "longIdGenerator", strategy = "net.rekent.framework.id.LongIdGenerator")protected Long id;public IdEntity() {super();}public IdEntity(Long id) {super();this.id = id;}//省略getter和setter
}
这时我们发现IdEntity
中含有一个Id
的变量,所以我们需要重构一下刚刚书写的Account.thrift
:
/*** 账户信息*/
struct Account{1: i64 id, //账户Id2: string password, //密码3: i64 createTime, //创建时间4: i64 lastLoginTime, //最后登录时间5: i32 loginCount, //登陆次数6: bool enabled,7: i64 passwordTime, //密码修改时间8: bool freeze, //账户是否被冻结
}
书写完Account.thrift
后,我们需要写其相应的接口即service
,查看Interface AccountService
:
public interface AccountService {/*** 创建账户* @param account* @return 返回创建后的Account对象*/Account create(Account account);/*** 更新账户信息* @param account* @return*/boolean update(Account account);/*** 修改开放平台密码 传入的 密码是未加密的* @param username* @param newPassword* @return*/boolean updatePasswd(String username, String newPassword);/*** 重置密码* @param username 用户名* @param newPassword 新密码*/void resetPasswd(String username, String newPassword);/*** 验证用户名和密码是否匹配* @param username* @param password*/boolean matches(String username,String password);
}
有很多方法,但是如果前端只需要用到校验用户名和密码的方法,那么我就只需要暴露创建账户的方法,即:
include "Account.thrift"service AccountService{/** 校验用户名和密码*/bool matches(1: string username,2: string password),
}
这样我们就完成了一个关于用户名和密码的校验方法的thrift idl
文档的书写,前端需要执行thrift
的一条语句对文件进行编译,以node.js
为例(具体可参考:Apache Thrift Tutorial)
thrift --gen <language> <Thrift filename>thrift -r --gen js:node Account.thrift
thrift -r --gen js:node AccountService.thrift
转载于:https://www.cnblogs.com/rekent/p/9722841.html
Thrift IDL使用方式相关推荐
- thrift IDL
参考资料: [1] Thrift 入门 [2] Thrift入门及Java实例演示 [3] Thrift使用指南及语法介绍 [4] Thrift RPC 系列教程(1)--Thrift语言 [5] J ...
- Thrift IDL基本语法
简言:介绍Thrift的IDL基本语法,初次使用或多或少的会有很有"坑"要踩,但是我们要遇山挖山,遇海填海,在学习的道路上坚定的走下去,方可日后吹牛B! IDL Thrift 采用 ...
- Thrift IDL示例文件
Java 示例1: 在src下新建thrift目录,在此目录下新建MyData.thrift文件 namespace java thrift.generatedtypedef i16 short ty ...
- WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...
- Hive之 hive的三种使用方式(CLI、HWI、Thrift)
Hive有三种使用方式--CLI命令行,HWI(hie web interface)浏览器 以及 Thrift客户端连接方式. 1.hive 命令行模式 直接输入/hive/bin/hive的执行程 ...
- [zz]Apache Thrift学习小记
参考: http://incubator.apache.org/thrift/ http://wiki.apache.org/thrift/FrontPage http://jnb.ociweb.co ...
- 序列化--反序列化:Schema evolution in Avro, Protocol Buffers and Thrift
当想要数据, 比如对象或其他类型的, 存到文件或是通过网络传输, 需要面对的问题是序列化问题 对于序列化, 当然各个语言都提供相应的包, 比如, Java serialization, Ruby's ...
- java服务端开发 php_PHP使用thrift做服务端开发
php中文网最新课程 每日17点准时技术干货分享 php使用thrift做服务端开发 thrift采用接口描述语言定义和创建服务,用二进制格式传输数据,体积更小.效率更高,对于高并发.数据量大和多语言 ...
- 记一次内存溢出的分析经历——使用thrift
背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的 ...
- 如果某个字段值相同则触发器新增_Thrift IDL新增字段导致版本不一致引发的惨案...
公司某业务出现严重的线上故障,复盘发现原因竟是某接口的 Thrift IDL 变更,未及时同步所有上游,导致上游某服务 OOM 引发 Crash.看似操作不规范是本次故障的根因,但进一步思考:该接口非 ...
最新文章
- 女大男9岁 我们不可以么
- android.mk 比较字变量,粉丝投稿 | 谈谈Android.mk
- PHP面向对象2之变量、方法
- python 中main函数总结
- rtmp httpflv 服务优化以及安全性分布式探讨
- linux 设置pip 镜像 Pip Warning:–trusted-host 问题解决方案
- 平衡二叉树的判定(LeetCode 110)
- 18.输入和输出函数
- 规定时间内,将浏览次数增加且只增加一次
- 统计学附录,F分布和t分布表
- 用户故事与敏捷方法—编写故事
- 数独终盘生成器(调试成果)
- gps串口通信程序c语言,stm32单片机串口接收GPS数据并解析NMEA之GPRMC
- 电脑可以连接手机热点,却无法连路由器无线wifi
- 在CentOs7上部署Gunicorn
- history路由下,Whitelabel Error Page错误
- 关于oracle导入数据出现字符集问题及一点点解决办法!
- 20220312纪中集训总结
- Joseph Darcy卸任OpenJDK 6负责人
- 数据库删除重复(所有列都重复)数据,保留一条,并且再给此表加上联合主键
热门文章
- 序列化和反序列化(JSON、protobuf)
- Hexo报错Usage: hexo command处理及图片显示问题
- Flutter之跨组件状态共享Provider框架剖析(2)
- php工具箱的mysql服务_解决php工具箱(phpStudy)Apache启动成功,MySql无法启动的问题...
- android自定义 ProgressBar(继承自View)
- 性能测试--jmeter中http的请求默认值【6】
- c# zxing条形码设置密度_C# 中 ZXing.Net 怎样突破 条形码 多识别 数量限制
- iqc工作职责和工作内容_新媒体实习生是做什么的?新媒体实习生岗位职责工作内容...
- python中矩阵除法_Python numpy矩阵处理运算工具用法汇总
- python设置很大的刻度_【Matplotlib】设置刻度(1)