发新话题
打印

Linux 下 L.A.M.P 环境部署详细步骤

本主题由 bottle 于 2008-6-5 01:42 移动

Linux 下 L.A.M.P 环境部署详细步骤

L.A.M.P 环境部署详细步骤

L.A.M.P 环境部署详细步骤


本文所用的操作系统为 CentOS 3.8,如果使用 Red Hat AS3/4 则不能使用 yum RPM 包管理命令!
推荐使用 CentOS 3.8 系统。

一、系统约定软件源代码包存放位置
/usr/local/src

源码包编译安装位置(prefix)
/usr/local/software_name

脚本以及维护程序存放位置
/usr/local/sbin

MySQL 数据库位置
/var/lib/mysql

Apache 网站根目录
/data/wwwroot

Apache 虚拟主机日志根目录
/data/logs/www

Apache 运行账户
www:www

yum RPM包信息文件
/etc/yum.list


二、系统环境部署及调整
1. 检查系统是否正常
   # more /var/log/messages   (检查有无系统内核级错误信息)
   # dmesg (检查硬件设备是否有错误信息)
   # ifconfig(检查网卡设置是否正确)
   # ping www.163.com  (检查网络是否正常)

2. 关闭不需要的服务
   # ntsysv
   以下仅列出需要启动的服务,未列出的服务一律关闭:
   crond
   irqbalance (仅当服务器CPU为S.M.P架构或支持双核心、HT技术时,才需开启,否则关闭。)
   haldaemon 管理系统硬件信息和其他的硬件相关的消息   (hotplug,udev)
   messagebus 这是 Linux 的 IPC(Interprocess Communication,进程间通讯)服务。确切地说,它与 DBUS 交互,是重要的系统服务。强烈建议开启它。
   microcode_ctl 在linux下对P6/NetBurst CPU做微代码更新
微代码(Microcode)是Intel的P6和NetBurst两个家族CPU的一种更新特性。通过从Intel的站点下载微代码,加载到处理器核中,对一些BUG进行勘误
   kudzu 该服务进行硬件探测,并进行配置。如果更换硬件或需要探测硬件更动,开启它。但是绝大部分的台式机和服务器都可以关闭它,仅仅在需要时启动。
   ntpd 该服务通过互联网自动更新系统时间。如果你能永久保持互联网连接,建议开启它,但不是必须的。
   network
   random
   sendmail
   sshd
   syslog

3. 对TCP/IP网络参数进行调整,加强抗SYN Flood能力
   # echo 'net.ipv4.tcp_syncookies = 1' >> /etc/sysctl.conf
   # sysctl -p

4. 配置yum
   # rpm --import /usr/share/doc/centos-release-3/RPM-GPG-KEY-CentOS-3
   # yum list | tee /etc/yum.list

5. 修改命令history记录
   # vi /etc/profile
     找到 HISTSIZE=1000 改为 HISTSIZE=50



6. 定时校正服务器时间
   # yum install ntp
   # crontab -e
加入一行:
每15分钟
*/15 * * * * ntpdate 210.72.145.44

#每天早上6点10分
10 6 * * * ntpdate 210.72.145.44

#每两个小时
0 */2 * * * ntpdate 210.72.145.44

## 210.72.145.44 为中国国家授时中心服务器地址。

7. 重新启动系统
   # init 6

8. 使用 yum 程序安装所需开发包(以下为标准的 RPM 包名称)
复制内容到剪贴板
代码:
yum -y install \
"autoconf" \
"automake" \
"bison" \
"bzip2-devel" \
"cpp" \
"cyrus-sasl" \
"cyrus-sasl-plain" \
"expect" \
"flex" \
"fam-devel" \
"freetype-devel" \
"gd" \
"gcc" \
"gcc-c++" \
"gcc-g77" \
"gdbm-devel" \
"glibc-devel" \
"glibc-headers" \
"glibc-kernheaders" \
"libtool" \
"libxml2" \
"libf2c" \
"libjpeg-devel" \
"libpng-devel" \
"libtiff-devel" \
"libc-client-devel" \
"libstdc++-devel" \
"libmcrypt" \
"libmcrypt-devel" \
"libxslt-devel" \
"ncurses-devel" \
"net-snmp-devel" \
"openssl" \
"openssl-devel" \
"openssl-perl" \
"perl-libwww-perl" \
"perl-HTML-Parser" \
"perl-HTML-Tagset" \
"perl-URI" \
"perl-Crypt-Blowfish" \
"perl-Crypt-CBC" \
"perl-Date-Calc" \
"perl-MIME-tools" \
"perl-Convert-BinHex" \
"perl-IO-stringy" \
"perl-MailTools" \
"perl-TimeDate" \
"perl-DBI" \
"pkgconfig" \
"postgresql-devel" \
"pam-devel" \
"rpm-build" \
"zlib-devel"
9. 源码编译安装所需包(Source)
   (1) GD2
       # cd /usr/local/src
       # wget http://download.discuz.net/env/gd-2.0.33.tar.gz
       # tar xzvf gd-2.0.33.tar.gz
       # cd gd-2.0.33
       # ./configure --prefix=/usr/local/gd2
       # make
       # make install

   (2) LibXML2
       # cd /usr/local/src
       # wget http://download.discuz.net/env/libxml2-2.6.26.tar.bz2
              # tar xjvf libxml2-2.6.26.tar.bz2
              # cd libxml2-2.6.26
              # ./configure --prefix=/usr/local/libxml2
              # make
              # make install

   (3) Apache日志截断程序
# cd /usr/local/src
# wget http://download.discuz.net/env/cronolog-1.6.2.tar.gz
# tar xzvf cronolog-1.6.2.tar.gz
# cd cronolog-1.6.2
# ./configure –prefix=/usr/local/cronolog
# make
# make install


10. 升级OpenSSL和OpenSSH
    # cd /usr/local/src
    # wget http://download.discuz.net/env/openssl-0.9.7j.tar.gz
    # wget http://download.discuz.net/env/openssh-4.2p1.tar.gz
    # tar xzvf openssl-0.9.7j.tar.gz
    # cd openssl-0.9.7j
    # ./config --prefix=/usr/local/openssl
    # make
    # make test
    # make install
    # cd ..
    # tar xzvf openssh-4.2p1.tar.gz
    # cd openssh-4.2p1
