存档

2013年8月 的存档

PHP服务器端守护进程怎么实现MySQL连接池

2013年8月22日 没有评论

在启动时创建 10个MySQL连接和10个锁。然后fork出100个worker进程。worker进程随机从pool中取一个连接,先进行加锁操作,然后执行mysql_query。返回后释放锁,让其他进程可以使用此连接。

为什么要加锁呢,原因是mysql_query是一个收发包的过程,如果并发执行mysql_query,就会同时有多个进程发出去请求。这时候没办法区分到底哪个回包是对应的。mysql_query函数会直接抛出致命错误,并切断连接。

另外最好使用mysql_pconnect。避免子进程结束时执行mysql_close破坏此连接,其他子进程也没法用这个连接了。

这里的随机取也可以继续改进一下,使用共享内存来做一个忙闲区分。当执行mysql_query前将此连接设为忙。其他worker取连接时,判断为忙的话跳过此连接。

用下面的代码演示一下。


<?php
for($i = 0; $i < 1; $i ++)
{
	$db = new mysqli("localhost", "root", "root", "test");
	$lock = fopen("/tmp/mysql_lock.txt", 'w+');
	if ($db->connect_errno) 
	{
		printf("Connect failed: %s\n", $db->connect_error);
		exit();
	}
}

for($i = 0; $i < 5; $i++)
{
	if(pcntl_fork() > 0)
	{
		continue;
	}
	if (flock($lock, LOCK_EX))
	{
		$result = $db->query('show tables');
	}
	flock($lock, LOCK_UN); 
	
	if (empty($result)) 
	{
    		print('Invalid query: ' . $db->error."\n");
	}
	else
	{
		while ($row = $result->fetch_assoc()) 
		{
			echo "#".posix_getpid(),"\t";
			var_dump($row);
			echo "\n";
		}
		$result->close();
	}
	sleep(1000);
	exit;
}
sleep(1000);
分类: PHP 标签:

Swoole压测:如何做到并发10万TCP连接

2013年8月6日 2 条评论

Server代码调整

  • 要关闭输出,否则打印屏幕会拖垮Server.
  • 修改server的max_conn参数为100000或者更大,为了安全实际上只能到99999。

内核参数调整

  • ulimit -n 要调整为100000甚至更大。如何调这个参数,可以参考网上的一些文章。命令行下执行 ulimit -n 100000即可修改。如果不能修改,需要设置  /etc/security/limits.conf,加入
    * hard nofile 100000
    * soft nofile 100000
  • net/ipv4/ip_local_port_range 需要修改为更大的范围,如20000 – 60000,否则端口号会不够用。导致客户端报 99错误
  • 单台是不能压到10万的。客户端连接需要分配一个local port。范围是上一条设置的。也就是只有4万个port可以用。可以使用多台机器来测试。
  • net.ipv4.tcp_tw_recycle = 1 ,设置快速回收被close的端口。否则端口会不够用
  • 其他内核参数的调整,如tcp_fin_timeout、tcp_keepalive_time、tcp_max_syn_backlog可以搜索网上的文章。
  • 长期运行的Server要有坏连接检测的能力,比如心跳、活动时间检测等方案。避免客户端没有发REST,导致坏连接堆积
分类: C/C++, Swoole扩展 标签:

关于Swoole编码风格

2013年8月5日 没有评论

一、大括号独占一行

有些人觉得放在同一行更好更紧凑,我个人不喜欢这种风格。代码密密麻麻挤在一起严重影响美观,可读性也不够好。

独占一行,代码就很稀疏。没那么累。

另外if 语句如果只有一行,我也习惯性写成有括号的。

if (a > b)
{
    return false;
}

二、使用下划线分割

swoole的C代码里都用swServer_这样来命名函数,然后用下划线分割。

swoole用了面向对象的风格来写C代码,方法名都很短。比如锁的代码

swMutex m = swMutex_create(&m, 1);
m.lock();
m.unlock();

三、源代码目录结构

swoole源代码使用两层目录结构,最外层是代码分类,比如是memory、factory、lock等。里面的每个.c文件都是具体的实现代码。如lock下有mutex.c、rwlock.c等。

四、少用宏

swoole里还是使用了宏的,宏是预编译期执行的,不会生成额外的指令。有些地方使用宏很方便。但swoole里不推荐使用宏来编写逻辑代码。

五、使用goto

goto其实可以减少很多if else while块,很方便。少量使用goto还是有助于提升开发效率的。但不滥用。

分类: C/C++, Swoole扩展 标签: