重新编写测试端程序

测试端程序需要增加绑定本机IP和本地端口的功能,以尽可能的向外发出更多的tcp请求。需要对client1.c重构,增加参数传递。 下面是client2.c的代码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
#include <sys/types.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <stdlib.h>
#include <err.h>
#include <event.h>
#include <evhttp.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <pthread.h>
#define BUFSIZE 4096
#define SLEEP_MS 10
char buf[BUFSIZE];
int bytes_recvd = 0;
int chunks_recvd = 0;
int closed = 0;
int connected = 0;
static char ip_array[300] = "192.168.190.134,192.168.190.143,192.168.190.144,192.168.190.145,192.168.190.146,192.168.190.147,192.168.190.148,192.168.190.149,192.168.190.151,192.168.190.152";
static char server_ip[16] = "192.168.190.133";
static int server_port = 8000;
static int max_conns = 62000;
// called per chunk received
void chunkcb(struct evhttp_request *req, void *arg) {
int s = evbuffer_remove( req->input_buffer, &buf, BUFSIZE );
bytes_recvd += s;
chunks_recvd++;
if (connected >= max_conns && chunks_recvd % 10000 == 0)
printf(">Chunks: %d\tBytes: %d\tClosed: %d\n", chunks_recvd, bytes_recvd, closed);
}
// gets called when request completes
void reqcb(struct evhttp_request *req, void *arg) {
closed++;
}
int main(int argc, char **argv) {
int ch;
while ((ch = getopt(argc, argv, "o:h:p:m:")) != -1) {
switch (ch) {
case 'h':
printf("host is %s\n", optarg);
strncpy(server_ip, optarg, 15);
break;
case 'p':
printf("port is %s\n", optarg);
server_port = atoi(optarg);
/*strncpy(server_ip, optarg, 15);*/
break;
case 'm':
printf("max_conns is %s\n", optarg);
max_conns = atoi(optarg);
/*strncpy(server_ip, optarg, 15);*/
break;
case 'o':
printf("ori_ips is %s\n", optarg);
strncpy(ip_array, optarg, 300 - 1);
break;
}
}
event_init();
struct evhttp *evhttp_connection;
struct evhttp_request *evhttp_request;
char path[32];
int i;
char delims[] = ",";
char *ori_ip = NULL;
ori_ip = strtok( ip_array, delims );
while (ori_ip != NULL) {
for (i = 1; i <= max_conns; i++) {
evhttp_connection = evhttp_connection_new(server_ip, server_port);
evhttp_connection_set_local_address(evhttp_connection, ori_ip);
evhttp_set_timeout(evhttp_connection, 864000); // 10 day timeout
evhttp_request = evhttp_request_new(reqcb, NULL);
evhttp_request->chunk_cb = chunkcb;
sprintf(&path, "/test/%d", ++connected);
if (i % 1000 == 0)
printf("Req: %s\t->\t%s\n", ori_ip, &path);
evhttp_make_request( evhttp_connection, evhttp_request, EVHTTP_REQ_GET, path );
evhttp_connection_set_timeout(evhttp_request->evcon, 864000);
event_loop( EVLOOP_NONBLOCK );
if ( connected % 1000 == 0 )
printf("\nChunks: %d\tBytes: %d\tClosed: %d\n", chunks_recvd, bytes_recvd, closed);
usleep(SLEEP_MS * 10);
}
ori_ip = strtok( NULL, delims );
}
event_dispatch();
return 0;
}
view rawclient2.c hosted with ❤ by GitHub

若不指定端口,系统会随机挑选没有使用到的端口,可以节省些心力。

编译:

gcc -o client2 client2.c -levent

参数解释

  • -h 要连接的服务器IP地址
  • -p 要连接的服务器端口
  • -m 本机IP地址需要绑定的随机端口数量
  • -o 本机所有可用的IP地址列表,注意所有IP地址都应该可用

运行:

./client2 -h 192.168.190.230 -p 8000 -m 64000 -o 192.168.190.134,192.168.190.143,192.168.190.144,192.168.190.145,192.168.190.146,192.168.190.147,192.168.190.148,192.168.190.149,192.168.190.150,192.168.190.151