# ./configure  \
"--prefix=/usr" \
"--with-pam" \
"--with-zlib" \
"--with-ssl-dir=/usr/local/openssl" \
"--with-md5-passwords"
    # make
    # make install
    禁止root直接登录,此处先建立一个普通系统用户:
    # useradd username
    # passwd username
    # echo 'Protocol 2' >> /etc/ssh/sshd_config
    # echo 'Protocol 2' >> /usr/etc/sshd_config
    # echo 'PermitRootLogin no' >> /etc/ssh/sshd_config
    # echo 'PermitRootLogin no' >> /usr/etc/sshd_config
    # /etc/rc.d/init.d/sshd restart




三、编译安装L.A.M.P环境
1. 下载软件
    # cd /usr/local/src
    # wget http://download.discuz.net/env/httpd-2.2.3.tar.bz2
    # wget http://download.discuz.net/env/mysql-5.0.27.tar.gz
    # wget http://download.discuz.net/env/php-5.2.0.tar.bz2
# wget http://download.discuz.net/env/Z ... glibc21-i386.tar.gz
2. 编译安装MySQL
    # tar xzvf mysql-5.0.27.tar.gz
    # cd mysql-5.0.27
# ./configure \
        "--prefix=/usr/local/mysql" \
        "--localstatedir=/var/lib/mysql" \
        "--with-comment=Source" \
        "--with-server-suffix=-Comsenz" \
        "--with-mysqld-user=mysql" \
        "--without-debug" \
        "--with-big-tables" \
        "--with-charset=gbk" \(或utf8)
        "--with-collation=gbk_chinese_ci" \(utf8_general_ci)
        "--with-extra-charsets=all" \
        "--with-pthread" \
        "--enable-static" \
        "--enable-thread-safe-client" \
        "--with-client-ldflags=-all-static" \
        "--with-mysqld-ldflags=-all-static" \
        "--enable-assembler" \
        "--without-isam" \
        "--without-innodb" \
        "--without-ndb-debug"
    # make
    # make install
# useradd mysql
    # cd /usr/local/mysql
    # bin/mysql_install_db --user=mysql
    # chown -R root:mysql .
    # chown -R mysql /var/lib/mysql
# cp share/mysql/my-huge.cnf /etc/my.cnf
    # cp share/mysql/mysql.server /etc/rc.d/init.d/mysqld
    # chmod 755 /etc/rc.d/init.d/mysqld
    # chkconfig --add mysqld
    # /etc/rc.d/init.d/mysqld start
# bin/mysql -u root password "password_for_root"

为了能让系统找到mysql,请运行如下命令
# PATH=$PATH:/usr/local/mysql/bin
# export PATH
# echo "/usr/local/mysql/lib/mysql" >> /etc/ld.so.conf
# ldconfig


如果编译时没有设置默认字符集可以修改mysql配置文件添加如下设置
vi /etc/my.cnf
复制内容到剪贴板
代码:
[mysqld]
character_set_server=utf8

[mysql]
default-character-set=utf8
参考:
引用:
CFLAGS="-O3 -mcpu=pentium4" CXX=gcc CXXFLAGS="-O3 -march=pentium4 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/home/mysql/ --without-debug   --with-unix-socket-path=/home/mysql/tmp/mysql.sock --with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static --enable-assembler --with-extra-charsets=gbk,gb2312,utf8 --without-innodb --without-isam --with-pthread --enable-thread-safe-client
配置mysql
gcc的相关参数:

-O3 \
-O
-O1
优化.对于大函数,优化编译占用稍微多的时间和相当大的内存.
不使用`-O'选项时,编译器的目标是减少编译的开销,使编译结果能够调试.语句是独立的:如果在 两条语句之间用断点中止程序,你可以对任何变量重新赋值,或者在函数体内把程序计数器指到其他语句,以及从源程序中 精确地获取你期待的结果.
不使用`-O'选项时,只有声明了register的变量才分配使用寄存器.编译结果比不用 `-O'选项的PCC要略逊一筹.
使用了`-O'选项,编译器会试图减少目标码的大小和执行时间.
如果指定了`-O'选项, `-fthread-jumps'和`-fdefer-pop'选项将被 打开.在有delay slot的机器上, `-fdelayed-branch'选项将被打开.在即使没有帧指针 (frame pointer)也支持调试的机器上, `-fomit-frame-pointer'选项将被打开.某些机器上 还可能会打开其他选项.
-O2
多优化一些.除了涉及空间和速度交换的优化选项,执行几乎所有的优化工作.例如不进行循环展开(loop unrolling)和函数内嵌(inlining).和-O选项比较,这个选项既增加了编译时间,也提高了生成代码的 运行效果.
-O3
优化的更多.除了打开-O2所做的一切,它还打开了-finline-functions选项.
-O0
不优化.
如果指定了多个-O选项,不管带不带数字,最后一个选项才是生效的选项。
-mcpu=pentium4 \根据CPU类型优化编译,可以让你的mysq表现更好!可选项目很 多:i386, i486, i586, i686, pentium, pentium-mmx, pentiumpro, pentium2, pentium3, pentium4, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-4, athlon-xp,athlon-mp,winchip-c6, winchip2 , c3.
-fomit-frame-pointer \对于不需要栈指针的函数就不在寄存器中保存指针,因此可以忽略存储和检索地址的代码,并将寄存器用于普通用途。所有"-O"级别都打开着一选项,但仅在调试器可以不依靠栈指针运行时才有效。建议不需要调试的情况下显式的设置它。

configure的相关参数:
--prefix=/home/mysql/  \指定安装目录
--without-debug \去除debug模式
--with-extra-charsets=gbk,gb2312,utf8  \添加gbk,gb2312,utf8中文字符支持
--with-pthread \强制使用pthread库(posix线程库)
--enable-assembler \使用一些字符函数的汇编版本
--enable-thread-safe-client \以线程方式编译客户端
--with-client-ldflags=-all-static \以纯静态方式编译客户端
--with-mysqld-ldflags=-all-static \以纯静态方式编译服务端
--without-isam \去掉isam表类型支持,现在很少用了,isam表是一种依赖平台的表
--without-innodb \去掉innodb表支持,innodb是一种支持事务处理的表,适合企业级应用

