服务器设计之请求处理框架[转]

Posted on 2016-06-27 10:27  bingoshaw  阅读(105)  评论(0编辑  收藏  举报

自 http://blog.csdn.net/maray/article/details/8588595

上一篇讲了工作线程池的设计,这一篇讲讲工作线程前面的事:如何写Server Front-end。

 

有三个主要类:ObMySQLServer,ObMySQLCallback,ObMySQLCommandQueueThread

ObMySQLServer负责和网络框架libeasy进行交互,具体交互的桥梁通过ObMySQLCallback来实现。首先ObMySQLServer将ObMySQLCallback注册到easy框架中(easy暴露了encode、decode、process、on_disconnect、on_connect、cleanup几个数据处理接口),easy框架收到请求后会回调ObMySQLCallback中的函数,ObMySQLCallback一方面维护easy的状态,一方面会将请求路由到ObMySQLServer,ObMySQLServer中有一整套处理请求的函数,它会判断请求类型,然后调用对应函数。

为了多线程处理并发请求,请求路由到ObMySQLServer后它并不是立即处理请求,而是将请求推送到ObMySQLCommandQueueThread线程池上去,唤醒一个线程来处理该请求。ObMySQLCommandQueueThread主要是提供线程资源,具体如何处理请求它也并不知道,它会委托ObMySQLPacketQueueHandler来处理。OceanBase中为了简化处理,ObMySQLServer实现了ObMySQLPacketQueueHandler接口。也就是说,转了一圈,请求最终还是被ObMySQLServer处理的,只不过切换到了另一个线程上下文中。

 

脱离OceanBase背景,再捋一遍如何写Server front-end。

首先要写一个server架子,这个server首先进行以下初始化:

 

  • 创建线程池,启动工作线程。为了共享状态(一些singleton的proxy、manager),server的指针可以在启动阶段就传递给工作线程,然后在工作线程中回调server提供的方法。
  • 调用网络框架的接口监听端口

 

一旦有请求到来,就从线程池中选择一个工作线程,将请求丢给它处理。

一般,线程池被实现为工作队列,没有请求时工作线程都等待在工作队列上,请求到来时工作线程被唤醒,并从队列上取出一个任务进行处理。提交一个请求到工作队列用queue.push(),从工作队列取出一个请求进行处理用queue.pop()。

工作队列有几个重要接口:

 

  • init(int thread_count)  -- 初始化工作队列,设定队列中的工作线程数
  • start()  -- 启动工作队列,主要是启动工作线程
  • stop()  -- 停止所有工作线程
  • push(packet)  --- 将请求放入工作队列,唤醒工作线程处理
  • run()  --- 工作线程主循环,用于等待请求、处理请求、等待请求、处理请求
实现工作队列需要对一对函数有比较深刻的认识pthread_cond_wait(), pthread_cond_signal(),通常在大型软件中你不会直接看到这两个函数,他们被封装起来了。在OB中它被封装到了tbsys::CThreadCond

Copyright © 2024 bingoshaw
Powered by .NET 8.0 on Kubernetes