Thrift 原生的请求响应模式是不支持添加 request id 等跟踪信息的,为了解决这个问题,饿了么参考twitter 的 finagle thrift 为 Thrift 的 RPC 调用添加了 meta 支持。

大致流程如下: flow

需要留意的是,meta的支持需要Client&Server同时支持,所以在thrift连接发起后要进行一次应用层握手。

实现

client发送rpc请求:

def _send(self, _api, **kwargs):
    if self._upgraded:
        self._header = track_thrift.RequestHeader()
        self.tracker.gen_header(self._header)
        self._header.write(self._oprot)
 
    self.send_start = int(time.time() * 1000)
    super(TTrackedClient, self)._send(_api, **kwargs)

server处理rpc请求:

def _process_in(self, api, iprot):
    if api not in self._service.thrift_services:
        iprot.skip(TType.STRUCT)
        iprot.read_message_end()
        return TApplicationException(
            TApplicationException.UNKNOWN_METHOD), None
 
    args = getattr(self._service, api + "_args")()
    args.read(iprot)
    iprot.read_message_end()
    result = getattr(self._service, api + "_result")()
 
    # convert kwargs to args
    api_args = [args.thrift_spec[k][1]
                for k in sorted(args.thrift_spec)]
 
    def call():
        return getattr(self._handler, api)(
            *(args.__dict__[k] for k in api_args)
        )
 
    return result, call