以下是示例:
CFLAGS="-O3 -mcpu=pentium4" CXX=gcc CXXFLAGS="-O3 -march=pentium4 -felide-constructors -fno-exceptions -fno-rtti -fomit-frame-pointer -ffixed-ebp" \
./configure \
"--prefix=/usr/local/mysql" \
"--localstatedir=/var/lib/mysql" \
"--with-mysqld-user=mysql" \
"--with-big-tables" \
"--with-charset=utf8" \
"--with-collation=utf8_general_ci" \
"--with-extra-charsets=all" \
"--with-pthread" \
"--with-client-ldflags=-all-static" \
"--with-mysqld-ldflags=-all-static" \
"--enable-static" \
"--enable-thread-safe-client" \
"--enable-assembler" \
"--without-isam" \
"--without-innodb" \
"--without-debug" \
"--without-ndb-debug"
3. 编译安装Apache
    # cd /usr/local/src
# tar xjvf httpd-2.2.3.tar.bz2
# cd httpd-2.2.3/srclib/apr
#./configure --prefix=/usr/local/apr
#make && make install
# cd httpd-2.2.3/srclib/apr-util
#./configure --prefix=/usr/local/apr --with-apr=/usr/local/apr
#make && make install
# cd httpd-2.2.3
#./configure \
"--prefix=/usr/local/apache2" \
"--enable-module=so" \ # --enable-so by apache 2.2.9
"--with-perl" \  # apache 2.2.9 没有这个配置项
"--enable-proxy=shared" \
"--enable-proxy-connect=shared" \
"--enable-proxy-ftp=shared" \
"--enable-proxy-http=shared" \
"--enable-proxy-ajp=shared" \
"--enable-proxy-balancer=shared" \
"--with-apr-util=/usr/local/apr-util" \
"--with-apr=/usr/local/apr" \
"--enable-ssl=shared" \
"--enable-mods-shared=all" \
"--enable-deflate=shared" \
"--enable-expires=shared" \
"--enable-rewrite=shared" \
"--enable-static-support" \
"--enable-static-htpasswd" \
"--enable-static-htdigest" \
"--enable-static-rotatelogs" \
"--enable-static-logresolve" \
"--enable-static-htdbm" \
"--enable-static-ab" \
"--enable-static-checkgid" \
"--disable-userdir"
# make
# make install
# cp /usr/local/apache2/bin/apachectl /etc/init.d/httpd
# vi /etc/init.d/httpd
在 #!/bin/sh 下面增加以下内容:(使httpd 可以用 chkconfig 加入到服务中)
引用:
./configure \
"--prefix=/usr/local/apache2" \
"--with-zlib" \
"--enable-so" \
"--enable-module=so" \
"--enable-ssl=shared" \
"--enable-mods-shared=all" \
"--enable-deflate=shared" \
"--enable-expires=shared" \
"--enable-rewrite=shared" \
"--enable-static-support" \
"--enable-static-htpasswd" \
"--enable-static-htdigest" \
"--enable-static-rotatelogs" \
"--enable-static-logresolve" \
"--enable-static-htdbm" \
"--enable-static-ab" \
"--enable-suexec" \
"--with-suexec-caller=daemon" \
"--with-suexec-docroot=/var/www" \
"--enable-static-checkgid" \
"--disable-userdir"
# chkconfig: 2345 70 30
# description: Apache is a World Wide Web server.  It is used to serve \
#              HTML files and CGI.
# processname: httpd


将httpd 加入到服务并自动启动
# chkconfig --add httpd
# chkconfig httpd on

启动apache

# service httpd start

4. 编译安装PHP
#-------------------------------------------------
./configure \
"--prefix=/usr/local/php" \
"--with-apxs2=/usr/local/apache2/bin/apxs" \
"--with-config-file-path=/etc" \
"--with-zlib" \
"--with-libxml-dir" \
"--enable-mbstring" \
"--with-bz2" \
"--enable-bcmath" \
"--with-curl" \
"--enable-ftp" \
"--with-gd" \
"--with-jpeg-dir" \
"--with-png-dir" \
"--with-ttf" \
"--enable-gd-native-ttf" \
"--with-freetype-dir" \
"--with-iconv-dir" \
"--enable-zend-multibyte" \
"--enable-mbstring" \
"--disable-ipv6" \
"--with-mysql=/usr/local/mysql" \
"--enable-sockets" \
"--with-oci8" \
"--enable-inline-optimization" \
"--disable-debug"
#-------------------------------------------------
./configure \
"--prefix=/usr/local/php" \
"--with-apxs2=/usr/local/apache2/bin/apxs" \
"--with-config-file-path=/etc" \
"--with-mysql=/usr/local/mysql" \
"--with-libxml-dir=/usr/local/libxml2" \
"--with-gd=/usr/local/gd2" \
"--enable-gd-native-ttf" \
"--with-oci8=/opt/oracle" \ #可选
"--with-oracle=/opt/oracle" \ #可选
"--with-jpeg-dir" \
"--with-png-dir" \
"--with-bz2" \
"--with-freetype-dir" \
"--with-iconv-dir" \
"--with-zlib-dir" \
"--enable-mbstring" \
"--disable-ipv6" \ # IPv6 离我们还好远,暂时不用它
"--disable-cgi" \   # 出于安全考虑,禁用 CGI 支持
"--disable-cli"  \   # 出于安全考虑,禁止编译出 php Command Line Shell 命令
"--enable-inline-optimization" \
"--disable-debug"
    # make
    # make install
# cp php.ini-dist /etc/php.ini
引用:
./configure \
"--prefix=/usr/local/php" \
"--with-apxs2=/usr/local/apache2/bin/apxs" \
"--with-mysql=/usr/local/mysql" \
"--with-config-file-path=/etc" \
"--with-zlib" \
"--with-mcrypt" \
"--with-pear" \
"--with-libxml-dir" \
"--with-bz2" \
"--with-gd" \
"--with-openssl" \
"--with-jpeg-dir" \
"--with-png-dir" \
"--with-ttf" \
"--with-pgsql" \
"--with-snmp" \
"--with-imap" \
"--with-imap-ssl" \
"--with-kerberos" \
"--enable-gd-native-ttf" \
"--with-freetype-dir" \
"--with-iconv-dir" \
"--enable-mbstring" \
"--enable-ftp" \
"--enable-bcmath" \
"--enable-zend-multibyte" \
"--enable-mbstring" \
"--enable-sockets" \
"--enable-ctype" \
"--enable-exif" \
"--enable-sigchild" \
"--enable-magic-quotes" \
"--enable-inline-optimization" \
"--disable-ipv6" \
"--disable-debug"
5. 安装Zend Optimizer
    # cd /usr/local/src
    # tar xzvf ZendOptimizer-3.2.0-linux-glibc21-i386.tar.gz