太长了,每次执行都要粘贴过去,直接放在一个client2.sh文件中,执行就很简单方便多了。

#!/bin/sh
./client2 -h 192.168.190.230 -p 8000 -m 64000 -o 192.168.190.134,192.168.190.143,192.168.190.144,192.168.190.145,192.168.190.146,192.168.190.147,192.168.190.148,192.168.190.149,192.168.190.150,192.168.190.151

保存,赋值可运行:

chmod +x client2.sh

启动测试:

sh client2.sh

第三个遇到的问题:fs.file-max的问题

测试端程序client2.c在发出的数量大于某个值(大概为40万时)是,通过dmesg命令查看会得到大量警告信息:

[warn] socket: Too many open files in system

此时,就需要检查/proc/sys/fs/file-max参数了。

查看一下系统对fs.file-max的说明

 /proc/sys/fs/file-max
This file defines a system-wide limit on the number of open files for all processes. (See also setrlimit(2), which can be used by a process to set the per-process limit,
RLIMIT_NOFILE, on the number of files it may open.) If you get lots of error messages about running out of file handles, try increasing this value:
echo 100000 > /proc/sys/fs/file-max
The kernel constant NR_OPEN imposes an upper limit on the value that may be placed in file-max.
If you increase /proc/sys/fs/file-max, be sure to increase /proc/sys/fs/inode-max to 3-4 times the new value of /proc/sys/fs/file-max, or you will run out of inodes.

file-max表示系统所有进程最多允许同时打开所有的文件句柄数,系统级硬限制。Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不用修改,除非打开的文件句柄数超过此值。

在为测试机分配4G内存时,对应的fs.file-max值为386562,很显然打开的文件句柄很受限,38万个左右。 很显然,无论是测试端还是服务端,都应该将此值调大些,一定要大于等于/etc/security/limits.conf送所设置的soft nofile和soft nofile值。 
注意ulimit -n,仅仅设置当前shell以及由它启动的进程的资源限制。

备注:以上参数,具有包含和被包含的关系。

当前会话修改,可以这么做:

echo 1048576 > /proc/sys/fs/file-max

但系统重启后消失。

永久修改,要添加到 /etc/sysctl.conf 文件中:

fs.file-max = 1048576

保存并使之生效:

sysctl -p

再测,就不会出现此问题了。

一台6G内存机器测试机,分配7个网卡,可以做到不占用虚拟内存,对外发出64000 * 7 = 448000个对外持久请求。要完成100万的持久连接,还得再想办法。

最终测试端组成如下:

  • 两台物理机器各自一个网卡,每个发出64000个请求
  • 两个6G左右的centos测试端机器(绑定7个桥接或NAT连接)各自发出64000*7 = 448000请求
  • 共使用了16个网卡(物理网卡+虚拟网卡)
  • 1M ≈ 1024K ≈ 1024000 = (64000) + (64000) + (64000*7) + (64000*7)
  • 共耗费16G内存,16个网卡(物理+虚拟),四台测试机

备注: 
下面就要完成1M持久连接的目标,但在服务端还会遇到最后一个问题。

