用workerman写好了服务端的程序,现在用PHP写了个测试程序,模拟多个用户同时访问服务端,测试服务器的处理能力,代码如下:
<?php
class Client {
private $lastSendTime = 0;
private $SEND_INTERVAL = 60;
private $socket;
private static $global_id = 0;
private static $host;
private static $port;
private $id;
public function __construct($host, $port) {
self::$host = $host;
self::$port = $port;
self::$global_id ++;
$this->id = self::$global_id;
$this->lastSendTime = mt_rand(time() - $this->SEND_INTERVAL * 2, time() - $this->SEND_INTERVAL);
}
public function connect() {
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($this->socket) {
if (socket_connect($this->socket, self::$host, self::$port) && socket_set_nonblock($this->socket)) {
return TRUE;
}
}
$errno = socket_last_error($this->socket);
$errstr = socket_strerror($errno);
echo 'Client connect failed..' . PHP_EOL . $errno . ': ' . $errstr . PHP_EOL;
socket_close($this->socket);
return FALSE;
}
public function sendCommand($command) {
$now = time();
if ($now - $this->lastSendTime > $this->SEND_INTERVAL) {
if (socket_write($this->socket, $command)) {
//echo 'Client ' . $this->id . ' send message successfully' . PHP_EOL;
$this->lastSendTime = $now;
}
else {
$errno = socket_last_error($this->socket);
$errstr = socket_strerror($errno);
if ($errno == 10054 || $errno == 10053) {
echo 'Client ' . $this->id . ' connect again' . PHP_EOL;
socket_close($this->socket);
$this->connect();
}
else {
echo 'Client send message failed' . PHP_EOL;
echo $errno . ': ' . $errstr . PHP_EOL;
}
}
}
}
}
if (count($argv) != 2) {
exit('1 param is required.');
}
$port = 4832;
$host = 'xxxx.xxxx.xxx.xxx';
$total = (int) $argv;
$clients = [];
$command = 'XXx';
$stat = 0;
for ($i = 0; $i < $total; $i++) {
$c = new Client($host, $port);
if ($c->connect()) {
echo (++$stat) . ' clients connected' . PHP_EOL;
$clients[] = $c;
$c->sendCommand($command);
}
}
echo count($clients) . ' Clients are connected.' . PHP_EOL;
while (true) {
foreach ($clients as $c) {
$c->sendCommand($command);
}
sleep(1);
//echo memory_get_usage(true) . PHP_EOL;
}
在windows下用cmd(命令行模式)来运行,发现一段时间后,系统的已使用内存越来越高,把程序结束后,内存占用马上恢复到原来的水平。但是我在程序中使用memory_get_usage方法来检查进程占用的内存时,却发现长时间都是不变的,在任务管理器中查看进程占用内存时,也是不变的。我想长时间运行测试程序,以检查服务端的稳定性,但是大概运行一天后,内存就不够用了。就教大神,我的内存到底去哪里了??
我现在怀疑是不是我的程序没有读取服务器返回的数据,导致数据都堆积到内存了?但是我并不关心服务器的回复信息,而且我用的是非阻塞模式,要读取回复信息好像挺麻烦的。如果果真是这个原因,有什么办法让程序直接丢弃服务的回复信息?
客户端必须读数据,不然数据都会积压在每个socket连接的读缓冲区,导致内存不断增长。如果每个连接的socket读缓冲区都满了,则客户端无法再接收到数据
嗯嗯,测试过了,确实是这样,感谢~~
这也是我一直的疑问