为编程爱好者分享易语言教程源码的资源网
好用的代理IP,游戏必备 ____广告位招租____ 服务器99/年 ____广告位招租____ ____广告位招租____ 挂机,建站服务器
好用的代理IP,游戏必备 ____广告位招租____ 服务器低至38/年 ____广告位招租____ ____广告位招租____ 挂机,建站服务器

网站首页 > 网络编程 > 其它综合 正文

性能优化(网络)篇

三叶资源网 2022-11-06 19:18:50 其它综合 269 ℃ 0 评论

个人在极客时间、工作经验、技术博客的总结。

网络收包流程

当一个网络帧到达网卡后,网卡会通过 DMA 方式,把这个网络包放到收包队列中;然后通过硬中断,告诉中断处理程序已经收到了网络包。接着,网卡中断处理程序会为网络帧分配内核数据结构(sk_buff),并将其拷贝到 sk_buff 缓冲区中;然后再通过软中断,通知内核收到了新的网络帧。接下来,内核协议栈从缓冲区中取出网络帧,并通过网络协议栈,从下到上逐层处理这个网络帧。

比如,在链路层检查报文的合法性,找出上层协议的类型(比如 IPv4 还是 IPv6),再去掉帧头、帧尾,然后交给网络层。网络层取出 IP 头,判断网络包下一步的走向,比如是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(比如 TCP 还是 UDP),去掉 IP 头,再交给传输层处理。传输层取出 TCP 头或者 UDP 头后,根据 < 源 IP、源端口、目的 IP、目的端口 > 四元组作为标识,找出对应的 Socket,并把数据拷贝到 Socket 的接收缓存中。最后,应用程序就可以使用 Socket 接口,读取到新接收到的数据了。

高并发优化

C10K(并发1w个请求)

I/O 模型优化

  • 使用非阻塞 I/O 和边缘触发通知,比如 epoll。
  • 使用异步 I/O(Asynchronous I/O,简称为 AIO)(windows推荐)

工作模型优化

  • 主进程 + 多个 worker 子进程/线程(如nginx)

这里要注意,accept() 和 epoll_wait() 调用,还存在一个惊群的问题。换句话说,当网络 I/O 事件发生时,多个进程被同时唤醒,但实际上只有一个进程来响应这个事件,其他被唤醒的进程都会重新休眠。其中,accept() 的惊群问题,已经在 Linux 2.6 中解决了;而 epoll 的问题,到了 Linux 4.5 ,才通过 EPOLLEXCLUSIVE 解决。为了避免惊群问题, Nginx 在每个 worker 进程中,都增加一个了全局锁(accept_mutex)。这些 worker 进程需要首先竞争到锁,只有竞争到锁的进程,才会加入到 epoll 中,这样就确保只有一个 worker 子进程被唤醒。

  • 监听到相同端口的多进程/线程 模型(nginx 1.9.1支持)。

在这种方式下,所有的进程都监听相同的接口,并且开启 SO_REUSEPORT 选项,由内核负责将请求负载均衡到这些监听进程中去,由于内核确保了只有一个进程被唤醒,就不会出现惊群问题了

C1000K(并发100w)

从c10K ~ c100K,通过epoll配合线程池,cpu、内存、网卡性能和容量的提升,容易达到。

那么,再进一步,C1000K 是不是也可以很容易就实现呢?这其实没有那么简单了。

首先从物理资源使用上来说,100万个请求需要大量的系统资源。比如,假设每个请求需要 16KB 内存的话,那么总共就需要大约 15 GB 内存。而从带宽上来说,假设只有 20% 活跃连接,即使每个连接只需要 1KB/s 的吞吐量,总共也需要 1.6 Gb/s 的吞吐量。千兆网卡显然满足不了这么大的吞吐量,所以还需要配置万兆网卡,或者基于多网卡 Bonding 承载更大的吞吐量。

其次,从软件资源上来说,大量的连接也会占用大量的软件资源,比如文件描述符的数量、连接状态的跟踪(CONNTRACK)、网络协议栈的缓存大小(比如套接字读写缓存、TCP 读写缓存)等等。

最后,大量请求带来的中断处理,也会带来非常高的处理成本。这样,就需要多队列网卡、中断负载均衡、CPU 绑定、RPS/RFS(软中断负载均衡到多个 CPU 核上),以及将网络包的处理卸载(Offload)到网络设备(如 TSO/GSO、LRO/GRO、VXLAN OFFLOAD)等各种硬件和软件的优化。

C1000K 的解决方法,本质上还是构建在 epoll 的非阻塞 I/O 模型上。只不过,除了 I/O 模型之外,还需要从应用程序到 Linux 内核、再到 CPU、内存和网络等各个层次的深度优化,特别是需要借助硬件,来卸载那些原来通过软件处理的大量功能。

C10M(并发1000w)

实际上,在 C1000K 问题中,各种软件、硬件的优化很可能都已经做到头了。特别是当升级完硬件(比如足够多的内存、带宽足够大的网卡、更多的网络功能卸载等)后,你可能会发现,无论你怎么优化应用程序和内核中的各种网络参数,想实现 1000 万请求的并发,都是极其困难的。究其根本,还是 Linux 内核协议栈做了太多太繁重的工作。从网卡中断带来的硬中断处理程序开始,到软中断中的各层网络协议处理,最后再到应用程序,这个路径实在是太长了,就会导致网络包的处理优化,到了一定程度后,就无法更进一步了。要解决这个问题,最重要就是跳过内核协议栈的冗长路径,把网络包直接送到要处理的应用程序那里去。这里有两种常见的机制,DPDK 和 XDP。