# ./ZendOptimizer-3.2.0-linux-glibc21-i386/install.sh
    安装Zend Optimizer过程的最后不要选择重启Apache。

6. 整合Apache与PHP
# vi /usr/local/apache2/conf/httpd.conf
找到:
AddType application/x-gzip .gz .tgz
在该行下面添加
AddType application/x-httpd-php .php
AddOutputFilterByType DEFLATE text/html text/plain text/xml

找到:
<IfModule dir_module>
    DirectoryIndex index.html index.html.var
</IfModule>
将该行改为
<IfModule dir_module>
    DirectoryIndex index.html index.htm index.php
</IfModule>

找到:
#Include conf/extra/httpd-mpm.conf
#Include conf/extra/httpd-info.conf
#Include conf/extra/httpd-vhosts.conf
#Include conf/extra/httpd-default.conf
去掉前面的“#”号,取消注释,设置相关的模块配置文件。

修改完成后保存退出。
# /usr/local/apache2/bin/apachectl restart
7. 查看确认L.A.M.P环境信息,提升 PHP 安全性
   # echo '#!/usr/local/php/bin/php \
<?php \
         phpinfo(); \
         ?>' > /usr/local/php/phpinfo.php
   # chmod 755 /usr/local/php/phpinfo.php
   # /usr/local/php/phpinfo.php > /usr/local/php/phpinfo
   # more /usr/local/php/phpinfo
   检查phpinfo中的各项信息是否正确。

   确认 PHP 能够正常工作后,在 php.ini 中进行设置提升 PHP 安全性。
   # vi /etc/php.ini
       找到:
       disable_functions =
       设置为:
       disable_functions = phpinfo,passthru,exec,system,popen,chroot,escapeshellcmd,escapeshellarg,shell_exec,proc_open,proc_get_status,ini_restore

最后,重新启动 Apache 服务即可。

TOP

为 PHP 应用提速、提速、再提速!,第 1 部分: 使用操作码缓存软件提升性能和吞吐量
PHP 是一种脚本语言,常用于创建 Web 应用程序。它易于掌握,并能迅速生成可视化结果。然而,由于 PHP 是以解释的方式执行的,所以 PHP 代码每次执行时都会被解析和转换成操作码(opcode)。操作码缓存能消除这项重复的工作,使 PHP 应用程序运行得更快。
在很短的时间内,PHP 成为了一种非常流行的开发 Web 应用程序的程序设计语言。对初学者来说,PHP 易于安装和学习。对于有经验的开发人员而言,PHP(从 V5 开始)提供了强大的面向对象特性。PHP 开发人员拥有庞大的群体,大量的开源及商业库和工具扩展了该核心语言的功能。PHP 能迅速产生可视化结果,因此备受众人推崇。
与其他开发 Web 应用程序的脚本语言(包括 Perl、Python 和 Ruby)相似,每次 HTTP 请求调用时,PHP 代码都会被解析和翻译为操作码(PHP 引擎直接执行的原语指令 —— 类似于汇编语言)再执行。在要求很低或可忽略的情况下,服务器看上去能立即执行这个复杂的解释过程。但是一旦处理的页面增加,解释 —— 从本质上说,重复工作 —— 就会对服务器造成很大的负担。在某些情况下,“编译” PHP 代码的时间会远远超过执行该代码所需的时间。因此,当需求增加时,您常常会自食其果,因为处理这些不断解释和动态生成的页面需要消耗更多的系统资源。
若您对处理器和 RAM 的预算没有限制,那么就大可不必通过优化应用栈(硬件、操作系统、数据库、Web 服务器和 PHP 代码)来保证站点的可响应性。然而,由于资金通常都是最缺乏的资源,所以改善性能是必不可少的。调优意味着对系统增加内存、修改操作系统参数、加速 Web 或数据库服务器、提高代码效率或者这其中的一些组合。每一项都有其各自的作用。
不要浪费周期 —— 重复使用
节约 CPU 周期的另一种方法是减少运行 PHP 应用程序所需的重复工作。当然,没有必要每次都把同样的 PHP 代码翻译一遍。PHP 代码被翻译成操作码后,可以把它保存起来并重复使用 —— 直到原始代码被修改。确实,缓存 —— 用于保存和重用 PHP 操作码 —— 是几种 PHP 加速器内部的机制,包括开源 Alternative PHP Cache (APC)、支持 PHP 的 Turck MMCache、XCache、eAccelerator 和商业 Zend Platform。后三类加速器能够缓存和优化字节码,这为系统提供了更多的速度提升。
这个月,我将探究如何安装、部署和配置 XCache。XCache 相对较新,但是很多站点使用它的效果都很好。此外,XCache 易于构建、安装和配置,因为它是做为 PHP 扩展实现的。不需对 Apache 和 PHP 进行重编译。
本文基于 XCache V1.2.0。它可为 PHP V4.3.11 至 V4.4.4、PHP V5.1.x 至 V5.2.x 以及 PHP V6 的早期版本提供可靠支持(XCache 并不支持 PHP V5.0.x)。XCache 兼容 mod_php 和 FastCGI 但并不支持 Common Gateway Interface (CGI) 和命令行 PHP 解释器。XCache 源代码能构建在许多系统上,包括 FreeBSD、Sun Solaris、Linux® 和这里所示的 Mac OS X。使用 Cygwin UNIX® 仿真环境或 Visual C,能在 Microsoft® Windows® 上构建 XCache。还可以为 Cygwin 或原生 Win32 构建 XCache。后者与 PHP 的官方 Win32 版本兼容。
本文的演示基于 Apache V2.2.3、PHP V5.2.0、XCache V1.2.0(2006 年 10 月发布)和 Mac OS X V10.4.8 Tiger 上的 Xcode V2.4.1。硬件平台为配有 2-GHz Intel® Core Duo 处理器和 2 GB RAM 的 Apple MacBook。




