当前位置:编程学习 > C/C++ >>

thrift oneway的问题

今天同事试验oneway的时候,发现client发送的消息数目和server接收的不一致。自己也做了下试验。发现也是不一致。

数据结构定义如下:book.thrift

namespace cpp codelab

struct Book {
1: i32 book_id
2: string name
}

server 端 hello.thrift 定义如下:

include "book.thrift"

namespace cpp codelab_proto

service HelloBook {
oneway void ping(1: book.Book book)
}

server代码大致如下

class HelloBookHandler : virtual public HelloBookIf {
public:
HelloBookHandler() {
// Your initialization goes here
}

void ping(const codelab::Book& book) {
// Your implementation goes here
++count;
printf("book name: %s,%d\n", book.name.c_str(), count);
}
private:
static volatile int count;
};
volatile int HelloBookHandler::count = 0;

int main(int argc, char **argv) {
// create the server in a new thread
ThriftNonBlockingServerThread<HelloBookHandler, HelloBookProcessor>
thread(false, 9090, NULL);
thread.Start();
bool flag = true;
// wait forever or do anything you need to do
while (true) {
sleep(1);
if (flag) {
LOG(INFO) << "server port:" << thread.ServerPort();
flag = false;
}
}
return 0;
}

 

client代码大致如下:

int main(int argc, char **argv) {
base::ParseCommandLineFlags(&argc, &argv, true);
boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
boost::shared_ptr<TTransport> transport(new TFramedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

HelloBookClient client(protocol);
transport->open();
Book book;
book.name = "This is a hello thrift test";
for(size_t i = 0; i < 10000; ++i) {
try{
client.ping(book);
sleep(0); // 这里是第一处A
}catch(TException& tx) {
LOG(ERROR) << "exception:" << tx.what();
transport->open();
}
}
sleep(60);//这里是第二处B
transport->close();

return 0;
}

注: 由于个人代码编译环境问题,上面的代码仅供了解逻辑,可能无法直接使用。

实现现象如下:

当thrift接口定义非oneway时,服务端收到的消息个数和客户端是一致的。

但是当定义为oneway时,有如下几种情况

注意上面有两处A和B 当A设置为大于0时, 没有B处的代码时,服务端接收到的消息个数和客户端是一致的。

当A设置为0时,而没有B处的代码时。服务端接收到的消息个数就不一致了。收到消息个数跟消息大小有关系。

当A设置为0时,同时设置B出的代码做一定的sleep。服务端接收到的消息的个数和客户端就一致了。

 

个人分析:

  oneway的方式是客户端将消息写入本地的网络缓冲区就直接返回。是否成功发送到服务端是由网络保证的。而如果发送的速度慢。客户端直接退出了。后面的消息就会丢失。

  而非oneway的方式是将消息发送给对方。服务端收到消息后,会给client端发送响应。这样就是同步的停等发送方式。

  所以oneway应该使用在可靠性要求不高,同时对发送的速度有了解。可以保证失败的几率很低时。

 

 

摘自 @且听风吟@

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,