调优

应用层

优化报文大小。比如压缩、pb序列化

报文合并,减少交互次数。比如登陆时多个消息可以合并为一次请求消息

最近1公里。将接入网关部署在用户最近的机房、云主机,通过域名解析、运营商匹配、大数据分析、客户端测试、复杂均衡等策略将用户按照最近原则分配到最近的接入网关。

ssl 协议是很耗性能的。应当了解接入网关最大的访问量

使用httpdns、powerdns。 普通的dns解析也会导致连接出现异常

传输层(tcp)

  • tcp缓存区设置 (tcp_moderate_revbuf、ipv4.tcp_rmem、ipv4.tcp_wmem)
  • tcp的两个积压队列(tcp_max_syn_backlog、net.core.somaxconn)
  • 开启syncookies字段,但是会占用tcp头的timestamps字段
  • Google 提出了 TCP fast open 方案(FTO)
  • 设备的积压队列(net_core.netdev_max_backlog)
  • tcp阻塞控制算法(ipv4.tcp_congestion_control)
  • 重传次数优化:tcp_syn_retries、tcp_synack_retries
  • 选择性确认(SACK/FACK):允许tcp确认非连续的包,以减少需要重传输的数量
  • 延迟ack:推迟最多500ms发送ack,从而可以合并多个ack;减少网络包的数量
  • 慢启动窗口:设置为10mss
  • Nagle算法
  • time_wait重复利用:设置tcp_tw_reuse=1,tcp_timestamps=1,使用tcp新版本的时间搓字段,它允许作为客户端的新连接,在安全条件下使用 TIME_WAIT 状态下的端口。
  • 网络接口:对于10Gbe NIC是必须的(ifconfig etho exqueuelen 10000)
  • 资源控制:控制组的网络优先级

拥塞控制算法

TCP拥塞控制算法(Reno、Bio、Cubic、tahoe)

  • 基于丢包策略
  • 延时不可控

GCC

  • webrtc默认,基于时延+丢包
  • 带宽估计不准确,低带宽过降
  • 与tcp竞争,过度退让
  • 时延抖动场景,带宽估计波动大

BBR

  • google提出,演进到第二版
  • 算法核心是尽量不排队、低延时
  • 带宽估计准确
  • 与tcp竞争,不吃亏


工具

tcpdump、wireshark

ping

netstat

ifconfig

traceroute

sar

nethogs

iftop

hping3

dig

ddos攻击的一些知识

从攻击的原理上来看,DDoS 可以分为下面几种类型。

第一种,耗尽带宽。无论是服务器还是路由器、交换机等网络设备,带宽都有固定的上限。带宽耗尽后,就会发生网络拥堵,从而无法传输其他正常的网络报文。

第二种,耗尽操作系统的资源。网络服务的正常运行,都需要一定的系统资源,像是 CPU、内存等物理资源,以及连接表等软件资源。一旦资源耗尽,系统就不能处理其他正常的网络连接。

第三种,消耗应用程序的运行资源。应用程序的运行,通常还需要跟其他的资源或系统交互。如果应用程序一直忙于处理无效请求,也会导致正常请求的处理变慢,甚至得不到响应。

为什么不是解决 DDoS ,而只是缓解呢?实际上,当 DDoS 报文到达服务器后,Linux 提供的机制只能缓解,而无法彻底解决。即使像是 SYN Flood 这样的小包攻击,其巨大的 PPS ,也会导致 Linux 内核消耗大量资源,进而导致其他网络报文的处理缓慢。虽然你可以调整内核参数,缓解 DDoS 带来的性能问题,但无法彻底解决它。

Linux 内核中冗长的协议栈,在 PPS 很大时,就是一个巨大的负担。对 DDoS 攻击来说,也是一样的道理。

比如,你可以基于 XDP 或者 DPDK,构建 DDoS 方案,在内核网络协议栈前,或者跳过内核协议栈,来识别并丢弃 DDoS 报文,避免 DDoS 对系统其他资源的消耗。不过,对于流量型的 DDoS 来说,当服务器的带宽被耗尽后,在服务器内部处理就无能为力了。这时,只能在服务器外部的网络设备中,设法识别并阻断流量(当然前提是网络设备要能扛住流量攻击)。比如,购置专业的入侵检测和防御设备,配置流量清洗设备阻断恶意流量等。既然 DDoS 这么难防御,这是不是说明, Linux 服务器内部压根儿就不关注这一点,而是全部交给专业的网络设备来处理呢?当然不是,因为 DDoS 并不一定是因为大流量或者大 PPS,有时候,慢速的请求也会带来巨大的性能下降(这种情况称为慢速 DDoS)。

比如,很多针对应用程序的攻击,都会伪装成正常用户来请求资源。这种情况下,请求流量可能本身并不大,但响应流量却可能很大,并且应用程序内部也很可能要耗费大量资源处理。这时,就需要应用程序考虑识别,并尽早拒绝掉这些恶意流量,比如合理利用缓存、增加 WAF(Web Application Firewall)、使用 CDN 等等。

可靠udp

kcp

quic

Tags:

来源:三叶资源网,欢迎分享,公众号:iisanye,(三叶资源网⑤群:21414575

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

百度站内搜索
关注微信公众号
三叶资源网⑤群:三叶资源网⑤群

网站分类
随机tag
精易模块CryptoJS加密模块卡密生成系统WORD文件加图片DiscuzEXUI缓动登陆界面源码微博热搜榜火山视窗软件折线图seoEXDUI4.1例程源码文本型行内元素WMF图片转BMP编码转换工具箱快速启动名片点赞文本颜色
最新评论