-
2019-08-12 00:29:54
前言
tcpkali在github项目的地址如下:https://github.com/satori-com/tcpkali。
本文详述TCPkali的基本测试用法。TCPkali是一个可以用来测试四层TCP协议,七层HTTP(s)协议和websocket协议的测试工具。当然这个工具最主要的优点用的还是在于能够独立的进行TCP和websocket测试。
安装
tcpkali可以支持在Mac OS,linux和UNIX上安装。博主在实操中所使用linux操作系统,这里主要详述centos7.x版本中的安装。
包安装
在tcpkali的github上推荐使用包安装的方法。但是博主亲自实验之后发现其实在国内包安装没有源码编译安装好用。centos操作系统中要直接安装tcpkali的软件包,需要用到nix工具。而安装nix安装管理工具之后,再去安装tcpkali的包会去nix国外的源去下载,经常访问超时导致安装失败。所以笔者不建议国内的玩家使用这种方式。这里仅给出安装所需的操作步骤
#安装bzip解压工具 yum -y install bzip2* #访问nix官网下载安装nix安装管理工具,nix是类yum的安装包管理工具,可以通过nix安装可用的包。 curl https://nixos.org/nix/install | sh #通过nix安装tcpkali的可执行的软件包 nix-env -i tcpkali
源码编译安装
在国内笔者比较推荐使用编译安装的方式在centos的操作系统中安装tcpkali工具。其主要步骤如下
#以最小化安装centos7.5操作系统为例,yum列出了所需要安装的软件包。主要下载所需的编译软件,git安装工具,vim编辑工具。 yum install -y git autoconf automake libtool bison flex gcc-c++ ncurses-devel vim #在git上拉取所tcpkali的源码 git clone https://github.com/satori-com/tcpkali.git #切换到tcpkali的下载文件目录 cd tcpkali/ #检测configure文件并更新已经生成的配置文件 test -f configure || autoreconf -i #编译安装前执行配置文件 ./configure #编译安装,安装完成之后可系统中就可以tab出tcpkali的命令 make && make install
tcpkali命令参数详解
通用配置
-h, --help : 打印出tcpkali的帮助文档并退出。
–version : 打印出tcpkali的版本号并退出
-v, --verbose level :详细打印输出结果,可以增加-v参数的次数来表示详细信息程度。例如想打印更为详细的输出结果可以使用“-vvv”。也可以使用“–verbose 3”来表示打印输出信息的详细程度。默认的详细信息程度从0-3。
-d, --dump-one : 选择在任意的一个链接上打印出该链接输入或者输出的数据。当该链接被关闭时,将会使用其他链接来进行转储信息。主要用来诊断链接中收发信息是否符合预期。
–dump-one-in : 只转储单个连接上的输入数据。
–dump-one-out : 只转储单个连接上的输出数据。
–dump-{all,all-in,all-out} : 转储所有链接上的输入输出数据。
–write-combine=off : 单独发送消息而不是批量的写入消息. 该参数设置为off则暗示着 --nagle=off, 如果没有在命令行显示调用将其关闭,这该参数默认是开启的。
-w, --workers N : 要使用的并行线程数。默认值是根据需要使用尽可能多的内核,最多使用系统中检测到的内核数量。网络堆栈参数的设置
–nagle=on|off : 通过使用setsockopt()设置TCP_NODELAY套接字选项来控制Nagle算法。默认情况下根本不调用setsockopt(),这使得Nagle在大多数系统上都是启用的。
–rcvbuf SizeBytes : 设置TCP接收缓冲区(使用setsockopt()设置SO_RCVBUF套接字选项)。此选项对具有自动接收缓冲区管理的某些系统无效。如果rcvbuf不起作用,tcpkali将打印一条消息。
–sndbuf SizeBytes : 设置TCP发送缓冲区(使用setsockopt()设置SO_SNDBUF套接字选项)。此选项对具有自动接收缓冲区管理的某些系统无效。如果sndvbuf不起作用,tcpkali将打印一条消息。
–source-ip IP : 默认情况下,tcpkali自动检测当前主机端口并使用所有可用接口连接到目标主机。这个默认行为允许tcpkali打开到目的地的超过64k个连接。使用**–source- IP 通过指定要使用的特定源IP来覆盖此行为。多次指定–source-ip**选项将构建要使用的源ip列表。运行测试时设置
–ws, --websocket : 使用RFC6455规范进行WebSocket通信传输。
–ssl : 为客户端和服务器端连接启用传输层安全性(TLS,以前称为SSL)。
–ssl-cert filename : 使用X.509证书来进行TLS加密传输。 默认 “cert.pem”。
–ssl-key filename :使用私钥文件来进行TLS加密传输。默认 “key.pem”。
-H, --header : 添加指定HTTP包头到WebSocket握手中。
-c, --connections N : 打开到目标的并发连接数。默认值为1。
–connect-rate Rate : 限制每秒新连接的数量。默认值是每秒100个连接。
–connect-timeout Time : 限制尝试连接中花费的时间。默认值是1秒。
–channel-lifetime Time : 在设置的时间秒数后关闭每个连接。
–channel-bandwidth-upstream Bandwidth : 限制单个连接的上行带宽。
–channel-bandwidth-downstream Bandwidth : 限制单个连接的下行带宽。
-l, --listen-port port : tcpkali作为服务端接收指定端口上的链接。
–listen-mode=silent|active : 在接收到新建连接时执行操作。在静默模式下(silent),tcpkali不发送数据并忽略接收到的数据,这是默认值。在活动模式下(active),tcpkali向连接的客户机发送消息。消息需要由message参数指定。
-T, --duration Time : 退出并在指定的时间之后打印最终统计信息。默认为10秒(-T10s)。
–delay-send Time : 将发送字节延迟到指定的时间量。网络流量选项
-e, --unescape-message-args : 如在tcpkali命令行上使用了-m、-f或其他发送了流量内容的指定选项,则发送的消息数据不会进行转义。将\xxx序列转换为具有相应八进制值的字节,将\n转换为换行符,等等。
-1, --first-message : 首先发送此消息,在每个新建连接开始时发送一次。可以多次指定此选项,以便在每个连接开始时发送几个初始消息。如果–websocket选项被给出使用,每个消息都被包装到它自己的websocket框架中。
–first-message-file filename : 从文件中读取消息,并在每个连接开始时发送一次。可以多次指定此选项。
-m, --message string : 从文件中读取消息,并在每个连接开始时发送一次。可以多次指定此选项.
–message-stop string : 如果在接收到的字节流中遇到给定字符串,则终止tcpkali。
-f, --message-file filename : 重复地将从文件读取的消息发送到目标地址。可以多次指定此选项。
-r, --message-rate Rate : 在连接中每秒发送的消息数。tcpkali试图保留消息边界。此设置与–channel-bandwidth-upstream选项互不兼容,因为它们都控制消息发送速率。
-r, --message-rate @Latency : 不要指定消息速率,而是尝试计算不会导致超过给定消息延迟的最大消息速率。需要设置“ --latency-marker”延迟标记选项。示例:
tcpkali -m "PING" --latency-marker "PONG" -r @100ms
时延计算选项
tcpkali可以测量TCP连接延迟,tcpkali会标记指定接收特定的字节。当接收到特定标记的第一个字节时计算时间和请求-响应延迟。
–latency-connect : 测量TCP连接延迟。
–latency-first-byte : 测量第一个字节的延迟。只适用于活动套接字。
tcpkali通过重复记录每次发送消息的时间(由-m或-f指定)与在下行流量中观察到延迟标记的时间(由–latency-marker标记设置)之间的时间差来度量请求-响应延迟。
–latency-marker string : 指定要在数据流中查找的每个消息的特定字符序列。
–latency-marker-skip N : 忽略掉前N个特定字符值,该字符由–latency-marker标记。
–latency-percentiles list : 报告指定百分比的延迟。该选项采用逗号分隔的浮点值列表。平均值和最大值可以使用 --latency-percentiles 50,100报告。默认是95、99、99.5。
00
–message-marker : 被动模式下的检查或消息标记。给定此选项,tcpkali将检测{message.marker}字节序列,并将计算消息速率(以每秒消息数为单位)和消息到达延迟。在活动模式下,通过隐式启动{message.marker}}表达式来计算消息速率。STATSD选项
StatsD 就是一个简单的网络守护进程,基于 Node.js 平台,通过 UDP 或者 TCP 方式侦听各种统计信息,包括计数器和定时器,并发送聚合信息到后端服务
–statsd : 启用StatsD输出。默认情况下禁用StatsD输出。
–statsd-host host : 将数据发送到指定的statsd主机上。默认是本地。
–statsd-port port : 使用StatsD端口。默认是8125。
–statsd-namespace string : 指定命名空间,默认是“tcpkali”。
–statsd-latency-window Time : 默认情况下,测量延时是在tcpkali运行的整个持续时间(由–duration或-T设置)内进行。此选项指示tcpkali每次将延迟数据刷新到StatsD并重新开始测量延迟的时间。在tcpkali整个运行过程中,用户界面中显示的延迟仍然被收集。操作系统优化
使用tcpkali需要关注的一点是如何打开想要的并发连接数。不难想象如果一个机器有一张网卡,网卡上配置了一个IP。那么这台机器和目标“IP:端口”所能建立的并发链接数就可以达到6.4W。如果有多个网卡的话那么就可以达到十万以上的并发。在执行压测之前需要对系统进行一些优化使其能够打开你需要并发链接。
- 放开对用户限制打开的最大文件数
vim /etc/security/limit.conf * soft core unlimited * hard core unlimited * soft nofile 1024000 * hard nofile 1024000 #添加如下配置项,使root用户的最大文件数可到百万级别 root soft nofile 1024000 root hard nofile 1024000
- 设置sysctl.conf配置内核参数
vim sysctl.conf #设置系统可打开的最大文件句柄数,该参数与第一步修改的用户可打开文件数相互作用 fs.file-max=130000 #这里给出的配置公式是:10000+2*N(N为你想打开的最大连接数) net.ipv4.tcp_max_orphans=60000 #For load-generating clients. net.ipv4.ip_local_port_range=1024 65535 #放开系统端口限制,可以允许使用1024之后65535之前的任意端口 net.ipv4.tcp_tw_reuse=1 #开启端口复用技术
tcpkali压测示例
就笔者实际使用tcpkali经验,tcpkali可以执行以下三种测试任务:
- 对http(s)进行压测,测量固定并发,消息速率下的带宽吞吐和时延。
- 对websocket服务进行压测,测量固定并发,消息速率下的带宽吞吐和时延。
- 通过搭建tcpkali服务端和客户端,对四层tcp协议的负载均衡器进行固定并发,消息速率下的带宽吞吐和时延性能测试。
压测webserver
首先看一下tcpkali如何压测webserver。这里压测端是一个使用nginx搭建的静态页面webserver。tcpkali作为压力端虚机上有三张网卡,ip分别为10.130.1.71/24,10.130.1.11/24,10.130.1.110/24。nginx服务端只有一张网卡ip为10.130.1.217/24。
客户端使用单网卡压测:
#这里发送的消息转义之后就是一个GET请求 # tcpkali --connections 6000 --connect-rate 6000 -T 120s -em "GET / HTTP/1.1\r\nHost: 10.130.1.217\r\n\r\n" 10.130.1.217:80 Destination: [10.130.1.217]:80 Interface eth0 address [10.130.1.71]:0 Using interface eth0 to connect to [10.130.1.217]:80 Ramped up to 6000 connections. ? Traffic 220.537↓, 16363.188↑ Mbps (conns 0↓ 4262↑ 1736⇡; seen 21656) 等待测试执行结束之后打印出结果如下: # tcpkali --connections 6000 --connect-rate 6000 -T 120s -em "GET / HTTP/1.1\r\nHost: 10.130.1.217\r\n\r\n" 10.130.1.217:80 Destination: [10.130.1.217]:80 Interface eth0 address [10.130.1.71]:0 Using interface eth0 to connect to [10.130.1.217]:80 Ramped up to 6000 connections. Total data sent: 34716.8 MiB (36403218124 bytes) Total data received: 1535.0 MiB (1609569208 bytes) Bandwidth per channel: 0.479⇅ Mbps (59.9 kBps) Aggregate bandwidth: 107.304↓, 2426.878↑ Mbps Packet rate estimate: 15806.7↓, 207872.1↑ (2↓, 42↑ TCP MSS/op) Test duration: 120 s.
nginx服务端观测到并发连接数如下:
可以看到在压测七层webserver时,压力端指定的并发连接数并不能达到,主要原因是有nginx服务端关闭连接造成。Total: 8534 (kernel 8552) TCP: 18313 (estab 816, closed 7288, orphaned 2809, synrecv 0, timewait 7288/0), ports 0 Transport Total IP IPv6 * 8552 - - RAW 0 0 0 UDP 8 5 3 TCP 11025 11019 6 INET 11033 11024 9 FRAG 0 0 0
使用tcpkali服务端压测四层tcp连接
服务器端监听12345端口,接收到的包不做回应并丢弃:
#tcpkali -l 12345 -T 720 Every 1.0s: ss -s Sun Aug 11 16:11:55 2019 #检测到实际建立链接的并发量也就在6.4W左右 Total: 64178 (kernel 64311) TCP: 63864 (estab 63839, closed 0, orphaned 2, synrecv 0, timewait 0/0), ports 0 Transport Total IP IPv6 * 64311 - - RAW 0 0 0 UDP 8 5 3 TCP 63864 63854 10 INET 63872 63859 13 FRAG 0 0 0
客户端tcpkali虚机上有三张网卡,ip分别为10.130.1.71/24,10.130.1.11/24,10.130.1.110/24。使用–source-ip参数分别指定三张网卡来发起并发链接,每个连接每秒钟传输一个"PING"消息。发现客户端仍然只能建立6.4W个链接。使用-vvv打印详细的建立链接过程发现仍然是用三个网卡与对端建立链接的。但是链接超时。
# tcpkali --source-ip 10.130.1.71 --source-ip 10.130.1.11 --source-ip 10.130.1.110 --connections 180000 --connect-rate 100000 -m "PING" --message-rate 1 -T 120s 10.130.1.217:12345 WARNING: Will not be able to open 180000 simultaneous connections since "/proc/sys/net/ipv4/ip_local_port_range" specifies too narrow range [1025..65534]. Destination: [10.130.1.217]:12345 Source IP: [10.130.1.71]:0 Source IP: [10.130.1.11]:0 Source IP: [10.130.1.110]:0 |================>--------------------------------| 62437 of 180000 (358005) Connection [10.130.1.11]:48233 -> [10.130.1.217]:12345 opened as 198 Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection [10.130.1.11]:43493 -> [10.130.1.217]:12345 opened as 207 Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection [10.130.1.71]:10702 -> [10.130.1.217]:12345 opened as 188 Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection [10.130.1.110]:9942 -> [10.130.1.217]:12345 opened as 213 Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection to [10.130.1.217]:12345 is being closed: Connection timed out Connection [10.130.1.71]:53393 -> [10.130.1.217]:12345 opened as 216
使用多网卡压测
这里笔者作死去压测百度的公网,然后居然能压测上…
tcpkali --source-ip 10.130.1.71 --source-ip 10.130.1.11 --source-ip 10.130.1.110 --connections 80000 --connect-rate 1000000 -T 120s www.baidu.com:80 WARNING: Will not be able to open 80000 simultaneous connections since "/proc/sys/net/ipv4/ip_local_port_range" specifies too narrow range [1025..65534]. Destination: [180.97.33.108]:80 Destination: [180.97.33.107]:80 Source IP: [10.130.1.71]:0 Source IP: [10.130.1.11]:0 Source IP: [10.130.1.110]:0 Ramped up to 80000 connections. ? Traffic 0.000↓, 0.000↑ Mbps (conns 0↓ 4015↑ 75985⇡; seen 2042906)
在本地使用tcpkali监听12345端口,压测127.0.0.1本地环回IP地址。
执行压测命令
# tcpkali --source-ip 10.130.1.71 --source-ip 10.130.1.11 --source-ip 10.130.1.110 --connections 180000 --connect-rate 1000000 -T 120s 127.0.0.1:12345 WARNING: Will not be able to open 180000 simultaneous connections since "/proc/sys/net/ipv4/ip_local_port_range" specifies too narrow range [1025..65534]. Destination: [127.0.0.1]:12345 Source IP: [10.130.1.71]:0 Source IP: [10.130.1.11]:0 Source IP: [10.130.1.110]:0 Ramped up to 180000 connections. ? Traffic 0.000↓, 0.000↑ Mbps (conns 0↓ 139753↑ 45446⇡; seen 843272)
执行监听端口命令并观察并发连接数
# tcpkali -l 12345 -T 720 Listen on: [0.0.0.0]:12345 Listen on: [::]:12345 ? Traffic 0.000↓, 0.000↑ Mbps (conns 130903↓ 0↑ 0⇡; seen 112385088) #watch -n 1 "ss -s" Every 1.0s: ss -s Mon Aug 12 00:23:35 2019 Total: 300915 (kernel 304725) TCP: 308814 (estab 278546, closed 6, orphaned 126, synrecv 0, timewait 6/0), ports 0 Transport Total IP IPv6 * 304725 - - RAW 2 0 2 UDP 3 3 0 TCP 308808 308773 35 INET 308813 308776 37 FRAG 0 0 0
tcpkali工具优劣分析
优点
- 可以当做服务端的测试工具。
tcpkali主要的优势就在于它是C/S架构的测试工具。它可以在一台服务器上监听固定端口的所收到的流量并可以选择对接收到的信息做回应。作为服务器tcpkali可以按照测试计划接受压力端发来的请求包并按照你输入的参数对包做丢弃或者回应。你可以将TCPkali拿来单独作为测试工具使用对服务器建立连接发起请求。你也可以使用tcpkal作为服务器建监听某个端口,然后使用tcpkali的客户端对该监听端口发起请求。这种模式的主要好处在于你可以针对网络系统中的四层负载均衡器或者代理服务器性能进行测试。 - 可以测试使用TCP和websocket协议,固定并发下的带宽和时延。
- 对流量和时延的控制,可以说很少有工具可以针对每个链接来控制流量和时延。
- tcpkali客户端如有多个IP地址的情况下,可以指定一个或者若干个系统已经配置的IP地址来对服务端发起请求。如果想要测试四层负载均衡器,代理服务器的并发性能。根据四层传输层协议五元组,目的端提供服务的端口与IP不变的情况下,如果你客户端无法启用更多的IP地址和端口,那所能建立起来的并发链接是有限(6.4W个左右就是极限,系统保留0-1024端口号,而端口号可用上限到65535)。但是笔者认为这个功能不是非常好用
缺点
- tcpkali作为一个性能测试工具而言是很好,但是作为基准测试工具来说就另当别论了。最主要的一点就是tcpkali客户端和服务端的执行时间是可以单独设定的。所以最后反馈的报告结果上看服务端的吞吐和客户端发送的吞吐存在一定的误差。如果将tcpkali服务器端的测试执行时间大于tcpkali客户端的测试时间。则服务端的每秒处理包速率会相对较低。
- tcpkali不具备分布式的能力,虽然它可以在单机上利用多IP来制造高并发,但这非常考验压力机的机器性能。
更多相关内容 -
反向代理连接数上限为什么是65535
2021-09-23 01:01:45无论是Nginx还是百度开源的BFE,或是其它四层/七层流量代理,都会存在Socket连接数上限问题。此连接数上限问题,指的是七层流量代理与后端服务建立的连接,而非七层流量代理与客户端建立...无论是Nginx还是百度开源的BFE,或是其它四层/七层流量代理,都会存在Socket连接数上限问题。
此连接数上限问题,指的是七层流量代理与后端服务建立的连接,而非七层流量代理与客户端建立的连接。
由于客户端与服务端建立连接,客户端需要占用一个端口号,这个端口号由系统分配,在Linux系统下,最大可用端口号为65535。
对于七层流量代理与后端服务间的通信而言,七层流量代理属于客户端,因此七层流量代理与后端服务建立的连接数是有限的。
如果是长连接,那么连接数理论上上限为65535。但由于一些系统进程会占用一部分端口号(如22端口),因此上限会少于65535。
这种不可修改的缺陷只能通过“低配置多实例”去增大连接数上限。
对于长连接而言,会有连接数上限问题,那么对于短连接是否就不存在这个问题了呢?
短链接,即创建连接后发起一次请并等待响应后就立即关闭的连接。但由于TCP协议存在四次挥手过程,因此,连接关闭后并不会马上释放端口,这个过程有个时间窗口,Linux下这个时间窗口默认大小为120秒。这么长的时间窗口,请求量达到546QPS以上就很容易导致无可用端口。
要理解这个问题,我们首先要理解TCP协议的四次挥手过程:
1、客户端向服务端发送标识FIN=1的数据包,告诉服务端,客户端不会再有会话数据发送,此时客户端的状态为FIN_WAIT_1;
2、服务端收到FIN请求后,向客户端发送ACK应答数据包,客户端收到ACK后状态变为FIN_WAIT_2,服务端状态为CLOSE_WAIT;
3、服务端向客户端发送标识FIN=1的数据包,告诉客户端,服务端不会再有会话数据发送。发送成功后,服务端状态为LAST_ACK;
4、客户端收到FIN请求后向服务端发送ACK应答数据包,此后客户端状态为TIME_WAIT,服务端收到ACK后,状态变为CLOSED,客户端等待2MSL后变为CLOSED。
从四次挥手过程可以看出,客户端的TIME_WAIT状态会持续2MSL才会变成CLOSED。
MSL(Maximum Segment Lifetime)即报文最大生存时间,是任何报文在网络上存活的最长时间,超过这个时间报文将被丢弃。因此,在2MSL时间内,该连接占用的端口将处于空闲且不可被使用状态。在Linux系统下,MSL默认值为60秒,2MSL即120秒。
为什么TIME_WAIT要维持2MSL时长呢?
1、第4次挥手是客户端发送ACK到服务端,如果发送完成后客户端就直接就关闭连接,如果网络抖动导致服务端未收到ACK,服务端就不会关闭连接。而等待2MSL时长期间,服务端没有收到应答就会继续发送FIN请求。
2、如果不等待2MSL,客户端关闭连接后端口就可能会被重用,如果再次用这个端口建立与服务器的连接,前后两个连接四元组(src ip+port,dec ip+port)相同,服务端就会认为是前一个连接,数据包会产生干扰。
-
Nginx应用:配置文件详解、反向代理、负载均衡,做限流、缓存、黑白名单
2019-07-22 19:23:56Nginx应该是现在最火的web和反向代理服务器,没有之一。她是一款诞生于俄罗斯的高性能web服务器,尤其在高并发情况下,相较Apache,有优异的表现。那除了负载均衡,她还有什么其他的用途呢,下面我们来看下。 一、...Nginx应该是现在最火的web和反向代理服务器,没有之一。她是一款诞生于俄罗斯的高性能web服务器,尤其在高并发情况下,相较Apache,有优异的表现。那除了负载均衡,她还有什么其他的用途呢,下面我们来看下。
一、静态代理
Nginx擅长处理静态文件,是非常好的图片、文件服务器。
把所有的静态资源的放到nginx上,可以使应用动静分离,性能更好。
二、负载均衡
Nginx通过反向代理可以实现服务的负载均衡,避免了服务器单节点故障,把请求按照一定的策略转发到不同的服务器上,达到负载的效果。常用的负载均衡策略有
1、轮询
将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。
2、加权轮询
不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。
给配置高、负载低的机器配置更高的权重,让其处理更多的请;
而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。
3、ip_hash(源地址哈希法)
根据获取客户端的IP地址,通过哈希函数计算得到一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。
采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。
4、随机
通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。
5、least_conn(最小连接数法)
由于后端服务器的配置不尽相同,对于请求的处理有快有慢,最小连接数法根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。
三、限流
Nginx的限流模块,是基于漏桶算法实现的,在高并发的场景下非常实用。
1、配置参数
1)limit_req_zone定义在http块中,$binary_remote_addr 表示保存客户端IP地址的二进制形式。
2)Zone定义IP状态及URL访问频率的共享内存区域。zone=keyword标识区域的名字,以及冒号后面跟区域大小。16000个IP地址的状态信息约1MB,所以示例中区域可以存储160000个IP地址。
3)Rate定义最大请求速率。示例中速率不能超过每秒100个请求。
2、设置限流
burst排队大小,nodelay不限制单个请求间的时间。
四、缓存
1、浏览器缓存,静态资源缓存用expire。
2、代理层缓存
五、黑白名单
1、不限流白名单
2、黑名单
六、Nginx配置文件结构
nginx 文件结构
... #全局块 events { #events块 ... } http #http块 { ... #http全局块 server #server块 { ... #server全局块 location [PATTERN] #location块 { ... } location [PATTERN] { ... } } server { ... } ... #http全局块 }
- 1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
- 2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
- 3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
- 4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
- 5、location块:配置请求的路由,以及各种页面的处理情况。
nginx 详细说明
########### 每个指令必须有分号结束。################# #user administrator administrators; #配置用户或者组,默认为nobody nobody。 #worker_processes 2; #允许生成的进程数,默认为1 #pid /nginx/pid/nginx.pid; #指定nginx进程运行文件存放地址 error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg events { accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off #use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport worker_connections 1024; #最大连接数,默认为512 } http { include mime.types; #文件扩展名与文件类型映射表 default_type application/octet-stream; #默认文件类型,默认为text/plain #access_log off; #取消服务日志 log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式 access_log log/access.log myFormat; #combined为日志格式的默认值 sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。 sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。 keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。 upstream mysvr { server 127.0.0.1:7878; server 192.168.10.121:3333 backup; #热备 } error_page 404 https://www.baidu.com; #错误页 server { keepalive_requests 120; #单连接请求上限次数。 listen 4545; #监听端口 server_name 127.0.0.1; #监听地址 location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。 #root path; #根目录 #index vv.txt; #设置默认页 proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表 deny 127.0.0.1; #拒绝的ip allow 172.18.5.54; #允许的ip } } }
七、反向代理
正向代理代理的是客户端,我们需要在客户端进行一些代理的设置。而反向代理代理的是服务器,作为客户端的我们是无法感知到服务器的真实存在的。
总结起来还是一句话:正向代理代理客户端,反向代理代理服务器。
Nginx 反向代理相关指令介绍
①、listen
该指令用于配置网络监听。主要有如下三种配置语法结构:
一、配置监听的IP地址
listen address[:port] [default_server] [setfib=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [deferred] [accept_filter=filter] [bind] [ssl];
二、配置监听端口
listen port[default_server] [setfib=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [ssl];
三、配置 UNIX Domain Socket
listen unix:path [default_server] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ssl];
上面的配置看似比较复杂,其实使用起来是比较简单的:
listen *:80 | *:8080 #监听所有80端口和8080端口 listen IP_address:port #监听指定的地址和端口号 listen IP_address #监听指定ip地址所有端口 listen port #监听该端口的所有IP连接
下面分别解释每个选项的具体含义:
1、address:IP地址,如果是 IPV6地址,需要使用中括号[] 括起来,比如[fe80::1]等。
2、port:端口号,如果只定义了IP地址,没有定义端口号,那么就使用80端口。
3、path:socket文件路径,如 var/run/nginx.sock等。
4、default_server:标识符,将此虚拟主机设置为 address:port 的默认主机。(在 nginx-0.8.21 之前使用的是 default 指令)
5、 setfib=number:Nginx-0.8.44 中使用这个变量监听 socket 关联路由表,目前只对 FreeBSD 起作用,不常用。
6、backlog=number:设置监听函数listen()最多允许多少网络连接同时处于挂起状态,在 FreeBSD 中默认为 -1,其他平台默认为511.
7、rcvbuf=size:设置监听socket接收缓存区大小。
8、sndbuf=size:设置监听socket发送缓存区大小。
9、deferred:标识符,将accept()设置为Deferred模式。
10、accept_filter=filter:设置监听端口对所有请求进行过滤,被过滤的内容不能被接收和处理,本指令只在 FreeBSD 和 NetBSD 5.0+ 平台下有效。filter 可以设置为 dataready 或 httpready 。
11、bind:标识符,使用独立的bind() 处理此address:port,一般情况下,对于端口相同而IP地址不同的多个连接,Nginx 服务器将只使用一个监听指令,并使用 bind() 处理端口相同的所有连接。
12、ssl:标识符,设置会话连接使用 SSL模式进行,此标识符和Nginx服务器提供的 HTTPS 服务有关。
②、server_name
该指令用于虚拟主机的配置。通常分为以下两种:
1、基于名称的虚拟主机配置
语法格式如下:
server_name name ...;
一、对于name 来说,可以只有一个名称,也可以有多个名称,中间用空格隔开。而每个名字由两段或者三段组成,每段之间用“.”隔开。
server_name 123.com www.123.com
二、可以使用通配符“*”,但通配符只能用在由三段字符组成的首段或者尾端,或者由两端字符组成的尾端。
server_name *.123.com www.123.*
三、还可以使用正则表达式,用“~”作为正则表达式字符串的开始标记。
server_name ~^www\d+\.123\.com$;
该表达式“~”表示匹配正则表达式,以www开头(“^”表示开头),紧跟着一个0~9之间的数字,在紧跟“.123.co”,最后跟着“m”($表示结尾)
以上匹配的顺序优先级如下:
准确匹配 server_name 配符在开始时匹配 server_name 成功 通配符在结尾时匹配 server_name 成功 正则表达式匹配 server_name 成功
2、基于 IP 地址的虚拟主机配置
语法结构和基于域名匹配一样,而且不需要考虑通配符和正则表达式的问题。
server_name 192.168.1.1
③、location
该指令用于匹配 URL。
语法如下:
location [ = | ~ | ~* | ^~] uri { }
1、= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
2、~:用于表示 uri 包含正则表达式,并且区分大小写。
3、~*:用于表示 uri 包含正则表达式,并且不区分大小写。
4、^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。
注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。
④、proxy_pass
该指令用于设置被代理服务器的地址。可以是主机名称、IP地址加端口号的形式。
语法结构如下:
proxy_pass URL;
URL 为被代理服务器的地址,可以包含传输协议、主机名称或IP地址加端口号,URI等。
proxy_pass http://www.123.com/uri;
⑤、index
该指令用于设置网站的默认首页。
语法为:
index filename ...;
后面的文件名称可以有多个,中间用空格隔开。
index index.html index.jsp;
通常该指令有两个作用:第一个是用户在请求访问网站时,请求地址可以不写首页名称;第二个是可以对一个请求,根据请求内容而设置不同的首页。
参考链接:
https://cloud.tencent.com/developer/article/1467167
-
02 网络面经:一个TCP连接可以发送多少个HTTP请求?
2021-08-25 09:27:13我们知道TCP协议对应于传输层,HTTP协议对应于应用层。WEB项目中,HTTP协议是建立在TCP的基础上的。 最初浏览器从服务器加载一个网页,会发起一个HTTP请求,这时需要先建立一个TCP连接。当本次数据请求完毕之后,会...一个TCP连接可以发送多少个HTTP请求?就这这个问题,我们聊聊TCP、HTTP以及浏览器之间的关系和对请求处理的优化。
TCP与HTTP的渊源
我们知道TCP协议对应于传输层,HTTP协议对应于应用层。WEB项目中,HTTP协议是建立在TCP的基础上的。
最初浏览器从服务器加载一个网页,会发起一个HTTP请求,这时需要先建立一个TCP连接。当本次数据请求完毕之后,会立刻断开TCP连接。
但随着时间的推理,HTML网页内容越来越复杂,不仅有内容,还有JS、CSS和图片资源,每个资源的请求都建立一次TCP连接,效率就会很低。
这时,Keep-Alive就被提出用来了,专门用于解决效率低的问题。
本文关于TCP连接能够发送多少个HTTP请求,本质上就是围绕着解决通信的低效问题的。
下面我们通过几个常见的面试问题,来逐步揭开这其中包含的知识点。
问题一:浏览器建立TCP连接之后,完成一次HTTP请求,是否会断开?
HTTP协议Header中的Connection属性决定了连接是否持久,不同HTTP协议版本有所不同。
HTTP/1.0中Connection默认为close,即每次请求都会重新建立和断开TCP连接。缺点:建立和断开TCP连接,代价过大。
HTTP/1.1中Connection默认为keep-alive,即连接可以复用,不用每次都重新建立和断开TCP连接。超时之后没有连接则主动断开。可以通过声明Connection为close进行关闭。
优点:TCP连接可被重复利用,减少建立连接的损耗,SSL的开销也可以避免。刷新页面时也可以复用,从而不再建立SSL连接等。
结论:默认情况下(HTTP/1.1)建立TCP连接不会断开,只有在请求报头中声明Connection: close才会请求完成之后关闭连接。不断开的最终目的是减少建立连接所导致的性能损耗。
问题二:一个TCP连接可以对应几个HTTP请求?
如果Connection为close,则一个TCP连接只对应一个HTTP请求。
如果Connection为Keep-alive,则一个TCP连接可对应一个到多个HTTP请求。
问题三:一个TCP连接中,可以同时发送多个HTTP请求吗?
HTTP/1.1中单个TCP连接在同一时刻只能处理一个请求。HTTP/1.1在RFC 2616中规定了Pipelining来解决这个问题,但浏览器默认是关闭的。
RFC 2616中规定:一个支持持久连接的客户端可以在一个连接中发送多个请求(不需要等待任意请求的响应)。收到请求的服务器必须按照请求收到的顺序发送响应。
Pipelining本身存在一些问题,比如代理服务器不能正确处理HTTP Pipelining、Head-of-line Blocking连接头阻塞(首个请求耗时过长,阻塞其他请求)。所以,浏览器默认关闭该功能。
HTTP/2.0提供了多路复用技术Multiplexing,一个TCP可以并发多个HTTP请求(理论无上限,但是一般浏览器会有TCP并发数的限制)。
HTTP/1.1中为了提升性能,通常会采用连接复用和同时建立多个TCP连接的方式提升性能。
结论:HTTP/1.1中存在Pipelining技术支持一个连接发送多个请求,但存在弊端,浏览器默认关闭。HTTP/2.0中通过多路复用技术支持一个TCP连接中并发请求HTTP。
问题四:浏览器对同一Host建立TCP连接的数量有没限制?
不同浏览器限制不同,比如Chrome最多允许同一个Host可建立6个TCP连接。
如果服务器只支持HTTP/1.1,浏览器会采用在同一个Host下建立多个TCP连接来进行效率提升。如果是基于HTTPS传输,在SSL握手之后,还会尝试协商是否可以采用HTTP/2.0的Multiplexing功能。
问题五:keep-alive使用场景及优缺点
开启keep-alive对内存要求高,关闭keep-alive对CPU要求高;如果内存和CPU都足够,开启和关闭keep-alive对性能影响不大;如果考虑服务器压力,如果是静态页面,大量的调用js或者图片的话,建议开启keep-alive;如果是动态网页,建议关闭keep-alive。
注意事项:如果需要使用keep-alive功能,服务器端如果使用nginx中keepalive_timeout值要大于0。
小结
通过上面的整体分析,我们不仅了解了TCP与HTTP之间的关系,还明确了现代浏览器基于不同的HTTP协议所作出的网络层面优化。而HTTP2/0的多路复用机制还是一些高性能框架的基础,比如gRPC的实现。
博主简介:《SpringBoot技术内幕》技术图书作者,酷爱钻研技术,写技术干货文章。
公众号:「程序新视界」,博主的公众号,欢迎关注~
技术交流:请联系博主微信号:zhuan2quan
“ 程序新视界”,一个100%技术干货的公众号
-
长连接及心跳保活原理简介
2018-11-04 15:20:40长连接及心跳保活原理简介 本文简要的分析了长连接产生的背景以及所解决的问题,并对比了keep-alive与心跳机制对长连接保活的影响,最后详细的介绍了心跳保活的两个关键因素–DHCP协议与NAT原理。如有不当之处,... -
哈工大计算机网络第四章——网络层复习
2021-12-01 18:20:131. 网络层服务 在从发送主机向接收主机传送数据段(segment)的过程中,发送主机的网络层取得传输层的报文段,将报文段封装到数据报(datagram)中,然后向相邻的路由器发送数据报。接收主机的网络层接收来自相邻... -
Nginx总结(反向代理、负载均衡、动静分离)篇
2021-11-30 22:59:49Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率﹐能经受高负载的考验,有报告表明能支持高达50, 000个并发连接数。 Nginx作用:反向代理、负载均衡、动静分离等 什么是反向代理 先了解一下... -
计算机网络第四章 网络层
2020-06-17 23:21:534.1.1 网络层功能概述 网络层 主要任务是把分组从源端传到目的端,为分组交换网上的不同主机提供通信服务,网络层传输单位是数据报。 功能 路由选择与分组转发(最佳路径) 异构网络互联 拥塞控制 4.1.2 数据交换... -
Nginx-正向、反向代理、安装、配置详解
2021-03-09 11:10:55一、Nginx简介 1、Nginx是什么? Nginx是一款轻量级的Web...(2)反向代理:客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求送到反向代理服务器,由反向代理服务器需选择目标服. -
nginx配置详解及设置代理服务器(1)
2021-01-06 15:21:39nginx配置详解及设置代理服务器1. nginx简单介绍2. nginx安装3. nginx 配置文件详解3.1 nginx.conf文件配置属性详解3.2 配置服务代理:4. 配置过程的注意事项:4.1 nginx启动等命令4.2 location 详解4.2.1 location... -
Nginx笔记——代理服务配置
2022-03-30 09:55:36Nginx的代理配置,正向代理、反向代理、负载均衡 -
linux的TCP连接数量最大不能超过65535个吗,那服务器是如何应对百万千万的并发的?
2021-04-03 01:01:24首先,问题中描述的65535个连接指的是客户端连接数的限制。 在tcp应用中,server事先在某个固定端口监听,client主动发起连接,经过三路握手后建立tcp连接。那么对单机,其最大并发tcp连接数是多少呢? 如何标识一... -
HttpClient连接池的深入理解
2021-01-22 00:08:00HTTP协议是全双工的协议,所以建立连接与断开连接是要经过三次握手与四次挥手的。显然在这种设计中,每次发送Http请求都会消耗很多的额外资源,即连接的建立与销毁。 于是,HTTP协议的也进行了发展,通过持久连接的... -
这些知识决定了一名程序员的上限
2019-04-27 10:00:42讲述决定程序员上限的一些知识技能点,包括如何学习、如何阅读源码、计算机科学基础知识体系等。 什么是程序员? 码农、程序猿、程序媛 使用 程序实现价值 程序=数据+算法 软件=程序+软件工程 程序员=工程师?... -
计算机网络学习笔记(四)——网络层
2022-02-01 13:43:59网络层的主要任务是把分组从源端传到目的端,为分组交换网上的不同主机提供通信服务。 网络层传输单位是数据报。 功能1:路由选择与转发 (最佳路径) 功能2:异构网络互联 功能3:拥塞控制 若所有结点都来不及接收... -
分析单机最大长连接数
2019-03-12 11:22:43linux文件描述符限制和单机最大长连接数 相关参数 linux系统中与文件描述符相关的参数有以下几个: soft/hard nofile file-max(/proc/sys/fs/file-max) nr_open(/proc/sys/fs/nr_open) 这三个参数的作用都是... -
Http 持久连接与 HttpClient 连接池
2018-05-22 18:39:13所以可能造成客户端与服务端都保持了连接,但是代理不接受该连接上的数据。 三、HTTP/1.1的持久连接 HTTP/1.1采取持久连接的方式替代了Keep-Alive。 HTTP/1.1的连接默认情况下都是持久连接。如果要显式... -
大量的 TCP 连接是 TIME_WAIT 状态,有什么影响?怎么处理?
2020-08-04 08:16:26ningg.top/computer-basic-theory-tcp-time-wait/你有没有遇到过进程里开了许多连接,但一看状态都是 TIME_WAIT,如果 TIME_WAIT... -
第四章:连接到ActiveMQ
2015-08-08 11:26:00第四章:连接到ActiveMQ ActiveMQ的主要作用就是向客户应用程序提供面向消息通信的架构。ActiveMQ提供了一种用于客户端和代理之间(Client-to-Broker)以及代理与代理(Broker-to-Broker)之间连接的连接器... -
【计算机网络】知识点整理 第四章 网络层(王道考研视频学习记录)
2021-12-11 13:44:48网络层4.14.1.1功能概述4.1.2 电路交换、报文交换与分组交换4.1.3 数据报与虚电路4.1.4 数据交换方式4.2 路由算法与路由协议概述4.34.3.1 IP 数据报格式4.3.2 IP数据报分片4.3.3 IPv4地址4.3.4 网络地址转换NAT4.3.5... -
高性能的连接管理和数据路由组件,OceanBase 生态工具 ODP 详解
2022-03-23 14:31:57作者简介:致新,OceanBase 数据链路高级研发工程师。...ODP 是 OceanBase 的访问入口,具有代理和中间件的特性。 1.2ODP 发展历史 ODP 目前的产品特性,除了方案设计外,和产品的发展历史也... -
服务端 TCP 连接的 TIME_WAIT 过多问题的分析与解决
2021-05-06 10:48:59本文给出一个 TIME_WAIT 状态的 TCP 连接过多的问题的解决思路,非常典型,大家可以好好看看,以后遇到这个问题就不会束手无策了。 问题描述 模拟高并发的场景,会出现批量的 TIME_WAIT 的 TCP 连接: 短时间后,... -
超详细Nginx学习笔记(Nginx反向代理+动静分离+高可用)
2021-02-27 09:03:45此笔记是博主在学习...概念:Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。 特点:占用内存少,并. -
服务端 TCP 连接的 TIME_WAIT 问题分析与解决
2020-06-08 08:08:00写在开头,大概 4 年前,听到运维同学提到 TIME_WAIT 状态的 TCP 连接过多的问题,但是当时没有去细琢磨;最近又听人说起,是一个新手进行压测过程中,遇到的问题,因此,花点时间... -
网络面经:一个TCP连接可以发送多少个HTTP请求?
2021-09-08 21:20:20我们知道TCP协议对应于传输层,HTTP协议对应于应用层。WEB项目中,HTTP协议是建立在TCP的基础上的。 最初浏览器从服务器加载一个网页,会发起一个HTTP请求,这时需要先建立一个TCP连接。当本次数据请求完毕之后,会... -
Http持久连接与HttpClient连接池
2018-05-19 16:28:51本文摘自微信公众号ImportNew。... 一、背景 ...因此它的最初实现是,每一个http请求都会打开一个tcpsocket连接,当交互完毕后会关闭这个连接。... HTTP协议是全双工的协议,所以建立连接与断开连接是... -
Linux服务篇--反向代理及负载均衡器Haproxy
2019-06-06 10:09:04nginx(haproxy)功能多,性能相对较弱,因此,一般情况下,在前端使用LVS四层调度器加haproxy七层调度的结构 HAProxy: 是法国人Willy Tarreau开发的一个开源软件,是一款应对客户 端10000以上的同时连接的高性能的TCP... -
linux文件描述符限制和单机最大长连接数
2017-09-13 17:52:20linux文件描述符限制和单机最大长连接数相关参数linux系统中与文件描述符相关的参数有以下几个: soft/hard nofile file-max(/proc/sys/fs/file-max) nr_open(/proc/sys/fs/nr_open) 这三个参数的作用都是限制一... -
经典!服务端 TCP 连接的 TIME_WAIT 过多问题的分析与解决
2020-07-15 08:00:00开源Linux专注分享开源技术知识本文给出一个 TIME_WAIT 状态的 TCP 连接过多的问题的解决思路,非常典型,大家可以好好看看,以后遇到这个问题就不会束手无策了。问题描述模...