thrift&http

What

Thrift: Apache基金会下的软件栈,提供了根据IDL进行RPC的PRC工具。

目前的RPC方案

  • HTTP/JSON/XML/REST (当前方案)
  • Thrift (Apache)
  • Protocol buffers (Google)

HTTP

  • 跨语言
  • 缺乏协议描述(你需要什么,你会给我什么)
  • 需要同时维护client和server
  • 需要在HTTP上在定义一层自己的封装
  • 一次请求的数据量太大(HEADER)
  • 跨机房请求较为方便

Thrift

  • 跨语言
  • 自动生成server和client代码、结构体,自动处理参数验证、序列化、网络
  • 协议分层简单 service -> transport -> protocol,可定制性高,支持多种协议
  • 跨机房请求需要网络支持

Thrift中的IDL。

# Simple Calculator Service
typedef i32 int

enum Operators {
    ADD = 0,
    SUB = 1,
    MUL = 2,
    DIV = 3
}

struct Expression {
    1: i32 a = 0,
    2: i32 b,
    3: Operators op
}

exception InvalidOperation {
    1: i32 code,
    2: string msg
}

service SimpleService {
    string ping(1:string msg),
    i32 cal(1:Expression exp) throws (
        1: InvalidOperation exc
    )
}

Service define

class SimpleHandler:
    def ping(self, msg):
        print("Get Ping")
        return "Pong %s" % msg

    def cal(self, exp):
        print("Get Cal")
        ops = dict(zip([0,1,2,3], [operator.add, operator.sub, operator.mul, operator.floordiv]))
        if exp.op == 3 and exp.b == 0:
            raise InvalidOperation(233, 'div 0 error')
        return ops[exp.op](exp.a, exp.b)

if __name__ == '__main__':
    handler = SimpleHandler()
    processor = SimpleService.Processor(handler)
    transport = TSocket.TServerSocket(port=9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
    server.serve()

Client

transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = SimpleService.Client(protocol)
transport.open()

print(client.ping("Hi From Client"))
print(client.ping("Hi Again From Client"))
exp = Expression()
exp.a = 10
exp.b = 20
exp.op = Operators.ADD

print(client.cal(exp))

exp.b = 0
exp.op = Operators.DIV
print(client.cal(exp))

transport.close()

Layer of Thrift

Fig.1

Type of Server

Fig.2

限制

  • IDL限制
    • 没有环形引用 (A->B->C)
    • 不能return null
    • 无法继承
  • 没有开箱即用的认证
  • 无法双工通信
  • Python thread server suck
  • 服务端和客户端的协议必须相同

Thrift 只是协议和工具集,重要的还是服务治理。

服务治理平台

  • 服务注册,服务发现(自动化的endpoint)
  • 自动扩容、自动缩容
  • 服务管理,状态监测,健康检查,负载均衡
  • 流量分发,灰度发布,请求动态配置
  • 调用链(重要),接口健康性监控
  • 配置中心
  • ACL

链路分析

为什么链路分析很重要?

  • 快速定位问题
  • 瓶颈分析
  • 错误追踪
  • 服务依赖分析