PHP连接Nginx服务器并解析Nginx日志的方法


Posted in PHP onAugust 16, 2015

php与nginx整合

PHP-FPM也是一个第三方的FastCGI进程管理器,它是作为PHP的一个补丁来开发的,在安装的时候也需要和PHP源码一起编译,也就是说PHP-FPM被编译到PHP内核中,因此在处理性能方面更加优秀;同时它在处理高并发方面也比spawn-fcgi引擎好很多,因此,推荐Nginx+PHP/PHP-FPM这个组合对PHP进行解析。
FastCGI 的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求

#fastcgi
FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同时,FastCGI也被许多脚本语言所支持,其中就有PHP。
FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。
FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。
Nginx+FastCGI运行原理
Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端,这就是Nginx+FastCGI的整个运作过程。

php与nginx整合
php.ini:php的主配置文件

[root@server79 php-5.4.12]# cp php.ini-production /usr/local/lnmp/php/etc/php.ini

拷贝php的启动脚本

[root@server79 fpm]# pwd
/root/php-5.4.12/sapi/fpm
[root@server79 fpm]# cp init.d.php-fpm /etc/init.d/php-fpm

给启动脚本加可执行权限

[root@server79 fpm]# chmod +x /etc/init.d/php-fpm
[root@server79 ~]# vim /usr/local/lnmp/php/etc/php.ini
cgi.fix_pathinfo=0
date.timezone = /Asia/Shanghai
[root@server79 ~]# cp /usr/local/lnmp/php/etc/php-fpm.conf.default /usr/local/lnmp/php/etc/php-fpm.conf
[root@server79 etc]# vim php-fpm.conf

打开注释pid = run/php-fpm.pid

php-fpm.conf文件参数解析
PHP的全局配置文件是php.ini,在上面的步骤中,已经将此文件复制到了/usr/local/lnmp/php/etc/php.ini下。可以根据每个应用需求的不同,对php.ini进行相应的配置。
下面重点介绍PHP-FPM引擎的配置文件。
根据上面指定的安装路径,PHP-FPM的默认配置文件为/usr/local/lnmp/php/etc/php-fpm.conf。
php-fpm.conf是一个XML格式的纯文本文件,其内容很容易看明白。这里重点介绍几个重要的配置标签:
标签listen_address是配置fastcgi进程监听的IP地址以及端口,默认是127.0.0.1:9000。

listen = 127.0.0.1:9000

标签user和group用于设置运行FastCGI进程的用户和用户组。需要注意的是,这里指定的用户和用户组要和Nginx配置文件中指定的用户和用户组一致。

user = nginx
group = nginx

标签max_children用于设置FastCGI的进程数。根据官方建议,小于2GB内存的服务器,可以只开启64个进程,4GB以上内存的服务器可以开启200个进程。

<value name="max_children">5</value>

标签request_terminate_timeout用于设置FastCGI执行脚本的时间。默认是0s,也就是无限执行下去,可以根据情况对其进行修改。

<value name="request_terminate_timeout">0s</value>

标签rlimit_files用于设置PHP-FPM对打开文件描述符的限制,默认值为1024。这个标签的值必须和Linux内核打开文件数关联起来,例如要将此值设置为65535,就必须在Linux命令行执行'ulimit -HSn 65536'。

<value name="rlimit_files">1024</value>

标签max_requests指明了每个children最多处理多少个请求后便会被关闭,默认的设置是500。

pm.max_requests = 500

标签allowed_clients用于设置允许访问FastCGI进程解析器的IP地址。如果不在这里指定IP地址,Nginx转发过来的PHP解析请求将无法被接受。

<value name="allowed_clients">127.0.0.1</value>

5.管理FastCGI进程
在配置完php-fpm后,就可以启动FastCGI进程了。启动fastcgi进程有两种方式:

/usr/local/php/bin/php-cgi --fpm
或者
/usr/local/php/sbin/php-fpm start

建议采用第二种方式启动FastCGI进程。
/usr/local/php/sbin/php-fpm还有其他参数,具体为start|stop|quit|restart|reload|logrotate。
每个启动参数的含义如下:

  • q start,启动PHP的FastCGI进程。
  • q stop,强制终止PHP的FastCGI进程。
  • q quit,平滑终止PHP的FastCGI进程。
  • q restart,重启PHP的FastCGI进程。
  • q reload,重新加载PHP的php.ini。
  • q logrotate,重新启用log文件。
  • reload是个很重要的参数,它可以在PHP的FastCGI进程不中断的情况下重新加载改动过的php.ini,因此通过php-fpm可以平滑变更FastCGI模式下的PHP设置。
[root@server79 etc]# /etc/init.d/php-fpm start

配置nginx的主配置文件,打开与php的接口