100万并发连接服务器笔记之测试端就绪相关推荐

  1. 100万并发连接服务器笔记之准备篇

    2019独角兽企业重金招聘Python工程师标准>>> 前言 测试一个非常简单服务器如何达到100万(1M=1024K连接)的并发连接,并且这些连接一旦连接上服务器,就不会断开,一直 ...

  2. 100万并发连接服务器笔记之处理端口数量受限问题

    第二个遇到的问题:端口数量受限 一般来说,单独对外提供请求的服务不用考虑端口数量问题,监听某一个端口即可.但是向提供代理服务器,就不得不考虑端口数量受限问题了.当前的1M并发连接测试,也需要在客户端突 ...

  3. 100万并发连接服务器笔记之1M并发连接目标达成

    第四个遇到的问题:tcp_mem 在服务端,连接达到一定数量,诸如50W时,有些隐藏很深的问题,就不断的抛出来. 通过查看dmesg命令查看,发现大量TCP: too many of orphaned ...

  4. 100万并发连接服务器笔记之Erlang完成1M并发连接目标

    http://www.blogjava.net/yongboy/archive/2013/04/28/398558.html 转载于:https://www.cnblogs.com/ziyouchut ...

  5. 100万并发连接服务器

    100万并发连接服务器笔记之准备篇 前言 测试一个非常简单服务器如何达到100万(1M=1024K连接)的并发连接,并且这些连接一旦连接上服务器,就不会断开,一直连着.  环境受限,没有服务器,刚开始 ...

  6. 访问量100万的网站服务器,100万访问量 服务器配置

    100万访问量 服务器配置 内容精选 换一换 弹性负载均衡有不同的负载均衡,分别是共享型负载均衡和独享型负载均衡,便于用户根据不同的应用场景和功能需求选择合适的负载均衡器类型.共享型负载均衡:适用于访 ...

  7. 83998 连接服务器出错_服务端 TCP 连接的 TIME_WAIT 问题分析与解决

    民工哥技术之路 写在开头,大概 4 年前,听到运维同学提到 TIME_WAIT 状态的 TCP 连接过多的问题,但是当时没有去细琢磨:最近又听人说起,是一个新手进行压测过程中,遇到的问题,因此,花点时 ...

  8. 小说阅读器未能连接服务器怎么办,vue移动端小说阅读器vue全家桶项目,已部署到服务器可访问预览...

    暑假实习了几个月辞职后,闲着无聊自己开发的一个vue小说阅读器链接 预览地址,里面的小说接口调用的是追书神器,然后我把里面的vip和收费章节做了处理加了个换源功能,里面需要收费或者vip的小说都可以免 ...

  9. [NewLife.Net]单机400万长连接压力测试

    目标 对网络库NewLife.Net进行单机百万级长连接测试,并持续收发数据,检测网络库稳定性. [2020年8月1日晚上22点] 先上源码:https://github.com/NewLifeX/N ...

最新文章

  1. 2021年大数据Flink(二十四):​​​​​​​Allowed Lateness案例演示
  2. 初学web标准的几个误区
  3. Python把数据存储到CSV
  4. QT的QMutableMapIterator类的使用
  5. 【干货】同步与互斥的失败例子
  6. linux下的shell和脚本
  7. tomcat更改端口序
  8. Linux-存储服务之NFS
  9. 数据分析应用统计学之分散性与变异性的测量【极差、四分位差、偏态系数、峰态系数、统计指标】
  10. 第51条:精简initialize与load的实现代码
  11. PHP date函数参数
  12. 利用Excel进行简单线性规划求解
  13. 一位全减器逻辑电路图_一位全减器电路实现方法探讨
  14. python怎么设置为中文-python设置中文界面实例方法
  15. 最新Oreo易支付源码开源版
  16. 物联网网络层安全需求
  17. 月报总结|Moonbeam 11月份大事一览
  18. 计算机上硬盘显示不出来怎么办,加装硬盘不显示怎么办_新硬盘装上去了但是没显示这么解决...
  19. Matlab之real和imag函数
  20. 带疑问的歌词有哪些_带有(我)字的歌词有哪些

热门文章

  1. 微信支付 php详解,PHP实现微信支付实战案例详解
  2. 轨迹相似性度量之基于Hausdorff与LCSS的理解
  3. 还在担心没有服务器做不了数据分析?这个免费资源看一下!
  4. 样本分布不平衡,机器学习准确率高又有什么用?
  5. NOI入门级:算法之动态规划
  6. 4.2 算法之数论 1486 A Funny Game python
  7. 人工智能python课程总结1500字_李开复的《人工智能》读后感1500字
  8. ueditor video 设置宽高的问题(uni app)
  9. centos 7 java安装路径_Linux CentOS 7.0中java安装与配置环境变量的步骤详解
  10. 信息安全工程师笔记-案例分析(二)