回页首
构建 XCache 的基本步骤
在开始之前,首先确保 PHP 正常安装并核实 phpize 是否位于 shell 的 PATH 下。同时,还需要一个 C 编译器,例如 GNU Compiler Collection (GCC),和一组包含 make 和 m4 的开发工具。在 Mac OS X 上,免费的 Xcode 软件开发环境提供了必需的构建工具。
完成以下操作步骤,在 Mac OS X 上构建、部署 XCache 并对其进行性能检测。在其他平台上构建 XCache 与之类似。如果使用 Linux,则其发行版可能已经包含了 XCache 或者已经将其以预先打包好的格式提供给您。
增加 Mac OS X 的共享内存
首先增加 Mac OS X 上留出的共享内存总量。要实现这一目的,需创建(或编辑)文件 /etc/sysctl.conf 并创建如下条目:
清单 1. 增加 Mac OS X 上留出的共享内存总量
kern.sysv.shmmax=33554432
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=8192

这些设置把共享内存总量增加到了 32 MB。如还需进一步扩展共享内存,可以把 kern.sysv.shmall 设定为 kern.sysv.shmmax 除以硬件页面大小。使用 sysctl hw.pagesize 能获得硬件页面大小。例如,假设需要 128 MB 的共享内存,那么设定 kern.sysv.shmmax=134217728 并设定 kern.sysv.shmall=32768。
重启 Mac OS X 使修改生效。重启后,检验新设置是否生效,键入:
sysctl -a | grep kern.sysv

通过源代码构建 XCache
接下来,通过源代码构建 XCache。从 http://xcache.lighttpd.net 处下载源代码。下载完后解压代码,并转换到 .tar 文件创建的新目录。
清单 2. 通过源代码构建 XCache
$ cd /tmp
$ wget http://210.51.190.228/pub/XCache/Releases/xcache-1.2.0.tar.gz
$ tar xzf xcache-1.2.0.tar.gz
$ cd xcache

运行 phpize 为编译 XCache 做准备。
清单 3. 运行 phpize
$ phpize
Configuring for:
PHP Api Version: 20020918
Zend Module Api No: 20020429
Zend Extension Api No: 20050606

运行 configure,创建适合于原生操作系统的 makefile。
清单 4. 运行 configure 创建 makefile
./configure --enable-xcache --enable-xcache-coverager --enable-xcache-optimizer --with-php-config=/usr/local/php/bin/php-config

checking build system type... i686-apple-darwin8.8.1
checking host system type... i686-apple-darwin8.8.1
...
creating libtool
configure: creating ./config.status
config.status: creating config.h

此处,--enable-xcache 选项包含 XCache 支持,--enable-xcache-coverager 选项包含用于测量加速器功效的附加特性。要启用操作码优化,添加 --enable-xcache-optimizer。
当然,下一步将使用 make 命令行构建和安装代码。运行 make,然后作为 root 用户运行 make install 。
清单 5. 利用 make 构建和安装代码
$ make
...
cp ./xcache.so /Users/strike/tmp/xcache/modules/xcache.so
Build complete.
$ sudo make install
Installing shared extensions: /usr/lib/php/extensions/no-debug-non-zts-20020429/

如果上述两项操作顺利完成,那么 XCache 将位于 /usr/lib/php/extensions/no-debug-non-zts-20020429/xcache.so。(路径 /usr/lib/php/extensions/no-debug-non-zts-20020429 反映了正在使用的 API 版本和用于构建 PHP 的编译选项。如果启用了试用的 Zend Thread Safety 特性,则 "no-debug" 应为 "debug","non-zts" 应为 "zts"。)
修改 php.ini 文件
因为安装了扩展,所以必需修改 php.ini 文件,使之包含 XCache 扩展并对其进行配置。打开文件 /private/etc/php.ini,在其中添加如下代码行:
清单 6. 为 XCache 扩展修改 php.ini 文件
[xcache-common]
zend_extension = /usr/lib/php/extensions/no-debug-non-zts-20020429/xcache.so
[xcache.admin]
; Change xcache.admin.user to your preferred login name xcache.admin.user = "admin"
; Change xcache.admin.pass to the MD5 fingerprint of your password
; Use md5 -s "your_secret_password" to find the fingerprint
xcache.admin.pass = "0ad72f3f352fcd8acdf266bafd0ac48d"
[xcache]
; Change xcache.size to tune the size of the opcode cache
xcache.size = 24M
xcache.shm_scheme = "mmap"
xcache.count = 2
xcache.slots = 8K
xcache.ttl = 0
xcache.gc_interval = 0
; Change xcache.var_size to adjust the size of variable cache
xcache.var_size = 8M
xcache.var_count = 1
xcache.var_slots = 8K
xcache.var_ttl = 0
xcache.var_maxttl = 0
xcache.var_gc_interval = 300
xcache.test = Off
xcache.readonly_protection = On
xcache.mmap_path = "/tmp/xcache"
xcache.coredump_directory = ""
xcache.cacher = On
xcache.stat = On
xcache.optimizer = Off
[xcache.coverager]
xcache.coverager = On
xcache.coveragedump_directory = ""

注意:为了简明起见,此处省略了一些注释。要了解每个参数的含义,请参阅 XCache 源代码中 xcache.ini 文件设置的例子。
操作码和变量缓存的大小是 32 MB,这是 /etc/rc 留出的最大值。对于 Mac OS X,xcache.mmap_path 必须为文件名。因为 PHP 代码将在 MacBook 上运行,所以 xcache.count 应设为 2,表示 MacBook 中 CPU 的数量。要访问 XCache 统计信息页面,需改变 xcache.admin.pass 设置。运行:
$ md5 -s "password"

此处 password 为您的密码。把输出复制给 xcache.admin.pass。例如,若需将密码设定为 op3nsesam3,可以运行:
$ md5 -s "op3nsesam3"
MD5 ("op3nsesam3") = cd959ac3debe8f587546a3fa353b3268

然后把 cd959ac3debe8f587546a3fa353b3268 复制给 xcache.admin.pass。
重启 Web 服务器
设置好 XCache 后,重启 Apache Web 服务器。对于大多数系统,可以以 root 用户的身份使用 apachectl restart 进行重启。
$ sudo apachectl restart
/usr/sbin/apachectl restart: httpd restarted
空间出租:P4 3.0+1G+RIAD 1 160G+PHP+IIS+MYSQL+MDaemon

