分析php include require 情况

2009-10-14 9:04 am

其实php有get_include_files()函数可以打印出被引入的文件,也包括html等这样的文件,如果只想看文件的包含情况,这就够了,现在来介绍一个更好玩的东西,能通过图表来查看php引入文件的情况,这对程序的分析和调优还是很有好处的。
首先安装pecl扩展,inclued:

wget ......inclued.tar.gz
tar ....
cd ...
phpize
./configure
make
make install

这些命令就不具体写了,流程是这个样子的(其实在inclued的文档中都有)。
安装好后在php.ini中加入:

extension=inclued.so
inclued.enabled = On
inclued.dumpdir = /tmp/

apache restart
然后在你需要分析的php文件底部写入以下代码:

$fp = fopen('/tmp/wp.json', 'w');
if ($fp) {
         $clue = inclued_get_data();
         if ($clue) {
              fwrite($fp, json_encode($clue));
         }
         fclose($fp);
 }

在/tmp下能看到保存后json数据了,
接下来把inclued中的gengraph.php文件cp到/tmp下,
执行php gengraph.php -i (生成的json文件)
你会看到dot的文件和提示画图的命令"dot ....",接下来就是画图了,安装graphviz,

apt-get install graphviz

在执行前面提示的dot....就可以了看到include.png图片了。
如:

这个是缩图,全图比较大点,需要请查看

http://ls5pqq.blu.livefilestore.com/y1pTgyhqzYh7Eui6cIYW3-1Rq16w2-JqeeFy8k5fYXVKUV-Gpr9cG6UFaULrcXDtHQITpe77Qv9-APg1YkolS2cFOwzftvJqX2T/inclued_autoload.png

推荐(0)
收藏

linux 文件系统 && inode cache

2009-10-10 3:52 pm

最近在跟踪apc.stat参数的效果的时候遇到很多问题,为了一弄究竟,一直跟踪下来了,先上一个测试报告,
对zend framework空框架测试,开启apc或者eaccelerator这样的opcode缓存会提升很大的性能(废话),这个并不是我们要研究的,空的zend框架大概需要include 38个文件左右,试过将38个文件中大部分合并成一个文件,再测试,发现性能提升近50%,这个是非常诱人的,不管有没有opcode的缓存是一样的。apc.stat参数来控制每次是否检测涉及到的文件修改过没有,但是在仍然不是很理想,如对include_once和require_once是无效的,也对zend框架的require_once做了优化(官方提供的),改成autoload形式,效果也不明显,(修改文件缓存不更新,但是删除文件会报错),如果不使用zend框架来测试,写几个php文件包含apc.stat是完全没问题的,但是发现效果并不明显。
所以我认为在opcode缓存的情况下,每次检查文件是否修改过的操作并不是瓶颈,用strace(freebsd 下是ktrace)跟踪即使fstat操作。为了证实这点,也顺便对linux的文件系统做一个简单的分析。

引用一些linux文件系统的基础知识:原文地址: http://www.ibm.com/developerworks/linux/library/l-linux-filesystem/?S_TACT=105AGX52&S_CMP=cn-a-l

这个图很好的概述了linux文件系统,

Linux 以一组通用对象的角度看待所有文件系统。这些对象是超级块(superblock)、inode、dentry 和文件。超级块在每个文件系统的根上,超级块描述和维护文件系统的状态。文件系统中管理的每个对象(文件或目录)在 Linux 中表示为一个 inode。inode 包含管理文件系统中的对象所需的所有元数据(包括可以在对象上执行的操作)。另一组结构称为 dentry,它们用来实现名称和 inode 之间的映射,有一个目录缓存用来保存最近使用的 dentry。dentry 还维护目录和文件之间的关系,从而支持在文件系统中移动。

从图中也可以看出,inode和dentry(directory cache)都有cache,会将最近使用到的文件更新inode等缓存,缓存是保存在内存中的,所以读取缓存中的inode是没有io操作的,也就是非常高效的,下面附上linux 内核对inode结构的部分定义,/kernel/include/linux/fs.h中716行:

716 struct inode {
 717     struct hlist_node   i_hash;
 718     struct list_head    i_list;
 719     struct list_head    i_sb_list;
 720     struct list_head    i_dentry;
 721     unsigned long       i_ino;
 722     atomic_t        i_count;
 723     unsigned int        i_nlink;
 727     u64         i_version;
 728     loff_t          i_size;
 729 #ifdef __NEED_I_SIZE_ORDERED
 730     seqcount_t      i_size_seqcount;
 731 #endif
 732     struct timespec     i_atime;
 733     struct timespec     i_mtime;
 734     struct timespec     i_ctime;
742     const struct inode_operations   *i_op;
 743     const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */
}

能看出包括mtime和link等的元信息都在里面,所以要检查文件是否修改只需查看inode就足够了,inode 和目录缓存分别保存最近使用的 inode 和 dentry,且对于 inode 缓存中的每个 inode,在目录缓存中都有一个对应的 dentry。

其实 inode_operations 和 file_operations。这些结构表示可以在这个 inode 上执行的操作。inode_operations 定义直接在 inode 上执行的操作,而 file_operations 定义与文件和目录相关的方法(标准系统调用)。
dentry和super_block的结构在上面的文件中也有,不打出来了。

总结从以上的分析来看,有理由相信系统在判断一个文件是否修改过的操作上是花销是极小的,不会成为opcode检查中的瓶颈。 接下来继续往下跟踪,说明瓶颈可能出现在opcode的compile(include的开销)。

推荐(0)
收藏

php静态、全局变量及包含路径

2007-12-20 9:48 pm

静态变量只在当前文件内共享变量;
全局变量在整个进程内共享变量;
require和include的路径取决于最后执行的php文件的路径,如果写相对路径要注意了;

推荐(0)
收藏