— 深入了解PHP生命周期 一.背景 日志在WEB应用中的使用非常广泛,记录访问者IP,访问者操作的数据,接口请求的信息,异常提示信息等,尤其在产品环境中,我们往往需要通过日志来分析当前应用的运营情况,是否在存在一些不可见的未知错误。 在程序实现过程

— 深入了解PHP生命周期

一.背景

日志在WEB应用中的使用非常广泛,记录访问者IP,访问者操作的数据,接口请求的信息,异常提示信息等,尤其在产品环境中,我们往往需要通过日志来分析当前应用的运营情况,是否在存在一些不可见的未知错误。

在程序实现过程中,我们设计的输出日志往往都是在程序运行当中,如:

连接数据库失败了,捕捉到异常后,往本地磁盘写入一条日志;

图片上传时间超时,往本地磁盘写一条日志;

渲染页面中出现XSS攻击,往网络日志服务器写一条日志;

请求对方服务器Api接口,出现超时,往网络日志服务器写一条日志;

……

这种实时输出日志的方式往往存在两个主要的问题:

对本地磁盘的IO提高或者对网络日志服务器请求出现超时;

若日志写失败,极有可能对后面程序片段的执行产生影响;

既然是日志,那么说明它并不是非常重要的数据,却不能因为记录日志的失败影响重要的业务,那么我们是否可以把日志输入放在所有程序都执行完成的时候处理呢?因此有必要深入了解请求执行的PHP生命周期过程。

二.Web请求与PHP生命周期

PHP有两种运行模式:WEB模式,CLI模式

无论是哪种模式,PHP的工作原理都是一致的,都需要SAPI的运行

在Web请求时,Nginx就必然要和FastCGI通信,通过php_fpm调用php-cgi,需要通过SAPI接口,进入PHP的脚本执行。

在CLI模式下直接操作php-cgi也需要通过SAPI执行,以下展示了整个处理过程:

SAPI也叫Service API,在整个请求过程中承担了很重要的角色,外部应用通过SAPI进行对上层调用,所谓的外部应用可以理解为Apache,FastCgi等,上层也就是我们写的PHP程序。

以下是SAPI的简单示意图:

当请求调用SAPI时,将会按顺序促发以下几个阶段:

MINIT(Module init)

该阶段将调用PHP_MINIT_FUNCTION(extension)

该函数作用为遍历需要加载的扩展,并初始化扩展,注册模块常量,类等。

RINIT(Request init)

该阶段将调用PHP_RINT_FUNCTION(extension)

该函数的作用为遍历加载的扩展,并针对请求信息进行一些初始化工作,比如记录请求开始时间,初始化请求$_POST, $_GET全局遍历,若开启session模块下,注册全局Session变量等。

Execute php code

这部分就是自己编写的PHP代码,也就是真正执行的我们代码执行的部分。

RSHUTDOWN

该阶段将调用PHP_RSHUTDOWN_FUNCTION(extension)

该函数的作用遍历加载的扩展,并针对请求信息进行一些析构工作,比如记录请求结束时间,把相应的输入写入日志,开启session模块下,全局Session变量写到tmp目录下文件等。

MSHUTDOWN

该阶段将调用PHP_MSHUTDOWN_FUNCTION(extension)

该函数的作用为当Web请求结束或命令行执行脚本结束后会执行,完成释放资源操作。

可以通过下图直观的看出php执行test.php生命周期的过程:

其实我们编写的程序在复杂PHP生命周期中往往只运行在第3步,假如我们的日志能在第4步处理,那是不是可以避免文章开头提出的问题?那么除了利用编写扩展注册PHP_RSHUTDOWN_FUNCTION方法,我们还可以通过register_shutdown_function()注册的自定义函数,这些自定义函数在我们编写的PHP代码结束的时候将会被调用。

register_shutdown_function是php系统函数,注册shutdown的函数将会在PHP生命周期中第4阶段进行执行,如程序结束,或出现exit/die等命令后都会触发注册函数。

三.程序实现

为此利用register_shutdown_function,我们可以设计一个处理事件类,该类能够注册我们需要的事件,在PHP Shutdown的时候针对已经注册的事件进行处理,这些事件中可能就包括我们需要的日志输出。

该类实现的功能很简单:

需要一个增加事件的方法,把我们需要的处理事件过程放入;

需要一个调用事件的方法,把我们增加的所有事件在SHUTDOWN时调用;

最后需要注册方法,注册调用方法至SHUTDOWN中;

以下是该类(Service_Core_ShutdownEvent)的实现代码:

对于编写好的处理事件类,我们使用一个简单的Log类来验证这个注册事件类是否可行,这个Log类(Service_Core_NetLog)具体的程序就不展示了,主要演示以下两个方法:Service_Core_NetLog::trace(string $string);

Service_Core_NetLog::notice(string $string);

两个方法都比较简单,作用往磁盘中按照一定规则输出一行Log,因此我在一个控制器中来测试它,通过Web访问或者CLI的方式请求:

通过Sleep的方式来验证,上图红框处可以更加直观的验证有两条日志是在程序结束以后写入磁盘。

四.小结