QQ:126682182
Email:hhyisw@163.com
Home:http://www.stksky.com

TOP

为 PHP 应用提速、提速、再提速!,第 2 部分: 分析 PHP 应用程序以查找、诊断和加速运行缓慢的代码
如果 PHP 应用程序运行缓慢,可以使用分析器找出应用程序究竟在哪些方面浪费了时间。可以将语句、循环、函数、类或者是运行缓慢的库作为分析目标。如果不是时间而是内存使用出现了问题,那么一个优秀的分析器还可以显示组件的内存占用情况。

PHP 应用提速、提速、再提速!” 系列文章的 第 1
部分 演示了如何使用 XCache(PHP 操作码缓存)加速整个站点。XCache(仅是少数几种缓存包中的一种)保留了编译过程的输出,去掉了其他冗余的工作。只要页面没有发生变化,缓存后的页面就能够胜任代理的作用。当页面发生变化时,缓存后的页面就会变为无效并被替换掉。

操作码缓存 —— 以及一个操作码优化器,通常由相同的包提供 —— 是一种加快站点响应的低成本技术。很多缓存包是免费的,并且是开源的,无需改变任何代码即可从中受益。
当然,在某些应用程序中,相比较实际的执行时间,将 PHP 源代码文件翻译为其相应的操作码所需的时间微不足道。连接到远程数据库服务器,使用低效的 SQL 语句进行查询,以及其他大量解析和操作数据的工作都非常的繁琐,也因此增加了开销,甚至产生浪费。良好的网络设计和灵巧的数据库结构可以使时间冗长和查询缓慢的情况有所改善,如果需要的话还可以向友好的专家请求帮助。但是,如果代码运行缓慢,您可能更希望自己处理。
但是从何开始呢?正如人们普遍认为的,在代码完成前调试代码的做法很不明智 —— 因为代码的首次实现可能会非常的迅速。当代码正确且能实现相应的功能时,不管其表面上看起来运行缓慢还是实际如此,首先要做的就是对其性能进行测试或基准测试。不执行这样的诊断而尝试去优化代码无疑是在黑暗中摸索。
一个简单的性能指标是挂钟时间(wall clock time),或测量页面请求与完成呈现之间的实际延迟。对于某些情况 —— 比如在您自己的工作站本地运行的 Web 服务器、数据库和浏览器 —— 挂钟时间能够提供信息。然而,挂钟时间对于其他大多数情况而言并无实际意义,比如网络延迟时间、活动的 Web 服务器或者活动的数据库。
一种更精确的测量 —— 甚至可以测量运行单个源代码语句的时间 —— 可以采用代码分析器。分析器通常被实现为 PHP 运行时引擎的扩展,记录语句开始和结束的 delta、记录程序开始和结束之间的 delta 并捕获对来到的请求形成响应的总时间。有了这种垂直度,就可以将语句、循环、函数、类或者是运行缓慢的库作为分析目标。如果不是时间而是内存使用出现了问题,那么一个优秀的分析器还可以显示组件的内存占用情况。
PHP 的一个较流行的分析器是 Xdebug,它还为交互地调试 PHP 应用程序提供了服务器挂钩(hook)。(参见“调试的更好方法”以了解更多信息。该系列的另一部分将探讨高级交互式调试。) Xdebug 很容易从源代码构建,将其作为 Zend 扩展进行安装也非常简单。(现在已有针对某些平台的二进制文件。)当就绪后,对基于 PHP 页面的每个请求都将生成可在 KCacheGrind 中查看的数据集。
构建并安装 Xdebug
如果具备了 PHP 实用工具 phpizephp-config,而且具有对系统的 php.ini 配置文件的访问权,那么安装和设置 Xdebug 只需几分钟的时间。下面给出的指导说明针对 Linux®,不过在 Mac OS X 上的安装步骤实际上与此类似。(您可以从 Xdebug Web 站点找到针对 Microsoft® Windows® 的 Xdebug 预编译版本。)
Xdebug 的最新版本为 V2.0.0RC3(最终版本 V2.0.0 在您阅读此文时也许已经可用)。下载并解包 tarball,然后切换到源代码的子目录。确保 phpizephp-config 位于 shell 的 PATH,准备使用 phpize 进行构建。
清单 1. 设置 Xdebug
$ wget http://www.xdebug.org/files/xdebug-2.0.0RC3.tgz
$ tar xzf xdebug-2.0.0RC3.tgz
$ cd xdebug-2.0.0RC3/xdebug-2.0.0RC3
$ phpize
Configuring for:
PHP Api Version: 20020918
Zend Module Api No: 20020429
Zend Extension Api No: 20050606

phpize 的产品是一个脚本 —— 名为配置 —— 它对余下的构建过程进行配置。要构建 Xdebug,在 make 后紧接着输入 ./configure 即可。
清单 2. 构建 Xdebug
$ ./configure
--enable-xdebug
--with-php-config=/usr/local/php/bin/php-config


checking build system type... i686-apple-darwin8.8.1
checking host system type... i686-apple-darwin8.8.1
checking for egrep... grep -E
...
$ make
...
Build complete.
(It is safe to ignore warnings about tempnam and tmpnam).

make 命令生成 Xdebug 扩展,xdebug.so。剩下的工作就是使用 sudo make install 进行安装。
$ sudo make install
Installing shared extensions: /usr/lib/php/extensions/no-debug-non-zts-20020429/

注: 如果在终端窗口中运行最后一个命令,请选择并复制最后一步中发出的目录。在下一个步骤中将会用到它。
最后,要使配置数据可视化,必须使用 KCacheGrindGraphViz。包含 K Desktop Environment (KDE)的 Linux 发行版很可能已经含有了 KCacheGrindGraphViz。如果没有包含,适合您所使用的 Linux 的那些版本也不难找到。Debian 用户可以使用 Advanced Packaging Tool (APT) 快速安装 KCacheGrindGraphViz 以及所有包的依赖关系。
清单 3. 安装 KCacheGrind
$ apt-cache search kcachegrind
valgrind-callgrind - call-graph skin for valgrind
kcachegrind - visualisation tool for valgrind profiling output
kcachegrind-converters - format converters for KCachegrind profiling visualisation tool
$ apt-cache search graphviz
graphviz - rich set of graph drawing tools
graphviz-dev - graphviz Libs and Headers against which to build applications
graphviz-doc - additional documentation for graphviz
libdeps-renderer-dot-perl - DEPS renderer plugin using GraphViz/dot
...
$ sudo apt-get install kcachegrind graphviz ...

