在nginx listen配置项的说明中有一个选项:

  deferred -- indicates to use that postponed accept(2) on Linux with. the aid of option TCP_DEFER_ACCEPT.

  我们知道通常影响服务端性能的四大原因有:内存拷贝、内存分配、系统调用,进程切换。而nginx的deffered选项的作用是用来降低服务端进行epoll_ctl、epoll_wait(linux下)的次数(系统调用)和降低服务端保持的连接句柄数,从而提高服务端处理性能的设置。设置这个选项以后只有客户端有数据到达时才被epoll_wait监听到,再去accept和处理连接数据。
void
ngx_event_accept(ngx_event_t *ev)
{
......
if (ev->deferred_accept) {
rev->ready = ;
}
ls->handler(c);
......
}

而ls->handler在ngx_http_add_listening中被初始化为 ls->handler = ngx_http_init_connection,那么继续看

void
ngx_http_init_connection(ngx_connection_t *c)
{
......
if (rev->ready) {
/* the deferred accept(), rtsig, aio, iocp */
if (ngx_use_accept_mutex) {
ngx_post_event(rev, &ngx_posted_events);
return;
}
......
}

  在ngx_http_init_connection中就将接收到的事件放到posted队列中等待线程的处理。而在未设置deferred 选项时,这个操作是要我们在将接收到的连接epoll_ctl(ADD)之后再epoll_wait探测到EPOLLIN事件时才做这个处理的,从这里看我们就减少了一次epoll_wait该事件的过程,而且等到有数据时才accept,那么和未设置deffered选项时相比减少了accept到有数据之间这段事件服务器维护的一条连接。

  但是这个过程时如何实现的呢?我们知道TCP建立连接时进行三次握手协议,即客户端发送sync,服务端sync、ack,客户端ack即连接建立,这个时候服务端就对这个连接句柄进行accept。而查查TCP_DEFER_ACCEPT这个选项,可以了解到在tcp_check_req中有如下代码:
struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
struct request_sock *req,
struct request_sock **prev)
{
......
/* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + ) {
//如果选项设置了,并且是裸ack,丢弃该ack;选项值得默认为1
inet_rsk(req)->acked = ;
return NULL;
}
child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb,
req, NULL);
//如果非裸ack或没设置选项则建立连接(req从半连接队列到连接队列及tcp状态变为ESTABLISHED)
......
}
  TCP在处理链接请求时,服务器发送sync,ack后,处理客户端来的数据时,如果客户端只是对服务端的sync的ack那么则丢弃对这个裸ack,而直到有数据一起到来时再将tcp状态转换为ESTABLISHED,服务器端才对这个监听的句柄进行accept处理。
 
当然在服务端丢弃裸ack后就破坏了tcp的三次握手协议的过程,针对这个内核使用的是一个 超时重传sync、ack的机制,其以一个2的等比数列的方式进行重传。这部分具体的处理,请参考内核tcp协议栈的实现部分。

nginx 的socket 选项处理--TCP_DEFER_ACCEPT的更多相关文章

  1. 浅谈Linux环境下Socket选项的设置

    0.前言 TCP/IP协议栈是Linux内核的重要组成部分和网络编程的基石,虽然Linux和BSD有很大的联系,但是对于某些Socket选项和内核操作仍然存在差异,因此文中适用场景均为CentOS环境 ...

  2. Socket编程基础——Socket选项

    有些情况下,我们需要对Socket行为和属性进一步控制,例如修改缓冲区大小,查看Socket状态,这就需要设置/获取Socket选项. 1.获取Socket选项int getsockopt(SOCKE ...

  3. erlang R17新socket选项{active,N}

    erlang R17带来了新的socket选项{active,N} .与{active,once}连同应用层提供的流量控制.为什么会这样选择,{active,once}不能够有效地抑制了很多socke ...

  4. nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)

    环境:Centos6.5 行为:安装nginx 问题: nginx: [emerg] socket() [::]: failed (: Address family not supported by ...

  5. Nginx支持Socket转发过程详解

    序言 一网友在群中问,nginx支持socket转发吗? 实话说,我没做过socket转发,但是我知道socket跟http一样都是通过tcp或者udp通信的,我猜测啦一下nginx应该支持吧,然后又 ...

  6. Linux 高性能服务器编程——socket选项

    socket选项函数 功能:用来读取和设置socket文件描述符属性的方法 函数: #include <sys/scoket.h> int getsockopt ( int sockfd, ...

  7. 常用socket选项

    1.socket选项通常:服务端应在listen 前设置,accpet返回的socket继承自监听套接字. 客户端应在connect之前设置 2.socket 如果有大量短连接应设置SO_LINGER ...

  8. Socket编程中的强制关闭与优雅关闭及相关socket选项

    以下描述主要是针对windows平台下的TCP socket而言. 首先需要区分一下关闭socket和关闭TCP连接的区别,关闭TCP连接是指TCP协议层的东西,就是两个TCP端之间交换了一些协议包( ...

  9. 提高服务端性能的几个socket选项

    提高服务端性能的几个socket选项 在之前的一篇文章中,作者在配置了SO_REUSEPORT选项之后,使得应用的性能提高了数十倍.现在介绍socket选项中如下几个可以提升服务端性能的选项: SO_ ...

随机推荐

  1. 关联更新 Update

    Update a set a.Manage_FunctID=b.Manage_FunctID   From Manage_PageUrl a   Left join Manage_ButtonBar ...

  2. 《垃圾回收的算法与实现》——GC标记-清除算法

    基本算法 标记-清除算法由 ==标记阶段== 和 ==清除阶段== 构成. 标记即将所有活动的对象打上标记. 清除即将那些没有标记的对象进行回收. 标记与清除 遍历GC root引用,递归标记(设置对 ...

  3. django中有外键关系两张表的相互查找方法

    两张通过外键联系的表,如何在一张表上根据另一张表上的属性查找满足条件的对象集? 1  平常查找表中数据的条件是python中已有的数据类型,通过名字可以直接查找.如果条件是表中外键列所对应表的某一列, ...

  4. 如何在python3环境下的Django中使用MySQL数据库

    我们在使用Django过程中,连接MySQL数据库时,对Python不同的版本对应的库也不一样,用惯了Python2的人在使用Python3时经常会遇到下面的错误: Error loading MyS ...

  5. 在word中优雅地插入代码

    PlanetB:带行号 http://www.planetb.ca/syntax-highlight-word   Pygments(推荐):不带行号,多种样式可选 http://pygments.o ...

  6. 尝试用selenium+appium运行一个简单的demo报错:could not get xcode version. /Library/Developer/Info.plist doest not exist on disk

    业余时间抽空搭了个appium+selenium的环境(mac), 在执行第一个脚本的时候遇到个问题纪录下: could not get xcode version. /Library/Develop ...

  7. [WC 2018]州区划分

    Description 题库链接 小 \(S\) 现在拥有 \(n\) 座城市,第 \(i\) 座城市的人口为 \(w_i\) ,城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 \(n ...

  8. [CTSC 2018]假面

    Description 题库链接 有 \(n\) 个敌方单位,初始第 \(i\) 个单位的血量为 \(m_i\) .共 \(Q\) 次操作,分两种: 对某一个单位以 \(p\) 的概率造成 \(1\) ...

  9. ASPxGridView行的选中和行的焦点

    <SettingsBehavior AllowFocusedRow="true" /> 行的焦点,行的点击以及Command列按钮点击可以得到焦点 Styles-Foc ...

  10. python 3.x 爬虫基础---正则表达式

    python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 python 3.x 爬虫基础---Requer ...