衆所周知,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