lighttpd-1.4.39 : alarm
2016-02-15 11:34
543 查看
原文: http://bbs.chinaunix.net/thread-1251434-5-1.html
本节相对简单, 讲讲lighttpd中如何处理超时的连接.
方法很简单, lighttpd创建一个每隔一秒触发的定时器, 被触发后查找当前的所有连接, 看它们的时间是否已经超过了最长的生存期, 如果是就关闭连接.
创建定时器的代码在server.c的main函数中:
定时器触发的时候产生ALARM信号,此时在服务器主循环中轮询所有的连接,这段代码同样在server.c的main函数中:
需要注意的是, 由于lighttpd采用了这种方式处理超时连接, 会触发大量的ALARM信号产生,在编码的时候要特别注意被信号中断的情况.
本节相对简单, 讲讲lighttpd中如何处理超时的连接.
方法很简单, lighttpd创建一个每隔一秒触发的定时器, 被触发后查找当前的所有连接, 看它们的时间是否已经超过了最长的生存期, 如果是就关闭连接.
创建定时器的代码在server.c的main函数中:
#ifdef USE_ALARM struct itimerval interval; interval.it_interval.tv_sec = 1; interval.it_interval.tv_usec = 0; interval.it_value.tv_sec = 1; interval.it_value.tv_usec = 0; #endif ... #ifdef USE_ALARM // 定时 signal(SIGALRM, signal_handler); /* setup periodic timer (1 second) */ if (setitimer(ITIMER_REAL, &interval, NULL)) { log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed"); return -1; } getitimer(ITIMER_REAL, &interval); #endif
定时器触发的时候产生ALARM信号,此时在服务器主循环中轮询所有的连接,这段代码同样在server.c的main函数中:
// 如果产生了alarm信号 那么一秒钟过去了... if (handle_sig_alarm) { /* a new second */ #ifdef USE_ALARM /* reset notification */ handle_sig_alarm = 0; #endif /* get current time */ // 获得当前的时间 min_ts = time(NULL); // 如果当前时间不等于server上次记录的时间 if (min_ts != srv->cur_ts) { int cs = 0; connections *conns = srv->conns; handler_t r; switch(r = plugins_call_handle_trigger(srv)) { case HANDLER_GO_ON: break; case HANDLER_ERROR: log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed"); break; default: log_error_write(srv, __FILE__, __LINE__, "d", r); break; } /* trigger waitpid */ // 更新server的当前时间 srv->cur_ts = min_ts; /* cleanup stat-cache */ // 每秒清空一次stat cache stat_cache_trigger_cleanup(srv); /** * check all connections for timeouts */ // 检查所有连接是否已经超时 for (ndx = 0; ndx < conns->used; ndx++) { int changed = 0; connection *con; int t_diff; con = conns->ptr[ndx]; if (con->state == CON_STATE_READ || con->state == CON_STATE_READ_POST) { if (con->request_count == 1) { // 如果当前时间与read_idle_ts之差大于max_read_idle, 超时 if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) { /* time - out */ connection_set_state(srv, con, CON_STATE_ERROR); changed = 1; } } else { // 如果当前时间与read_idle_ts之差大于max_keep_alive_idle, 超时 if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) { /* time - out */ connection_set_state(srv, con, CON_STATE_ERROR); changed = 1; } } } if ((con->state == CON_STATE_WRITE) && (con->write_request_ts != 0)) { // 如果当前时间与write_request_ts之差大于max_write_idle, 超时 if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) { /* time - out */ #if 1 log_error_write(srv, __FILE__, __LINE__, "sbsosds", "NOTE: a request for", con->request.uri, "timed out after writing", con->bytes_written, "bytes. We waited", (int)con->conf.max_write_idle, "seconds. If this a problem increase server.max-write-idle"); #endif connection_set_state(srv, con, CON_STATE_ERROR); changed = 1; } } /* we don't like div by zero */ // 如果接收连接的时间 = server当前时间 if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1; if (con->traffic_limit_reached && // 如果已经达到了传输的极限 (con->conf.kbytes_per_second == 0 || // 似乎这个值一直是0啊 ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) { // 如果每秒发送的数据量小于kbytes_per_second * 1024 /* enable connection again */ // 传输极限不再 con->traffic_limit_reached = 0; changed = 1; } // 如果状态发生了改变, 那么进入状态机进行处理 if (changed) { connection_state_machine(srv, con); } con->bytes_written_cur_second = 0; *(con->conf.global_bytes_per_second_cnt_ptr) = 0; } if (cs == 1) fprintf(stderr, "\n"); } }
需要注意的是, 由于lighttpd采用了这种方式处理超时连接, 会触发大量的ALARM信号产生,在编码的时候要特别注意被信号中断的情况.
相关文章推荐
- linux下yum更新出现HTTP Error 404 NOT FOUND错误的办法
- Android 播放网络视频的一个demo
- 什么是HTTP协议
- 访问网络数据+json解析代码片段
- 网络---使用curl命令排查网络问题小结
- iOS开发网络—数据缓存
- 【 bzoj 3955 】[WF2013]Surely You Congest - 网络流 SPFA
- http请求中乱码------编码的转换
- When to use Tomcat CATALINA_OPTS instead of JAVA_OPTS - See more at: http://www.tikalk.com/java/when
- C# socket nat 映射 网络 代理 转发
- Poj 3057 未AC http://poj.org/showsource?solution_id=15175171
- 远程调用之RMI、Hessian、Burlap、Httpinvoker、WebService的比较
- 数据库,界面,多线程,网络通信
- 通过java发送http请求
- ImageLoader加载网络图片初始化类
- 程序包org.apache.http.client不存在
- 用Telnet发送HTTP请求
- Linux 永久配置网络(重启不还原)
- 基于TcpListener的web服务器
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容