Thrift protocol 層需要進行 4 次編解碼操作:
-
客戶端對請求進行編碼,服務端對請求進行解碼
-
服務端對響應進行編碼,客戶端對響應進行解碼
helloservice.thrift
namespace java com.meituan.service
include "model.thrift"
service HelloService {
model.Response sayHello(1: model.Request req)
}
model.thrift
namespace java com.meituan.model
struct Request {
1: required i32 age;
2: required string name;
}
struct Response {
1: required i16 code;
2: required string msg;
}
使用 Thrift 0.9.3 生成 HelloService 服務類。
編碼流程
編碼流程就是將
com.meituan.service.HelloService.Client#sayHello
com.meituan.service.HelloService.Client#send_sayHello
org.apache.thrift.TServiceClient#sendBase(String methodName, TBase<?,?> args)
org.apache.thrift.TServiceClient#sendBase(String methodName, TBase<?,?> args, byte type)
com.meituan.service.HelloService.sayHello_args#write
com.meituan.service.HelloService.sayHello_args.sayHello_argsStandardScheme#write
com.meituan.model.Request#write
com.meituan.model.Request.RequestStandardScheme#write
- writeMessageBegin: org.apache.thrift.TServiceClient#sendBase(String methodName, TBase<?,?> args, byte type)
- writeStructBegin–writeFieldBegin: com.meituan.service.HelloService.sayHello_args.sayHello_argsStandardScheme#write
- writeStructBegin–>writeFieldBegin–>writeI32–>writeFieldEnd–>writeFieldBegin–>writeString–>writeFieldEnd–>writeFieldStop–>writeStructEnd: com.meituan.model.Request.RequestStandardScheme#write
- writeFieldEnd–writeFieldStop–writeStructEnd: com.meituan.service.HelloService.sayHello_args.sayHello_argsStandardScheme#write
- writeMessageEnd: org.apache.thrift.TServiceClient#sendBase(String methodName, TBase<?,?> args, byte type)
總結
- 除了 writeFieldEnd 外所有的 writeXXX 操作都是成對(writeXXXBegin/writeXXXEnd)出現的。
- 假設 sayHello 請求參數不是 struct,而是普通的數據類型,則 3 是不存在的。
- FieldStop 是在所有 Field 寫完之後再寫入的。
- 客戶端調用的主體是 XXXService.Client/TServiceClient。
解碼流程
org.apache.thrift.TBaseProcessor#process
org.apache.thrift.ProcessFunction#process
com.meituan.service.HelloService.sayHello_args#read
com.meituan.service.HelloService.sayHello_args.sayHello_argsStandardScheme#read
com.meituan.model.Request#read
com.meituan.model.Request.RequestStandardScheme#read
- readMessageBegin: org.apache.thrift.TBaseProcessor#process
- readStructBegin – readFieldBegin: com.meituan.service.HelloService.sayHello_args.sayHello_argsStandardScheme#read
- readStructBegin–>readFieldBegin–>readI32–>readFieldEnd–>readFieldBegin–>readString–>readFieldEnd–>readStructEnd: com.meituan.model.Request.RequestStandardScheme#read
- readFieldEnd–>readStructEnd: com.meituan.service.HelloService.sayHello_args.sayHello_argsStandardScheme#read
- readMessageEnd: org.apache.thrift.ProcessFunction#process
總結
- Thrift 生成的 Processor 以及 AsyncProcessor 和調用端半毛錢關係沒有。
- 服務端調用的主體是 ProcessFunction/TBaseProcessor。
- TBaseProcessor 裏的 iface 是真正的實現。