本文记录轻量型服务器中遇到的问题和结果过程。
LT + LT 触发模式,同步 reactor 模型
epoll 的 LT 触发模式中,每个事件会被持续触发。
比如读事件:只要内核接收缓存区可读(字节数大于等于低水位标记 SI_RCVLOWAT),就会持续触发读事件。
reactor 事件处理模式:主线程(I/O 处理单元只负责监听文件描述符 (listenfd) 上是否有事件发生,一旦事件发生立即通知工作线程(逻辑单元),而工作线程负责接受新连接、数据读写以及处理客户请求。
问题
浏览器第一次发送 GET 请求,服务器正常返回登陆页面;
浏览器继续发送 POST 请求,提交请求的页面,服务器正常返回页面;
浏览器发送 POST 请求,请求 cgi 文件时,错误发生:服务器解析完请求报文后无响应,但查看日志发现服务器会重复解析浏览器端重传的报文,且解析有错误;且此后(仅有一个工作线程的情况下)服务器不再响应任何请求。
因此可以推断,出现错误后工作线程处于工作状态,且第一个问题首先出在 POST 请求的请求体的解析之后。
问题解决,程序写错了……实属智障。
LT + ET 触发模式,同步 reactor 模型
GET 请求无响应。因为 LT + LT 触发模式经测试没问题,那么就是 ET 触发模式的连接 socket 读取出问题。问题是 ET 模式读取数据时,由于 ET 模式每个事件只触发一次,因此必须循环读取 socket 数据,在第一次读出所有数据的情况下,while 循环会阻塞在 recv(),即工作线程会阻塞在 recv() 上直到再次收到数据。
问题解决,是设置文件描述符非阻塞时,
1 | fcntl(fd, F_SETFL, new_option); |
ET + LT 触发模式,同步 reactor 模型
测试没问题。
ET + ET 触发模式,同步 reactor 模型
测试通过。
BUG
客户端大量发送数据时会导致段错误。
timer 野指针
定时器删除节点后,指针未置空,导致重复删除时访问错误。
webbench 压测时 http 解析段错误
webbench使用短连接进行测试,服务器发送完数据