reactor单机布置突破C10k并发服务器测试
服务器性能测试需要满足3个条件:高性能,高可用,高并发。
服务器并发量:服务器能够同时承载客户端的数量。
服务器单位时间的吞吐量QPS:单位时间内服务器处理请求的数量,也就是每秒查询率,这个参数主要用于数据库每秒处理查询请求的测试中。
TPS:每秒处理事务数。每一个事务的处理流程包含3个过程:1.用户请求服务器;2,服务器自己的逻辑处理过程;3.服务器返回数据到用户端;TPS就是每秒完成n次这三个过程,TPS=n;
PPS和TPS区别:
Qps是服务器每秒能够响应的查询次数。如果是对一个查询接口(单场景)压测,且这个接口内部不会再去请求其它接口,那么tps=qps;如果是容量场景,假设x个接口都是查询接口,且这个接口内部不会再去请求其它接口,qps=x*tps。
C10K是指一台服务器同时应付1w个并发连接的场景。
假设服务器的5w并发需要维护这些fd, 服务器的并发考虑到以下因素:
1.5w以上的响应请求;
2.对数据库的操作;
3.对磁盘的操作;
4.cpu占有率,即CPU load不得超过60%;
5.内存占有率,不得超过80%;
同时满足时,才能满足服务器承载这些fd的基本的条件。
reactor反应堆模式可以同时承载100w的fd,下面对reactor做C1M并发处理同时承载fd数量的测试。
reactor服务器端测试代码:
https://github.com/sunhan3787/Linux_server/blob/master/01_reactor
编译服务器端测试代码:
gcc -o reactor 01_reactor.c
./reactor 6023
epoll 客户端测试代码:
https://github.com/sunhan3787/Linux_server/blob/master/01_C1M_epoll_client
编译客户端测试代码:
gcc -o client_epoll 01_mul_port_client_epoll.c
./client_epoll 192.168.1.114 6023
Q1,发现第一次测试止步于1023,这个数字限制于操作系统openflie打开fd数目的限制;
ulimit -a
返回结果:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7788
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7788
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
可以看出,操作系统一个进程打开fd最大数量是1024
vim /etc/security/limits.conf
添加修改:
* hard nofile 1048576
* soft nofile 1048576
vim /etc/sysctl.conf
添加修改:
net.ipv4.tcp_mem = 252144 524288 786432
net.ipv4.tcp_wmem = 1024 1024 2048
net.ipv4.tcp_rmem = 1024 1024 2048
fs.file-max = 1048576
net.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
#net.ipv4.ip_conntrack_max = 1048576
#net.ipv4.netfilter.ip_conntrack_max = 1048576
#net.ipv4.ip_local_port_range = 10000 65000
sysctl -p
ulimit -n 1048576
cat /proc/sys/net/ipv4/tcp_wmem
输入:sysctl -p 报错:
sysctl: cannot stat /proc/sys/net/nf_conntrack_max: No such file or directory
sysctl: cannot stat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established: No such file or directory
解决方法:
lsmod |grep conntrack
执行以上命令如果返回为空,执行:
modprobe ip_conntrack
再次执行sysctl -p
ok
多台client连接192.168.1.114时
./client_epoll 192.168.1.114 6023 报错:
connect: Connection refused
error : Connection refused
解决方法:#define MAX_PORT 100 ->1
Timrout
connect: Cannot assign requested address
error : Cannot assign requested address
Q2,Segmentation fault (core dumped) Fd 打开数量依然是1024
reactor将fd 多路复用IO转换成事件存储,因此还需要增大宏值:
#define MAX_EPOLL_EVENTS 1024*1024
Fd 并发数量可达到4w+
Q3,客户端宕机,客户端端口问题:
fd, socket, 网络io
fd ->五元组(sip源ip,dip目的ip,sport源端口,dport目的端口,proto协议)
解决方法:客户端采用多个端口
解决方法:#define MAX_PORT 1 ->5
修改服务器端reactor代码:
int main(int argc, char *argv[]) {
unsigned short port = SERVER_PORT;
if (argc == 2) {
port = atoi(argv[1]);
}
//int sockfd = init_sock(port);
struct ntyreactor *reactor = (struct ntyreactor*)malloc(sizeof(struct ntyreactor));
ntyreactor_init(reactor);
int listenfd[LISTEN_PORT_COUNT];
int i = 0;
for(i = 0; i < LISTEN_PORT_COUNT; i++){
listenfd[i] = init_sock(port);
ntyreactor_addlistener(reactor, listenfd[i], accept_cb);
}
ntyreactor_run(reactor);
ntyreactor_destory(reactor);
for(i = 0; i < LISTEN_PORT_COUNT; i++){
close(listenfd[i]);
}
return 0;
}