使用socket方式连接Nginx优化php-fpm性能

Nginx连接fastcgi的方式有2种:TCP和unix domain socket

什么是Unix domain socket?—— 维基百科
Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。与管道相比,Unix domain sockets 既可以使用字节流和数据队列,而管道通信则只能通过字节流。Unix domain sockets的接口和Internet socket很像,但它不使用网络底层协议来通信。Unix domain socket 的功能是POSIX操作系统里的一种组件。

Unix domain sockets 使用系统文件的地址来作为自己的身份。它可以被系统进程引用。所以两个进程可以同时打开一个Unix domain sockets来进行通信。不过这种通信方式是发生在系统内核里而不会在网络里传播。

TCP和unix domain socket方式对比
TCP是使用TCP端口连接127.0.0.1:9000
Socket是使用unix domain socket连接套接字/dev/shm/php-cgi.sock(很多教程使用路径/tmp,而路径/dev/shm是个tmpfs,速度比磁盘快得多

测试机是个1核的centos5.4,2用户并发时系统资源消耗50%左右,10用户资源就跑得很满了。

 
    2users 10users
nginx/1.2.9 + PHP 5.2.5 tcp 1060 1294
nginx/1.2.9 + PHP 5.2.5 socket 997 1487
nginx/1.2.9 + PHP 5.3.10 tcp 906 1082
nginx/1.2.9 + PHP 5.3.10 socket 880 1247

结论是在服务器压力不大的情况下,tcp和socket差别不大,但在压力比较满的时候,用套接字方式,效果确实比较好。

下面是php 5.3以上版本将TCP改成socket方式的配置方法:

修改php-fpm.conf(/usr/local/php/etc/php-fpm.conf)

XML/HTML代码
  1. ;listen = 127.0.0.1:9000  
  2. listen = /dev/shm/php-cgi.sock  

修改nginx配置文件server段的配置,将http的方式改为socket方式

XML/HTML代码
  1. location ~ .php$ {  
  2.     #fastcgi_pass   127.0.0.1:9000;  
  3.     fastcgi_pass unix:/dev/shm/php-cgi.sock;  
  4.     fastcgi_index  index.php;  
  5.     fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;  
  6.     include        fastcgi_params;  
  7. }  

重启php-fpm与nginx

service nginx restart
service php-fpm restart

然后
ls -al /dev/shm
可以看到php-cgi.sock文件unix套接字类型

参考:http://zh.wikipedia.org/wiki/Unix_domain_socket

 

转载后记:我根据上文配置完后,访问PHP页面出现502,查看Nginx日志,有错误信息:nginx error connect to php-cgi.sock failed (13: Permission denied)

编辑配置文件/usr/local/php/etc/php-fpm.conf

;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
改为
listen.owner = nobody
listen.group = nobody
listen.mode = 0666

保存,重启PHP-FPM即可

 

xhprof与Xdebug的奇怪问题

  为了查找项目中比较耗性能的PHP代码,这两天在装xhprof用来跟踪代码,结果遇到了一个很奇怪的问题。安装配置好xhprof后,用来跟踪简单的代码没一点问题,但是在项目中一跟踪,PHP-FPM进程直接就挂了,查看各种日志,并且开了内核转储,折腾了半天也没找到挂了的原因。

  没办法,只好换Xdebug。安装,配置,很快就搞定了。

  在使用Xdebug前我突发奇想,不知道Xdebug能不能跟踪到xhprof导致PHP-FPM挂了的的问题,于是同时启用两者,结果意外地发现xhprof也能用了。为了证明是不是Xdebug导致xhprof可以用了,我禁用了Xdebug,xhprof又导致PHP-FPM挂了,重新启用又好了。

  真是好奇怪的问题,不知道是什么原因造成的,暂时也没时间深究了。

附Xhprof的安装与使用方法:

XML/HTML代码
  1. [root@localhost ~]# tar -zxvf xhprof-0.9.4.tgz     
  2. [root@localhost ~]# cd xhprof-0.9.4/extension/    
  3. [root@localhost extension]# phpize    
  4. [root@localhost extension]# ./configure –with-php-config=/usr/local/php/bin/php-config    
  5. [root@localhost extension]# make    
  6. [root@localhost extension]# make install  

如果phpize执行不了,请先安装或者做链接:ln -s /usr/local/php/bin/phpize /usr/bin/phpize

在php.ini文件中,添加如下配置:

XML/HTML代码
  1. [xhprof]    
  2. extension=xhprof.so;    
  3. ; directory used by default implementation of the iXHProfRuns    
  4. ; interface (namely, the XHProfRuns_Default class) for storing    
  5. ; XHProf runs.    
  6. ;    
  7. ;xhprof.output_dir=<directory_for_storing_xhprof_runs>    
  8. xhprof.output_dir=/tmp/xhprof    

把xhprof-0.9.4目录下的目录xhprof_html 和 xhprof_lib 下的所有文件拷贝到你网站的主目录下

PHP代码
  1. <?php    
  2. //cpu: XHPROF_FLAGS_CPU    
  3. //内存: XHPROF_FLAGS_MEMORY    
  4. //如果都监控用XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY    
  5. xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);    
  6.     
  7. //这中间是需要性能分析的php代码  
  8.     
  9. //停止性能分析    
  10. $data = xhprof_disable();     
  11.   
  12. //显示性能分析数据    
  13. include_once "xhprof_lib/utils/xhprof_lib.php";     
  14. include_once "xhprof_lib/utils/xhprof_runs.php";     
  15. $objXhprofRun = new XHProfRuns_Default();     
  16.   
  17. //第一个参数 是xhprof_disable()的返回值    
  18. //第二个参数 是自定义命名空间字符串     
  19. //返回运行id,用这个id查看相关运行结果    
  20. $run_id = $objXhprofRun->save_run($data"xhprof");    
  21.   
  22. //查看运行结果的url    
  23. //run的值来源于save_run的返回值    
  24. //source值来源于save_run的第二个参数                                     
  25. //www.abc.com 需要用自己的域名替换    
  26. echo "<a href='http://www.abc.com/xhprof_html/index.php?run=".$run_id."&source=xhprof'>查看结果</a>";  

 

