服务器设计之请求处理框架
有三个主要类: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提供的方法。
调用网络框架的接口监听端口www.zzzyk.com
一旦有请求到来,就从线程池中选择一个工作线程,将请求丢给它处理。
一般,线程池被实现为工作队列,没有请求时工作线程都等待在工作队列上,请求到来时工作线程被唤醒,并从队列上取出一个任务进行处理。提交一个请求到工作队列用queue.push(),从工作队列取出一个请求进行处理用queue.pop()。
工作队列有几个重要接口:
init(int thread_count) -- 初始化工作队列,设定队列中的工作线程数
start() -- 启动工作队列,主要是启动工作线程
stop() -- 停止所有工作线程
push(packet) --- 将请求放入工作队列,唤醒工作线程处理
run() --- 工作线程主循环,用于等待请求、处理请求、等待请求、处理请求
实现工作队列需要对一对函数有比较深刻的认识pthread_cond_wait(), pthread_cond_signal(),通常在大型软件中你不会直接看到这两个函数,他们被封装起来了。在OB中它被封装到了tbsys::CThreadCond。
补充:综合编程 , 其他综合 ,