目录
一.背景
二.Web请求与PHP生命周期
三.程序实现
四.小结
首页 php教程 php手册 异步日志输出方案

异步日志输出方案

Jun 06, 2016 pm 08:13 PM
php 了解 周期 异步 方案 日志 深入 背景 输出

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

— 深入了解PHP生命周期

一.背景

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

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

  • 连接数据库失败了,捕捉到异常后,往本地磁盘写入一条日志;
  • 图片上传时间超时,往本地磁盘写一条日志;
  • 渲染页面中出现XSS攻击,往网络日志服务器写一条日志;
  • 请求对方服务器Api接口,出现超时,往网络日志服务器写一条日志;
  • ……


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

  1. 对本地磁盘的IO提高或者对网络日志服务器请求出现超时;
  2. 若日志写失败,极有可能对后面程序片段的执行产生影响;

既然是日志,那么说明它并不是非常重要的数据,却不能因为记录日志的失败影响重要的业务,那么我们是否可以把日志输入放在所有程序都执行完成的时候处理呢?因此有必要深入了解请求执行的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时,将会按顺序促发以下几个阶段:

  1. MINIT(Module init)

    该阶段将调用PHP_MINIT_FUNCTION(extension)

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

  2. RINIT(Request init)

    该阶段将调用PHP_RINT_FUNCTION(extension)

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

  3. Execute php code

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

  4. RSHUTDOWN

    该阶段将调用PHP_RSHUTDOWN_FUNCTION(extension)

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

  5. 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的时候针对已经注册的事件进行处理,这些事件中可能就包括我们需要的日志输出。

该类实现的功能很简单:

  1. 需要一个增加事件的方法,把我们需要的处理事件过程放入;
  2. 需要一个调用事件的方法,把我们增加的所有事件在SHUTDOWN时调用;
  3. 最后需要注册方法,注册调用方法至SHUTDOWN中;

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

<?php /**

 * Manage php shutdown events.

 * @author Lancer He

 * @since  2014-08-21

 */

class Service_Core_ShutdownEvent {

    /**

     * array to store user events.

     * @var array

     */

    private static $_events = array();

    /**

     * register shutdown

     */

    public static function register() {

        register_shutdown_function(array('Service_Core_ShutdownEvent', 'call'));

    }

    /**

     * Register event.

     * @return boolean

     */

    public static function add() {

        $event = func_get_args();

        if ( empty($event) ) {

            trigger_error("Register event need method.");

            return false;

        }

        if ( ! is_callable($event[0]) ) {

            trigger_error("Register event can not be call.");

            return false;

        }

        self::$_events[] = $event;

        return true;

    }

    /**

     * call event when you need.

     */

    public function call() {

        foreach (self::$_events as $event) {

            $callback = array_shift($event);

            call_user_func_array($callback, $event);

        }

    }

}

登录后复制

对于编写好的处理事件类,我们使用一个简单的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程序结束后处理我们需要的逻辑过程,如日志输出,邮件通知等,降低了程序中的处理额外业务逻辑的风险。


原创文章,转载请注明:

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

原文地址:http://www.crackedzone.com/asynchronous-log-output-scheme.html

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

CakePHP 项目配置 CakePHP 项目配置 Sep 10, 2024 pm 05:25 PM

在本章中,我们将了解CakePHP中的环境变量、常规配置、数据库配置和电子邮件配置。

适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

CakePHP 日期和时间 CakePHP 日期和时间 Sep 10, 2024 pm 05:27 PM

为了在 cakephp4 中处理日期和时间,我们将使用可用的 FrozenTime 类。

CakePHP 文件上传 CakePHP 文件上传 Sep 10, 2024 pm 05:27 PM

为了进行文件上传,我们将使用表单助手。这是文件上传的示例。

CakePHP 路由 CakePHP 路由 Sep 10, 2024 pm 05:25 PM

在本章中,我们将学习以下与路由相关的主题?

讨论 CakePHP 讨论 CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP 是 PHP 的开源框架。它的目的是使应用程序的开发、部署和维护变得更加容易。 CakePHP 基于类似 MVC 的架构,功能强大且易于掌握。模型、视图和控制器 gu

如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写

CakePHP 创建验证器 CakePHP 创建验证器 Sep 10, 2024 pm 05:26 PM

可以通过在控制器中添加以下两行来创建验证器。

See all articles