mysql主从同步配置

前两天配置了Mysql主从,再记录如下,以备下次查看。

 

主服务器设置

1、登录Master服务器,修改my.cnf,添加如下内容;
[mysqld]
server-id = 53 #//数据库ID号, 为1时表示为Master,其中master_id必须为1到232–1之间的一个正整数值;
log-bin=mysql-bin #//启用二进制日志;
binlog-do-db=dbname #//需要同步的二进制数据库名;
binlog-ignore-db=mysql /#/不同步的二进制数据库名;这个同步后听说很麻烦,不同步;
log-slave-updates #//把更新的记录写到二进制文件中;
slave-skip-errors=all #//跳过错误,继续执行复制;

2、建立同步用mysql账号,指定允许访问的IP为从服务器IP
mysql> #GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.* to rslave@192.168.33.54 identified by '83ea4e19efe34874b50';
mysql> FLUSH PRIVILEGES;

到从服务器上验证登陆:
mysql -urslave -p83ea4e19efe34874b50 -h192.168.33.53

3、写锁定 flush tables with read lock;
4、导出数据mysqldump -uroot -p dbname > webdb.sql

从服务器设置

新版本与老版本的Mysql从服务器设置方式不一样,据说是以5.1.7版为分界线,具体请自己尝试。

老版本的Mysql配置文件[mysqld]后添加:
server-id = 54
log-bin=mysql-bin
master-host = 192.168.33.53
master-user = rslave
master-password = 83ea4e19efe34874b50
master-port = 3306
master-connect-retry=60 #//如果发现主服务器断线,重新连接的时间差
replicate-ignore-db=mysql #//不需要备份的数据库;
replicate-do-db=dbname #//需要备份的数据库
log-slave-update
slave-skip-errors = all #//跳过错误,继续执行复制;

重启Mysql服务后执行:
mysql> start slave;

新版本的Mysql配置文件[mysqld]后添加:
server-id = 61
log-bin=mysql-bin

并执行下面命令:(每次重启都要重新配置)
mysql> stop slave;
mysql> change master to master_host='192.168.33.53',master_user='rslave',master_password='83ea4e19efe34874b50';
mysql> start slave;

 

验证设置是否正确:
mysql> show slave statusG;
主要是看以下两项是否为YES:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

ssh连接速度很慢的解决方法

问题现象:

公司有几台服务器,SSH连接的时候很慢,半天才连接上,连上后一切操作正常,网络速度没问题。

处理方法:

用命令:ssh -v 服务器IP或者域名

参数v能显示连接过程中的一系列步骤,看看在哪一步完成后卡得比较久,就是那一步出问题了。

发现卡得比较久的有

XML/HTML代码
  1. debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password  
  2. debug1: Next authentication method: gssapi-keyex  
  3. debug1: No valid Key exchange context  
  4. debug1: Next authentication method: gssapi-with-mic  

说明卡在了尝试gssapi认证过程上,编辑服务器上的SSH配置文件

vi /etc/ssh/sshd_config

将#GSSAPIAuthentication no这一行前面的#号删除,同时在GSSAPIAuthentication yes这行前面加上#号,禁用gssapi认证。

重启SSH服务:service sshd restart

再次连接,发现还是有点慢,但是比之前快了一些,继续用ssh -v 跟踪,卡在这:

XML/HTML代码
  1. debug1: Authentications that can continue: publickey,password  
  2. debug1: Next authentication method: publickey  

这是因为服务器要将客户机的IP解析成域名,再次编辑SSH配置文件,将

#UseDNS yes

这行改成

UseDNS no

重启SSH服务,再次连接,终于是飞一般的感觉。