程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> thrift oneway的問題

thrift oneway的問題

編輯:C++入門知識

今天同事試驗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應該使用在可靠性要求不高,同時對發送的速度有了解。可以保證失敗的幾率很低時。

 

 

摘自 @且聽風吟@

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved