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

  • 很多参考和学习文档,都将servicesstruct放在一个.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 idlstruct结构体中。
  • 时间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使用方式相关推荐

  1. thrift IDL

    参考资料: [1] Thrift 入门 [2] Thrift入门及Java实例演示 [3] Thrift使用指南及语法介绍 [4] Thrift RPC 系列教程(1)--Thrift语言 [5] J ...

  2. Thrift IDL基本语法

    简言:介绍Thrift的IDL基本语法,初次使用或多或少的会有很有"坑"要踩,但是我们要遇山挖山,遇海填海,在学习的道路上坚定的走下去,方可日后吹牛B! IDL Thrift 采用 ...

  3. Thrift IDL示例文件

    Java 示例1: 在src下新建thrift目录,在此目录下新建MyData.thrift文件 namespace java thrift.generatedtypedef i16 short ty ...

  4. WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例

    最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...

  5. Hive之 hive的三种使用方式(CLI、HWI、Thrift)

    Hive有三种使用方式--CLI命令行,HWI(hie web interface)浏览器 以及 Thrift客户端连接方式. 1.hive  命令行模式 直接输入/hive/bin/hive的执行程 ...

  6. [zz]Apache Thrift学习小记

    参考: http://incubator.apache.org/thrift/ http://wiki.apache.org/thrift/FrontPage http://jnb.ociweb.co ...

  7. 序列化--反序列化:Schema evolution in Avro, Protocol Buffers and Thrift

    当想要数据, 比如对象或其他类型的, 存到文件或是通过网络传输, 需要面对的问题是序列化问题 对于序列化, 当然各个语言都提供相应的包, 比如, Java serialization, Ruby's ...

  8. java服务端开发 php_PHP使用thrift做服务端开发

    php中文网最新课程 每日17点准时技术干货分享 php使用thrift做服务端开发 thrift采用接口描述语言定义和创建服务,用二进制格式传输数据,体积更小.效率更高,对于高并发.数据量大和多语言 ...

  9. 记一次内存溢出的分析经历——使用thrift

    背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的 ...

  10. 如果某个字段值相同则触发器新增_Thrift IDL新增字段导致版本不一致引发的惨案...

    公司某业务出现严重的线上故障,复盘发现原因竟是某接口的 Thrift IDL 变更,未及时同步所有上游,导致上游某服务 OOM 引发 Crash.看似操作不规范是本次故障的根因,但进一步思考:该接口非 ...

最新文章

  1. 女大男9岁 我们不可以么
  2. android.mk 比较字变量,粉丝投稿 | 谈谈Android.mk
  3. PHP面向对象2之变量、方法
  4. python 中main函数总结
  5. rtmp httpflv 服务优化以及安全性分布式探讨
  6. linux 设置pip 镜像 Pip Warning:–trusted-host 问题解决方案
  7. 平衡二叉树的判定(LeetCode 110)
  8. 18.输入和输出函数
  9. 规定时间内,将浏览次数增加且只增加一次
  10. 统计学附录,F分布和t分布表
  11. 用户故事与敏捷方法—编写故事
  12. 数独终盘生成器(调试成果)
  13. gps串口通信程序c语言,stm32单片机串口接收GPS数据并解析NMEA之GPRMC
  14. 电脑可以连接手机热点,却无法连路由器无线wifi
  15. 在CentOs7上部署Gunicorn
  16. history路由下,Whitelabel Error Page错误
  17. 关于oracle导入数据出现字符集问题及一点点解决办法!
  18. 20220312纪中集训总结
  19. Joseph Darcy卸任OpenJDK 6负责人
  20. 数据库删除重复(所有列都重复)数据,保留一条,并且再给此表加上联合主键

热门文章

  1. 序列化和反序列化(JSON、protobuf)
  2. Hexo报错Usage: hexo command处理及图片显示问题
  3. Flutter之跨组件状态共享Provider框架剖析(2)
  4. php工具箱的mysql服务_解决php工具箱(phpStudy)Apache启动成功,MySql无法启动的问题...
  5. android自定义 ProgressBar(继承自View)
  6. 性能测试--jmeter中http的请求默认值【6】
  7. c# zxing条形码设置密度_C# 中 ZXing.Net 怎样突破 条形码 多识别 数量限制
  8. iqc工作职责和工作内容_新媒体实习生是做什么的?新媒体实习生岗位职责工作内容...
  9. python中矩阵除法_Python numpy矩阵处理运算工具用法汇总
  10. python设置很大的刻度_【Matplotlib】设置刻度(1)