众所周知,Thrift
是一个RPC的框架,其可用于不一样语言之间的服务相互调用。好比最近接触到的一个运用环境:
*前端使用Node.Js重构了部分咱们的老旧代码(先后端未分离的SpringBoot项目),咱们后端使用zookeeper+Thrift为新的Node.Js前端项目提供基本的DAO层服务支持*
因此基于这个项目,我大概了解了一下Thrift,该文章则均以Java
为基础语言。前端
由于后端已经有一套服务注册和暴露机制,因此服务已是RPC的形式,因此咱们仅须要使用Thrift IDL
来重写一遍咱们须要暴露的方法便可,Thrift IDL
有两个比较好的参考选择:java
thrift
基本支持全部的Java基本类型以及引用类型:bool(boolean)、byte(byte)、i16(short)、i32(int)、i64(long)、double(double)、string(String)、binary(byte[])以及一些经常使用容器和自建类型(Struct);services
和struct
放在一个.thrift
文件中,这种方式将service
和其所需的struct
绑定在一块儿,会致使个别struct
重复出如今多个.thrift
文件中,致使大量的代码重复。因此,应该与Java的编码风格保持一致,采用POJO类(struct)
+接口(services)
的方案,利用include
关键字,将struct引进services中使用。Java基本类型
,可是注意是基本类型,相似于Java中的Integer、Boolean、Long、Double等基本类型包装类是不支持的,或许你可使用struct
实现一个相似的包装类结构进行数据承载。enum
枚举类型,可是若是没有description
的枚举类型也能够直接使用string
来承接。struct
结构体的数据的,因此struct
中的数据顺序必定要和java
文件中的一致,不然可能会出现数据对应关系错乱或者数据丢失。struct
体时,要注意java对象
的父级,若是父级中含有变量,不要忘记其变量的书写,且顺序必定在前面。java对象
中的常量能够不出如今thrift idl
的struct
结构体中。Date
咱们固定使用timestamp
时间戳的形式传递,即long
型。咱们如今有一个Account
对象,须要将其变为thrift
文件,Account
的结构以下:node
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; //帐户是否被冻结 //该帐户的绑定信息,非持久化字段 @Transient private Set<Binding> bindings = new HashSet(); @Transient private String name;//保存登陆时用的用户名,非持久化字段 //省略getter和setter }
根据上述结构咱们能够书写以下的Account.thrift
:apache
/** * 帐户信息 */ 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
:ide
/** * 帐户信息 */ struct Account{ 1: i64 id, //帐户Id 2: 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)ui
thrift --gen <language> <Thrift filename> thrift -r --gen js:node Account.thrift thrift -r --gen js:node AccountService.thrift