如果没有将 KDE 安装到系统中,KCacheGrindGraphViz 以及所有必要的内容将占用大约 90 MB 的磁盘空间。




回页首
配置 Xdebug
安装了 Xdebug 扩展后,就可以准备启用和配置该扩展了。在文本编辑器中打开 php.ini,并添加以下代码行。
清单 4. 启用和配置该扩展

zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so
xdebug.profiler_output_dir = "/tmp/xdebug"
xdebug.profiler_enable = Off
xdebug.profiler_enable_trigger = 1
第一行 zend_extension 加载 Xdebug 扩展。第二行命名放置分析器输出的目录。如果需要的话,创建命名的目标并更改其模式以允许用户对 Web 服务器进行写访问。
第三行禁用了分析器。然而,第四行将在设置 HTTP GETPOST 参数 XDEBUG_PROFILE 时启用分析器。(如果您希望一直使用分析器,在第三行代码中将 Off 更改为 On。)
添加这几行代码并验证了输出目录是可写的,然后重新启动 Web 服务器。对于其他 PHP 扩展,要验证 Xdebug 是否安装并可用,可以创建一个简单的骨架 PHP 程序来调用 phpinfo() 并查看结果。应该能够看到类似于图 1 所示的内容。(为简便起见,省略了完整输出的部分内容。)
图 1. Phpinfo 指明 Xdebug 是否已安装

您还可以向下滚动到 Zend 徽标。如果正确安装并配置了 Xdebug,它将显示在徽标的旁边。




回页首
使用分析器
要分析代码,只需将浏览器指向 PHP 应用程序即可。如果您将分析器设置为对每个触发逐个解决的方式,将 XDEBUG_PROFILE=1 追加到 URL 中,或者,像下面一样,将参数嵌入到表单中。
作为一个示例,我们来分析一下这个简单的 ACME Fibonacci Maker,fibonacci.php,如清单 5 所示。为方便起见,将 XDEBUG_PROFILE 参数设置在表单的隐藏变量内。(当代码投入生产时,很可能将禁用 Xdebug,呈现这个变量将不会造成什么损失。)
清单 5. Fibonacci.php
<?php
function fib($nth = 1) {
if ( $nth < 2 ) {
return( $nth ); }
return( fib( $nth - 1) + fib( $nth - 2 ) );
}
?> <html>
<head>
<title>ACME Fibonacci Maker</title>
</head>
<body>
<h2>Try the ACME Fibonacci Maker!</h2>
<form action="fibonacci.php" method="POST">
<input type="hidden" name="XDEBUG_PROFILE" value="1" />
Enter a number: <input type="text" name="n"></input>
</form>
<hr />
<?php if ( ! empty( $_REQUEST['n'] ) ) {
$n = $_REQUEST['n'] % 10;
$suffix = array( 1 => "st", 2 => "nd", 3 => "rd" );
if ( $_REQUEST['n'] < 4 || $_REQUEST['n'] > 20 ) {
$suffix = $suffix[$n];
}
else {
$suffix = 'th';
}
echo '<p>The ' . $_REQUEST['n'] . $suffix .' Fibonacci number is ';
echo fib( $_REQUEST['n'] ) . '</p>';
}
?>
</body>
</html>

将浏览器指向 http://localhost/fibonacci.php(或者合适的 URL)并输入数字 —— 比如,16。其结果 —— Fibonacci 系列的第 16 个元素 —— 如图 2 所示。
图 2. 示例 Fibonacci 应用程序

如果将分析器输出目录中的内容(名为 php.ini)列出来的话,应该能看到类似 cachegrind.out.951917687 这样名称的文件。cachegrind.out. 前缀是固定的。默认情况下,数值后缀是目录路径到 fibonacci.php 文件的 CRC32 散列。因此,如果每一个应用程序都位于自己的目录,那么每个程序的输出将根据文件名而被分隔。(如果您更喜欢将输出与时间相关联,将下面这行代码:
xdebug.profiler_output_name = timestamp

添加到 php.ini。)
从终端窗口启动 KCacheGrind 并打开 cachegrind.out.951917687。将立即打开一个类似于图 3 的新窗口。
图 3. KCacheGrind 应用程序

单击 Callees 选项卡,双击源代码中突出显示的行,并从 Grouping 列表选择 Source File 。所看到的视图应变为类似图 4 所示的内容。
图 4. 查看结果

正如您预期的一样,实际上全部的处理时间(70,989 毫秒的 99.87%)都花费在 3193 次对 fib() 函数的调用上了。要加快该应用程序(随着进一步执行 Fibonacci 序列,程序会随之变慢),应该避免重新计算 Fibonacci 数字这样代价高昂的重复工作。事实上,ACME Fibonacci Maker 能够很好地进行计算重用。
下面展示了 fib() 函数的优化版本。新的版本用内存换来了时间上的节省,因为它保留了中间的计算以便以后使用。图 5 展示了分析结果:与上次的 3192 次函数调用相比,这里仅需要 30 次调用(并且只有一半的调用需要计算结果),而时间则减少为只有 20 毫秒。
清单 6. 更新了的 fib() 函数
function fib($nth = 1) {
static $fibs = array();
if ( ! empty ($fibs[$nth] ) ) { return( $fibs[$nth] );
}
if ( $nth < 2 ) {
$fibs[$nth] = $nth;
}
else { $fibs[$nth - 1] = fib( $nth - 1 );
$fibs[$nth - 2] = fib( $nth - 2 );
$fibs[$nth] = $fibs[$nth - 1] + $fibs[$nth -2];
}
return( $fibs[$nth] );
}
?>

图 5. 加快了的 Fibonacci 函数

