zoukankan      html  css  js  c++  java
  • Linux 随记

    Tcp链接关闭

    在linux中,一切皆文件,本身socket就是一种文件类型,内核会为每一个打开的文件创建file结构并维护指向改结构的引用计数,每一个进程结构中都会维护本进程打开的文件数组,数组下标就是fd,内容就指向上面的file结构,close本身就可以用来操作所有的文件,做的事就是,删除本进程打开的文件数组中指定的fd项,并把指向的file结构中的引用计数减一,等引用计数为0的时候,就会调用内部包含的文件操作close,针对于socket,它内部的实现应该就是调用shutdown,只是参数是关闭读写端,从而比较粗暴的关闭连接。
    第二个问题,信号的处理有三种,默认处理,忽略处理,自定义处理。默认处理就是采用系统自定义的操作,大部分信号的默认处理都是杀死进程,忽略处理就是当做什么都没有发生。
     
    tw_reuse和SO_REUSEADDR区别
    tcp_tw_reuse 是内核选项,主要用在连接的发起方。TIME_WAIT 状态的连接创建时间超过 1 秒后,新的连接才可以被复用,注意,这里是连接的发起方;
    SO_REUSEADDR 是用户态的选项,SO_REUSEADDR 选项用来告诉操作系统内核,如果端口已被占用,但是 TCP 连接状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而 TCP 处于其他状态,重用端口时依旧得到“Address already in use”的错误信息。注意,这里一般都是连接的服务方。
     

    Linux中TCP报文重传

    net.ipv4.tcp_syn_retries = 6
    net.ipv4.tcp_synack_retries = 5
    对于SYN报文,重传时间由上面两个内核参数控制
    tcp_syn_retries Total_time = 2^0 + 2^1…+2^6=2^7-1=127s
    net.ipv4.tcp_synack_retries = 2^6-1=63s
    案例1:最常见的内核参数调优就是为了防止DoS(拒绝服务攻击)和DDoS(分布式拒绝服务攻击)。其中SYN Flood是当前最流行的DoS与DDoS的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来的海量请求连接的第一个握手包(SYN包),被攻击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。
    • 开启syncookies后,当SYN队列满了后,TCP会通过原地址端口,目的地址端口和时间戳打造一个特别的Sequence Number(又叫cookie发回去,如果是攻击者则不会有响应,如果是正常连接则把这个SYNCookie发回来,然后服务器端可以通过cookie建立连接(即使不在SYN队列)。
     
    案例2:在ha1.5版本的时候,由于还不支持热重载机制,当ha的配置文件变更时,一个临时的解决办法是通过开启SO_REUSEPORT,在ha reload过程中服务端直接拒绝所有的syn连接请求(比如通过iptables drop掉指定端口80的所有syn包),这样client端会根据上述内核参数在一定时间后重新发送syn请求,当服务端ha reload完成时,再允许syn连接
     
    net.ipv4.tcp_retries1
    net.ipv4.tcp_retries2
     
     

    快速重传

    快速重传机制「RFC5681」基于接收端的反馈信息来引发重传,而非重传计时器超时。
    刚刚提到过,基于计时器的重传往往要等待很长时间,而快速重传使用了很巧妙的方法来解决这个问题:服务器如果收到乱序的包,也给客户端回复 ACK,只不过是重复的 ACK。就拿刚刚的例子来说,收到乱序的包 6,7,8,9 时,服务器全都发 ACK = 5。这样,客户端就知道 5 发生了空缺。一般来说,如果客户端连续三次收到重复的 ACK,就会重传对应包,而不需要等到计时器超时。
     
    TCP用户超时UTO
    可以在通过setsockopt来设置TCP用户超时时长,表示:已发出的数据包若在指定的时间没有被确认,则关闭连接,相当于单次的tcp_keepalive
    需要注意的是该值会影响tcp报文重传机制中的RTO时间和待发送队列数据的最大保存时间
     
     
     
     

    在netstat中查看各种链接状态的计时器

    通过-o选项,查看Timer,如下
    keepalive (6176.47/0/0) 
    <1st field> <2nd field>

     

    该 1st field 可以有价值:
     
    keepalive - 当套接字的keepalive定时器为ON时
    on - 当套接字的重传定时器为ON时
    tme wait - 主动断开连接的一方所处的tw状态2MSL计时器 ,linux一般为30 * 2s
    off - 以上都不是ON
    该 2nd field 有三个子字段:
    (6176.47/0/0) -> (a/b/c)
    a =定时器值(a = keepalive定时器,当1st field =“keepalive”时; a =重传定时器,当1st field =“on”时)
    b =已发生的重新传输次数
    c =已发送的keepalive探测器的数量
     
     
     
    Linux IO多路复用
    为什么select/poll/epoll等IO多路复用一般不搭配阻塞IO:https://www.zhihu.com/question/37271342
     
    SIGPIPE信号理解
     
    在netfilet中注册一个hook handler:
      
    Linux中的进程描述符
    一个连接对应一个socket,每个socket都有独立的缓冲区(内核缓冲区):套接字也是文件,当server端监听到有连接时,应用程序会请求内核创建Socket,Socket创建好后会返回一个文件描述符给应用程序,当有数据包过来网卡时,内核会通过数据包的源端口,源ip,目的端口等在内核维护的一个ipcb双向链表中找到对应的Socket,并将数据包赋值到该Socket的缓冲区,应用程序请求读取Socket中的数据时,内核就会将数据拷贝到应用程序的内存空间,从而完成读取Socket数据
     
  • 相关阅读:
    [Swift]LeetCode1099. 小于 K 的两数之和 | Two Sum Less Than K
    转 用好HugePage,告别Linux性能故障
    子shell
    转 【推荐】 RAC 性能优化全攻略与经典案例剖析
    转 shell模拟数据库的读写
    c 语言写的高级Oracle&#174;数据库调优及监控工具
    crontab 在unix 没有执行。
    Oracle 云计算
    aix 推荐使用重启
    linux 打开FTP 功能
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/15533603.html
Copyright © 2011-2022 走看看