内容简介:众所周知,因为后端已经有一套服务注册和暴露机制,所以服务已经是RPC的形式,所以我们仅需要使用我们现在有一个
众所周知, 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; //账户是否被冻结 //该账户的绑定信息,非持久化字段 @Transient private Set<Binding> bindings = new HashSet(); @Transient private 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.qiyuesuo.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, //账户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
)
thrift --gen <language> <Thrift filename> thrift -r --gen js:node Account.thrift thrift -r --gen js:node AccountService.thrift复制代码
以上所述就是小编给大家介绍的《Thrift IDL 快速入门》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- TiDB入门(四):从入门到“跑路”
- MyBatis从入门到精通(一):MyBatis入门
- MyBatis从入门到精通(一):MyBatis入门
- Docker入门(一)用hello world入门docker
- 赵童鞋带你入门PHP(六) ThinkPHP框架入门
- 初学者入门 Golang 的学习型项目,go入门项目
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Building Social Web Applications
Gavin Bell / O'Reilly Media / 2009-10-1 / USD 34.99
Building a social web application that attracts and retains regular visitors, and gets them to interact, isn't easy to do. This book walks you through the tough questions you'll face if you're to crea......一起来看看 《Building Social Web Applications》 这本书的介绍吧!