虽然单次运行应用程序能够指出一些问题(可以试试上面原始的应用程序中的 Fibonacci 序列的第 50 个元素),通常,还是需要通过几次调用收集统计信息以及查看模式。
如果保留默认的 “crc32” 命名模式,每次运行 fibonacci.php 时,将重写数据文件。然而,可以通过在 php.ini 中设置 xdebug.profiler_append = 1 改变这种行为并将后续运行追加到相同的文件。更改之后重新启动 Web 服务器。
图 6 显示了三次运行 Fibonacci Maker 之后数据合计的示例。总时间稍大于两秒;其中 99.97% 的时间花费在了 fib() 上。图 6 显示了 Call Graph 选项卡,它由 GraphVizdot 工具生成。关于 KCacheGrind 的具体用法不在本文讨论的范围之内,但是可以从网上获得其完整的文档。KCacheGrind 可以以很多种方法对数据进行交叉分析,根据您希望解决的问题选择合适的方法。
图 6. 合计分析数据


调试的更好方法
除了分析 PHP 应用程序,还可以在发生错误并进行交互式调试时,配置 Xdebug 扩展(如其名字暗示的一样)来提供详细的栈跟踪和错误消息。栈跟踪和错误消息可以指出错误的原因,而交互式调试允许每次逐步调试代码中的一条指令,查看程序变量的类型和值,并检查所有的 PHP 超全局变量,包括进来的请求参数。
本系列的下一篇文章将具体介绍交互式调试。同时,您可以启用几个 Xdebug 特性来说明应用程序在发生错误时的状态:
  • 无论何时只要应用程序出现错误,设置 xdebug.default_enable=On 显示栈跟踪。如果您已经花费时间安装了 Xdebug,那么只要进行代码开发就启用这个特性。
  • 还可以设置 xdebug.show_local_vars=1 来进一步显示最顶部范围内的所有变量。
  • xdebug.var_display_max_childrenxdebug.var_display_max_dataxdebug.var_display_max_depth> 是相关的三个设置,分别用来控制因 xdebug.show_local_vars 的使用而显示的变量的属性数、字符串长度和嵌套深度。
可以在 Xdebug Web 站点找到更多信息。




回页首
分析类
如果没有具体的代码,那么很难演示具有意义的分析,下面这个示例是十分典型的代码,展示了从中所能获得的信息。清单 7 显示了一个装配玩具火箭的应用程序(人为设计)。这种玩具火箭由几个部分组成,生产每一个部分都需要一定的时间。在 PHP 中,使用类代表每个组成部分,使用实例方法表示每个部分的构造时间。您可以将这个玩具看作是一个应用程序,并把每个部分看作是该应用程序的功能。
清单 7. 模拟玩具装配的一组 PHP 类
<?php
define( 'BOOSTER', 5 );
define( 'CAPSULE', 2 );
define( 'MINUTE', 60 );
define( 'STAGE', 3 );
define( 'PRODUCTION', 1000 );
class Part {
function Part() {
$this->build( MINUTE );
}
function build( $delay = 0 ) {
if ( $delay <= 0 )
return;
while ( $delay-- > 0 ) {
}
}
}
class Capsule extends Part {
function Capsule() {
parent::Part();
$this->build( CAPSULE * MINUTE );
}
}
class Booster extends Part {
function Booster() {
parent::Part();
$this->build( BOOSTER * MINUTE );
}
}
class Stage extends Part {
function Stage() {
parent::Part();
$this->build( STAGE * MINUTE );
}
}
class SpaceShip {
var $booster;
var $capsule; var $stages;
function SpaceShip( $numberStages = 3 ) {
$this->booster = new Booster();
$this->capsule = new Capsule();
$this->stages = array();
while ( $numberStages-- >= 0 ) {
$stages[$numberStages] = new Stage();
}
}
}
$toys = array();
$count = PRODUCTION;
while ( $count-- >= 0 ) {
$toys[] = new SpaceShip( 2 );
}
?>
<html>
<head>
<title>
Toy Factory Output
</title>
</head>
<body>
<h1>Toy Production</h1>
<p>Built <? echo PRODUCTION . ' toys' ?></p>
</body>
</html>

运行这些代码将生成一个新的数据文件。同样,将数据加载到 KCacheGrind。如果切换到 SourceCall Graph 选项卡,将看到类似图 7 所示的视图。
图 7. 太空船应用程序的配置文件

Flat Profile 窗格(左面)显示了应用程序调用的所有函数(方法)。最左面的列展示了近似的累计总数,第二列展示了每种方法的单独测试,第三列列出了调用该方法的次数。在调用图表中使用有颜色的方块反映图表内容,这非常方便,能够很容易地将事件序列与其花费的时间关联起来。
很明显,构建阶段所使用的时间代价最昂贵。构建每一部分所需的系统开销(使用 Part 的构造器表示)次之。再看一下 PHP 自身的 define() 函数,它只花费了很少的开销。
最后,还可以查看内存的使用情况。从靠近顶部的下拉菜单中选择 MemoryClass,然后切换到顶部以及底部的 TypesCaller Map 选项卡。您看到的屏幕应该类似图 8。
图 8. 太空船应用程序的内存使用情况





回页首
找回周期
和其他众多 PHP 扩展一样,Xdebug 容易构建、安装快捷且易于配置 —— 所有这些工作 10 分钟内即可完成。如果您已经优化了 Apache 安装并且对应用程序进行了缓存,但是性能仍然很差,那么可以考虑一下代码的运行。算法是否有效?代码是否过于复杂?是否重复实现了 PHP 已提供的函数?
当然,如果不能判断出应用程序的瓶颈所在,那么就必须进行查找并加以修复。不要只凭猜测 —— 要进行分析!您可能会惊讶于宝贵的计算周期是如何被轻意耗费掉的。
并且永远不要忘记:要在生产服务器中禁用 Xdebug,因为启用它总会增加系统开销。
参考资料
学习
获得产品和技术
  • 下载 Xdebug 软件。
  • 使用 IBM
    试用软件 改进您的下一个开源开发项目,这些软件可下载或从 DVD 获得。
讨论
关于作者


Martin Streicher 是 Linux Magazine 的主编。他从普度大学获得了计算机科学硕士学位,从 1982 年开始用 Pascal、C、Perl、Java 和(最近)Ruby 编程语言编写类 UNIX 的系统。

源文档 <http://www.ibm.com/developerworks/cn/opensource/os-php-fastapps2/index.html>
空间出租:P4 3.0+1G+RIAD 1 160G+PHP+IIS+MYSQL+MDaemon

QQ:126682182
Email:hhyisw@163.com
Home:http://www.stksky.com

TOP

发新话题