web服务中超时机制的实现

hhxx
  • 569

本人主要从事广告后台检索服务的开发,是一个新人,现在想在自己开发的tcp服务器中添加一个超时机制。具体的需求就是因为检索比较耗时,有时候可能会超时,如何设置一个超时时间,让这个检索不会超时呢?超时的话直接返回空数据。
服务的大体框架都是master-workers,每个worker处理一个请求。现在的检索接口有两种,一种是异步(使用libevent,向另一个服务发送请求后就等着它可读),一种是阻塞的,这两种情况如何分别实现?

// 同步,该接口阻塞直到检索结束,如何添加超时机制?
search.GetAds(request)

// 异步
tcp_send(reqeust);
event_add(&read_event, NULL);
// 等待可读的时候返回数据

提前谢谢大家

回复
阅读 2.8k
2 个回答

1.io同步的可以通过setsockopt设置tcp收发包超时时间来做超时。
2.io异步的可以通过设置定时器来实现,定时器回调时,检索还没完成就是请求超时。

不清楚libevent, 最近在看asio相关的东西,针对 @ACb0y 给出的第二个思路尝试给出方法.

2.io异步的可以通过设置定时器来实现,定时器回调时,检索还没完成就是请求超时。

方法:查询的动作扔到一个线程里面去异步执行去, 当前主线程开一个异步定时器,到了时间查询动作还没有结束,那么直接结束当前线程,这个线程里面声明的查询线程也消失了.

libevent是有超时时间,但是问题是我如何知道那个请求现在是否完成了呢?也就是说我如何检查这次的检索有没有超时?以及如何通知放弃这次超时的检索呢?

请求动作完成后总有函数要执行把,你可以设定一个状态变量,查询有结果的时候置成1, 定时器到达时间了判断一下就是了;
放弃的话,直接让查询线程托管就可以了.

不一定满足你的需求,我的超时控制代码如下:

             do {
                 // 条件变量,用于定时器判断任务是否执行完
                 condition_variable cv;
                 // 待执行的任务(查询)放到线程里,自己跑去吧,执行之后发送条件变量 
                 std::thread t([&](){
                        task(); 
                        // 条件变量发送
                        cv.notify_one();
                     });
                 // 线程托管,和主线程的关系只剩下条件变量了
                 t.detach();
 
                 std::mutex m1; 
                 std::unique_lock<mutex> lock(m1);
                 // 超时机制由"条件变量"提供,判断条件变量是否超时还没传过来,如果超时了直接终结此调用
                 if(cv.wait_for(lock, _timeout*1s) == std::cv_status::timeout) {
                     std::cout<<"time out, cancel the thread"<<std::endl; 
                     break;
                 }
             } while(0);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