[root@server79 conf]# pwd
/usr/local/lnmp/nginx/conf
[root@server79 conf]# vim nginx.conf
user nginx;
#
location ~ \.php$ {
root html; 
fastcgi_pass 127.0.0.1:9000; //本地9000端口
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
[root@server79 conf]# nginx -t^C
[root@server79 conf]# nginx -s reload^C
[root@server79 html]# pwd
/usr/local/lnmp/nginx/html
[root@server79 html]# cat index.php
<?php
phpinfo()?>

测试:浏览器中输入192.168.0.179/index.php,出现php页面

PHP解析Nginx日志
nginx日志格式

access_log日志格式

log_format main '$server_name$remote_addr$remote_user[$time_local]"$request"' 
      '$status$body_bytes_sent"$http_referer"' 
      '"$http_user_agent""$http_x_forwarded_for"';

日志参数

    server_name          : 虚拟主机的主机名称 
    remote_addr          : 远程客户端的ip地址 
    remote_user          : 远程客户端用户名称 
    time_local           : 访问的时间与时区 
    status           : 记录请求返回的http状态码 
    body_bytes_sent      : 发送给客户端的文件主体内容的大小 
    http_referer             : 从哪个页面链接访问过来  
    http_user_agent      : 客户端浏览器信息 
    http_x_forwarded_for     : 客户端的真实ip 

日志分割符
使用特殊的不可打印字符^A(ctrl+v,ctrl+a)作为日志分割符

根据关键字过滤文件内容

需求
根据http的请求里是否有“weibo”这个关键字提取文件的内容

php代码

/** 
  * Description:按行读取文件内容进行过滤匹配 
  * 
  * @return array 
  */ 
 function readFileContent ($filename) 
 { 
  $weibo_content = array(); 
  $fh = @fopen($filename, 'r'); 
   
  if ($fh) { 
   while (! feof($fh)) { 
    $row = fgets($fh, 4096); 
    $row_arr = explode("", $row); 
    if (isset($row_arr[3]) && preg_match('/weibo/', $row_arr[3])) { 
     $weibo_content[] = $row_arr; 
    } 
   } 
  } 
  fclose($fh); 
   
  return $weibo_content; 
 }
PHP 相关文章推荐
php 中include()与require()的对比
Oct 09 PHP
Discuz 模板引擎的封装类代码
Jul 18 PHP
php 格式化数字的时候注意数字的范围
Apr 13 PHP
php下网站防IP攻击代码,超级实用
Oct 24 PHP
PHP 查找字符串常用函数介绍
Jun 07 PHP
基于Zend的Config机制的应用分析
May 02 PHP
PHP基于数组实现的分页函数实例
Aug 20 PHP
php curl 获取https请求的2种方法
Apr 27 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
Nov 15 PHP
php表单文件iframe异步上传实例讲解
Jul 26 PHP
PHP 的Opcache加速的使用方法
Dec 29 PHP
laravel 使用事件系统统计浏览量的实现
Oct 16 PHP
ThinkPHP开发框架函数详解:C方法
Aug 14 #PHP
提高php编程效率技巧
Aug 13 #PHP
php轻量级的性能分析工具xhprof的安装使用
Aug 12 #PHP
详细解读PHP中接口的应用
Aug 12 #PHP
举例讲解PHP面对对象编程的多态
Aug 12 #PHP
详解PHP中的状态模式编程
Aug 11 #PHP
简单介绍PHP的责任链编程模式
Aug 11 #PHP
You might like
解决MySQL中文输出变成问号的问题
2008/06/05 PHP
PHP和.net中des加解密的实现方法
2013/02/27 PHP
PHP7 其他修改
2021/03/09 PHP
IE下使用cloneNode注意事项分享
2012/11/22 Javascript
js控制的遮罩层实例介绍
2013/05/29 Javascript
jquery 获取dom固定元素 添加样式的简单实例
2014/02/04 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
再分享70+免费的jquery 图片滑块效果插件和教程
2014/12/15 Javascript
JQuery仿小米手机抢购页面倒计时效果
2014/12/16 Javascript
javascript实现画不相交的圆
2015/04/07 Javascript
JavaScript中的slice()方法使用详解
2015/06/06 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
2016/06/22 Javascript
jquery遍历标签中自定义的属性方法
2016/09/17 Javascript
JS创建对象的写法示例
2016/11/04 Javascript
AngularJS基于ui-route实现深层路由的方法【路由嵌套】
2016/12/14 Javascript
JS敏感词过滤代码
2016/12/23 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
自带气泡提示的vue校验插件(vue-verify-pop)
2017/04/07 Javascript
基于Vue实现支持按周切换的日历
2020/09/24 Javascript
jQuery实现常见的隐藏与展示列表效果示例
2018/06/04 jQuery
微信小程序开发之改变data中数组或对象的某一属性值
2018/07/05 Javascript
vue(2.x,3.0)配置跨域代理
2019/11/27 Javascript
详解JS深拷贝与浅拷贝
2020/08/04 Javascript
利用Django框架中select_related和prefetch_related函数对数据库查询优化
2015/04/01 Python
TensorFlow打印tensor值的实现方法
2018/07/27 Python
django+xadmin+djcelery实现后台管理定时任务
2018/08/14 Python
在Python中使用defaultdict初始化字典以及应用方法
2018/10/31 Python
python生成器用法实例详解
2019/11/22 Python
Python龙贝格法求积分实例
2020/02/29 Python
新加坡领先的时尚生活方式零售品牌:CHARLES & KEITH
2018/01/16 全球购物
EJB实例的生命周期
2016/10/28 面试题
英语系毕业生自荐信
2013/10/31 职场文书
办加油卡单位介绍信
2014/01/09 职场文书
个人事迹材料范文
2014/12/29 职场文书
2015年法院工作总结范文
2015/04/28 职场文书
2016大学军训心得体会
2016/01/11 职场文书