使用 Apache Thrift 时如何检测协议不匹配?

Posted

技术标签:

【中文标题】使用 Apache Thrift 时如何检测协议不匹配?【英文标题】:How to detect protocol mismatch while using Apache Thrift? 【发布时间】:2015-08-07 09:23:03 【问题描述】:

我正在我的 Mac 上运行一对使用 Apache Thrift 进行通信的客户端和服务器程序。在我们的生产系统中,我们最终可能会遇到客户端使用TJSONProtocol而服务器使用TBinaryProtocol进行序列化和反序列化的情况。

我知道这是一件可怕的事情。但我不确定如何事先检测到这一点。我尝试了一个具有不同协议的示例程序。我原以为会收到异常,但客户端卡在 RPC 调用上并且从未返回。

使用TBinaryProtocol的服务器代码:

shared_ptr<SomethingHandler> handler(new SomethingHandler());
shared_ptr<TProcessor> processor(new SomethingProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();

使用TJSONProtocol的客户端代码:

boost::shared_ptr < TSocket > socket(new TSocket(argv[1], 9090));
boost::shared_ptr < TTransport > transport(new TBufferedTransport(socket));
boost::shared_ptr < TProtocol > protocol(new TJSONProtocol(transport));
transport->open();
std::cout<<"Transport open success"<<std::endl;
SomethingClient client(protocol);
std::cout<<"Create client success"<<std::endl;
try
    std::cout<<"About to ping"<<std::endl;
    client.ping(argv[2]);
    std::cout<<"Ping success"<<std::endl;
    catch(TException e)
    std::cout<<"Exception occurred:"<<e.what()<<std::endl;

transport->close();

在这个例子中,我从来没有得到Ping success 来打印。 有什么方法可以检测到这种不兼容性而不会卡住?

【问题讨论】:

【参考方案1】:

恐怕你不能。根据定义,您应该在两端设置完全相同的协议/传输堆栈1);其他任何事情都是无效的。

如果您需要不同的协议/传输堆栈,则需要设置适当数量的不同端点。

除了堆栈更高级别的常用机制外,没有任何保护或检测。你卡住的原因很可能是对数据的误解,所以服务器可能只是等待更多的请求字节进来,而你没有发送。


1) 该规则有一些例外,但它们在这里无关紧要。

【讨论】:

哦,那太糟糕了。我想控制我在运行程序时动态使用的协议,以便我可以切换到 JSON/调试协议进行调试,并切换到二进制进行生产运行。我担心在测试过程中的某些情况下,我们最终可能会遇到配置不匹配导致协议不匹配的情况。 如何同时使用不同的端口进行调试/发布? 如果它只是为了调试目的,它可以只是程序选项(甚至是编译选项) - 你应该很少需要使用调试,并且在需要时只需使用不同启动的客户端和服务器设置调试环境。

以上是关于使用 Apache Thrift 时如何检测协议不匹配?的主要内容,如果未能解决你的问题,请参考以下文章

Thrift框架-安装

Thrift框架-安装

使用 Apache Thrift 实现具有 HTTP 协议的服务器/客户端

thrift原理分析

hiveserver2 org.apache.thrift.transport.TTransportException 在不活动分钟后运行第二个查询时出错

Apache Thrift系列详解 - 序列化机制