通过深入了解PHP生命周期,更直观的理解PHP运行的机制,通过注册shutdown方式(register_shutdown_function)在PHP程序结束后处理我们需要的逻辑过程,如日志输出,邮件通知等,降低了程序中的处理额外业务逻辑的风险。

原创文章,转载请注明:

原文标题:异步日志输出方案

cli能记日志web不能php,异步日志输出方案相关推荐

  1. C++ LinuxWebServer项目(5)同步异步日志系统

    一.前言 对于任何一个服务器而言,日志系统的设计是非常重要的,尝试设计一个简易的同步异步日志系统来完成系统日志的记录. 二.基础知识 日志,由服务器自动创建,并记录运行状态,错误信息,访问数据的文件. ...

  2. java 多线程 异步日志_精彩技巧(1)-- 异步打印日志的一点事

    一.前言 最近刚刚结束转岗以来的第一次双11压测,收获颇多,难言言表, 本文就先谈谈异步日志吧,在高并发高流量响应延迟要求比较小的系统中同步打日志已经满足不了需求了,同步打日志会阻塞调用打日志的线程, ...

  3. log4j2 异步日志

    Log4j2异步日志 异步日志 log4j2最大的特点就是异步日志,其性能的提升主要也是从异步日志中受益,我们来看看如何使用log4j2的异步日志. 同步日志 异步日志 Log4j2提供了两种实现日志 ...

  4. 双缓冲异步日志(Async Logging)

    文章目录 一.日志系统简介 二.功能需求 三.性能需求 四.高效的异步日志 1.异步日志的概念 2.双缓冲异步日志解析 3.AsyncLogging源码 4.代码运行图示 五.双缓冲异步日志的相关问题 ...

  5. 探索Java日志的奥秘:底层日志系统-log4j2

    前言 log4j2是apache在log4j的基础上,参考logback架构实现的一套新的日志系统(我感觉是apache害怕logback了). log4j2的官方文档上写着一些它的优点: 在拥有全部 ...

  6. cli能记日志web不能php,ThinkPHP6.0日志变化

    ### 2019 年 7 月 28 日 发布 `6.0`的日志类比之前版本完善了很多,主要新特性包括: * 日志信息格式化 * 多通道写入支持 * 延时/实时写入 * 日志信息处理事件 * 日志级别指 ...

  7. c++异步日志队列_Logback 配置文件这么写,日志 TPS 提高 10 倍

    点击蓝色"java版web项目"关注我哟 加个"星标",优质文章,第一时间送达 上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家 下一篇:这2 ...

  8. log4j mysql 异步_spring boot:配置druid数据库连接池(开启sql防火墙/使用log4j2做异步日志/spring boot 2.3.2)...

    一,druid数据库连接池的功能? 1,Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 2,druid的官方站: http ...

  9. Elasticsearch:使用 Filebeat 从 Node.js Web 应用程序提取日志

    本指南演示了如何从 Node.js Web 应用程序中提取日志并将它们安全地传送到 Elasticsearch Service 部署中. 你将设置 Filebeat 来监控具有标准 Elastic C ...

最新文章

  1. 本地清除电脑缓存后,mongodb数据库无法连接
  2. 社区电商平台小区乐获GGV领投超1亿美元融资
  3. (十一)python3 只需3小时带你轻松入门——面向对象
  4. @Autowired和构造方法执行的顺序解析
  5. S3C2440 偷学
  6. kotlin环境配置
  7. flash cs4中3D特性之PerspectiveProjection属性设置
  8. PYTHON自动化Day9-发邮件、面向对象、类、私有、继承
  9. Pareto Optimality 帕累托最优 是什么
  10. 高等数学 第七版 上册 下册 答案
  11. 蓝牙5.0芯片NRF52840详细参数介绍
  12. 如何对自动驾驶技术进行全面检验?
  13. mysql命令分号_MySql常用命令:注意命令后面的分号!
  14. GeoServer发布OSM地图
  15. iOS多线程编程之NSThread的使用(★★★推荐,为原作者点赞★★★)
  16. 文末福利 | 吐血整理!140种Python标准库、第三方库和外部工具都有了
  17. win7下搭载ubuntu双系统,独立引导
  18. Layui使用中遇到的问题
  19. 【附源码】国内首届Discord场景创意编程开源项目
  20. JavaScript中的异步、同步

热门文章

  1. Galaxy Project | 一些尝试与思考
  2. 为什么我参加了那么多学术会议依旧一无所获?
  3. MMinte:预测微生物群体内代谢物互作
  4. java制作画布_java – 使用自定义方法绘制到画布?
  5. python使用matplotlib可视化、为可视化图像添加图例(legend)、自定义图例的字体格式、字体大小、字体颜色等
  6. R语言使用pwr包的pwr.r.test函数对相关信息分析进行效用分析(power analysis)、在已知效应量(effect size)、显著性水平、效用值的情况下计算需要的样本量
  7. python使用imbalanced-learn的SMOTETomek方法同时进行上采样和下采样处理数据不平衡问题
  8. import h5py ImportError: DLL load failed: the specified module could not be found
  9. 验证曲线( validation curve)是什么?如何绘制验证曲线( validation curve)?验证曲线( validation curve)详解及实践
  10. oracle 存储过程= 1,oracle 存储过程1