在我们编译安装Apache 之前,要考虑的是让Apache 在什么样的模式下运行,因为从Apache 2.0

就加入了MPM(Multi-Processing Modules,多道处理模块)。
Apache 2.0 在性能上的改善最吸引人。在支持POSIX 线程的Unix 系统上,Apache 可以通过不
同的MPM 运行在一种多进程与多线程相混合的模式下,增强部分配置的可扩充性能。相比于Apache
1.3,2.0 版本做了大量的优化来提升处理能力和可伸缩性,并且大多数改进在默认状态下即可生效。
但是在编译和运行时刻,2.0 也有许多可以显著提高性能的选择.
毫不夸张地说,MPM 的引入是Apache 2.0 最重要的变化。大家知道,Apache 是基于模块化的设
计,而Apache 2.0 更扩展了模块化设计到Web 服务器的最基本功能。服务器装载了一种多道处理模
块,负责绑定本机网络端口、接受请求,并调度子进程来处理请求。扩展模块化设计有两个重要好
处:
◆ Apache 可以更简洁、有效地支持多种操作系统;
◆ 服务器可以按站点的特殊需要进行自定制。
在用户级,MPM 看起来和其它Apache 模块非常类似。主要区别是在任意时刻只能有一种MPM 被
装载到服务器中。

prefork 的工作原理及配置
如果不用“--with-mpm”显式指定某种MPM,prefork 就是Unix 平台上缺省的MPM。它所采用
的预派生子进程方式也是Apache 1.3 中采用的模式。prefork 本身并没有使用到线程,2.0 版使用
它是为了与1.3 版保持兼容性;另一方面,prefork 用单独的子进程来处理不同的请求,进程之间
是彼此独立的,这也使其成为最稳定的MPM 之一。

若使用prefork,在make 编译和make install 安装后,使用“httpd -l”来确定当前使用的
MPM,应该会看到prefork.c(如果看到worker.c 说明使用的是worker MPM,依此类推)。再查看
缺省生成的httpd.conf 配置文件,里面包含如下配置段:<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

prefork 的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足
MinSpareServers 设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创
建四个……如此按指数级增加创建的进程数,最多达到每秒32 个,直到满足MinSpareServers 设
置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程。
从而减小了系统开销以增加性能。
MaxSpareServers 设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache 会自动
kill 掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers 小,Apache 会自
动把其调整为MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers 和
MaxSpareServers。
MaxRequestsPerChild 设置的是每个子进程可处理的请求数。每个子进程在处理了
“MaxRequestsPerChild”个请求后将自动销毁。0 意味着无限,即子进程永不销毁。虽然缺省设
为0 可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:
◆ 可防止意外的内存泄漏;
◆ 在服务器负载下降的时侯会自动减少子进程数。
因此,可根据服务器的负载来调整这个值。笔者认为10000 左右比较合适。
MaxClients 是这些指令中最为重要的一个,设定的是Apache 可以同时处理的请求,是对
Apache 性能影响最大的参数。其缺省值150 是远远不够的,如果请求总数已达到这个值(可通过
ps -ef|grep http|wc -l 来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是
系统资源还剩下很多而HTTP 访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来
动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache 默认的限制不能大于
256。如果把这个值设为大于256,那么Apache 将无法起动。事实上,256 对于负载稍重的站点也
是不够的。在Apache 1.3 中,这是个硬限制。如果要加大这个值,必须在“configure”前手工修
改的源代码树下的src/include/httpd.h 中查找256,就会发现“#define HARD_SERVER_LIMIT 256”
这行。把256 改为要增大的值(如4000),然后重新编译Apache 即可。在Apache 2.0 中新加入了
ServerLimit 指令,使得无须重编译Apache 就可以加大MaxClients。下面是笔者的prefork 配置段:
<IfModule prefork.c>
StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 2000
MaxClients 1000
MaxRequestsPerChild 10000
</IfModule>

上述配置中,ServerLimit 的最大值是20000,对于大多数站点已经足够。如果一定要再加
大这个数值,对位于源代码树下server/mpm/prefork/prefork.c 中以下两行做相应修改即可:
#define DEFAULT_SERVER_LIMIT 256#define MAX_SERVER_LIMIT 20000

worker的工作原理及配置
相对于prefork,worker 是2.0 版中全新的支持多线程和多进程混合模型的MPM。由于使
用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器。但是,
worker 也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。这种MPM 的
工作方式将是Apache 2.0 的发展趋势。
在configure -with-mpm=worker 后,进行make 编译、make install 安装。在缺省生成的
httpd.conf 中有以下配置段:<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>

worker 的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含
固定的ThreadsPerChild 线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线
程,MinSpareThreads 和MaxSpareThreads 设置了最少和最多的空闲线程数;而MaxClients 设置了
所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进
程。
MinSpareThreads 和MaxSpareThreads 的最大缺省值分别是75 和250。这两个参数对Apache
的性能影响并不大,可以按照实际情况相应调节。

ThreadsPerChild 是worker MPM 中与性能相关最密切的指令。ThreadsPerChild 的最大缺
省值是64,如果负载较大,64 也是不够的。这时要显式使用ThreadLimit 指令,它的最大缺省值
是20000 。上述两个值位于源码树server/mpm/worker/worker.c 中的以下两行: #define
DEFAULT_THREAD_LIMIT 64

#define MAX_THREAD_LIMIT 20000
这两行对应着ThreadsPerChild 和ThreadLimit 的限制数。最好在configure 之前就把64
改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因Apache 不起动使
系统很不稳定。
Worker 模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild 值决定的,
应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子
进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。这
两个值位于源码树server/mpm/worker/worker.c 中的以下两行:#define DEFAULT_SERVER_LIMIT 16

#define MAX_SERVER_LIMIT 20000
需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild 的值必须大
于等于MaxClients,而且MaxClients 必须是ThreadsPerChild 的整数倍,否则Apache 将会自动调
节到一个相应值(可能是个非期望值)。下面是笔者的worker 配置段:<IfModule worker.c>
StartServers 3
MaxClients 2000
ServerLimit 25
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 200
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>

通过上面的叙述,可以了解到Apache 2.0 中prefork 和worker 这两个重要MPM 的工作原
理,并可根据实际情况来配置Apache 相关的核心参数,以获得最大的性能和稳定性。

源码安装LAMP

源代码编译都是使用C语言编写的,需要在本机编译才能安装。
检查gcc,可用命令gcc -v

可以卸载默认的低版本的环境

rpm -qa | grep -i httpd
rpm -e httpXXXX
yum remove

rpm -qa | grep -i mysql

rpm -qa | grep -i php

安装libxml2 库文件
libxml2 是个xml的c语言版的解析器。

# tar xf libxml2-2.6.30.tar.gz 
# cd libxml2-2.6.30

# ./configure --prefix=/usr/local/libxml2 && make && make install


安装libmcrypt库
libmcrypt 加密解密库
# tar xf libmcrypt-2.5.8.tar.gz
# ./configure  --prefix=/usr/local/libmcrypt && make && make install

安装zlib库

zlib是提供数据压缩用的函式库


# tar xf zlib-1.2.3.tar.bz2 
# ./configure --prefix=/usr/local/zlib && make && make install

安装libpng 库
png图片处理
./configure --prefix=/usr/local/libpng && make && make install


安装jpeg6库
安装GD2库前所需的jpeg6库,需要手动创建目录

# mkdir -p /usr/local/jpeg6/bin
# mkdir -p /usr/local/jpeg6/lib
# mkdir -p /usr/local/jpeg6/include
# mkdir -p /usr/local/jpeg6/man/man1


# ./configure \
> --prefix=/usr/local/jpeg6 \
> --enable-shared \                #建立共享库使用的GNU的libtool
> --enable-static   #建立静态库使用的GNU的libtool

# make && make install

安装freetype   字体库

# ./configure --prefix=/usr/local/freetype && make && make install

安装autoconf 库
Autoconf是一个用于生成可以自动地配置软件源代码包以适应多种Unix类系统的 shell脚本的工具。

# tar xf autoconf-2.63.tar.gz
# ./configure && make && make install

安装GD库
php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片

# tar xf gd-2.0.33.tar.gz
# ./configure --prefix=/usr/local/gd2 --with-zlib=/usr/local/zlib/ --with-jpeg=/usr/local/jpeg6/
--with-png=/usr/local/libpng/ --with-freetype=/usr/local/freetype/

会看到
** Configuration summary for gd 2.0.33:

   Support for PNG library:          yes
   Support for JPEG library:         yes
   Support for Freetype 2.x library: yes
   Support for Fontconfig library:   yes
   Support for Xpm library:          yes
   Support for pthreads:             yes

   make && make install


安装apache2 服务器
为了试验采用worker模式

# tar xf httpd-2.2.17.tar.gz 

# ./configure --prefix=/usr/local/apache2work \
> --with-mpm=worker \ #指定worker模式
> --with-z=/usr/local/zlib/ \ #指定zlib库的位置
> --with-include-apr \ #使用捆绑apr
> --disable-userdir \ #请求映射到用户特点目录
> --sysconfdir=/etc/apache2 \ #配置文件位置
> --enable-so \ #以动态共享对象编译
> --enable-deflate=shared #缩小传输码
> --enable-expires=shared #期满头控制
> --enable-rewrite=shated #基于规则的URL
> --enable-static-suport #建立一个静态链接版本

make $$ make install

# cp apachectl /etc/init.d/apache
# chmod +x /etc/init.d/apache 
# /etc/init.d/apache start
# netstat -anpt | grep 80
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      13116/httpd

可以看到五个进程。
ps -ef | grep httpd
root     13116     1  0 14:38 ?        00:00:00 /usr/local/apache2work/bin/httpd -k start
daemon   13117 13116  0 14:38 ?        00:00:00 /usr/local/apache2work/bin/httpd -k start
daemon   13118 13116  0 14:38 ?        00:00:00 /usr/local/apache2work/bin/httpd -k start
daemon   13120 13116  0 14:38 ?        00:00:00 /usr/local/apache2work/bin/httpd -k start
daemon   13121 13116  0 14:38 ?        00:00:00 /usr/local/apache2work/bin/httpd -k start
root     13221 15015  0 14:39 pts/1    00:00:00 grep httpd

观察上面进程列表,发现 进程 13116 的父进程 pid 是1,同时它也是 进程的父进程。
为什么是5个进程呢?5个进程之间有什么关系呢?
mpm_default.h 中设置了默认进程数(DEFAULT_START_DAEMON),最大进程数(DEFAULT_MAX_FREE_DAEMON),最小进程数(DEFAULT_MIN_FREE_DAEMON)。在没有参数配置的情况下,会应用这些值。在 2.2.17 的版本中, DEFAULT_START_DAEMON 的值是 3。所以,上面的5个进程的组成是:一个listen 进程,3个 recv进程.还有一个进程,我就不知道啦。

修改配置文件 http.conf,加入以下内容,设置主线程为1:
 
# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_worker_module>
    StartServers          1
    MaxClients           15
    MinSpareThreads       1
    MaxSpareThreads       1 
    ThreadsPerChild       1
    MaxRequestsPerChild   0
</IfModule>
 查看进程
$ /usr/local/apache2worker/bin/apachectl restart
$ ps -ef |grep httpd
fancp    15242     1  0 23:19 ?        00:00:00 /usr/local/apache2worker/bin/httpd -k start
fancp    16035 15242  0 23:45 ?        00:00:00 /usr/local/apache2worker/bin/httpd -k start
fancp    16036 15242  0 23:45 ?        00:00:00 /usr/local/apache2worker/bin/httpd -k start
fancp    16041  4762  0 23:45 pts/1    00:00:00 grep httpd


安装MYSQL

# useradd mysql

# tar xf mysql-5.1.55.tar.gz

./configure --prefix=/usr/local/mysql \
--localstatedir=/data/mysql --enable-assembler \
--with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static \
--with-pthread --enable-static --with-big-tables --without-ndb-debug \
--with-charset=utf8 --with-extra-charsets=all \
--without-debug --enable-thread-safe-client --enable-local-infile --with-plugins=max

--localstatedir=/data/mysql //库文件存放目录
--with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static//静态编译安装mysql 客户端和服务端
--with-pthread //采用线程
--with-big-tables //对大表的支持
--with-charset=utf8 //默认字符集为utf8
--with-extra-charsets=all //安装所有字符集
--without-debug //去掉debug 模式
--enable-thread-safe-client //以线程方式编译客户端
--with-plugins=max //添加对innodb 及partition 的支持
--enable-local-infile //对load data 的支持

make && make install

初始化数据库
cd /usr/local/mysql/
mysql]# bin/mysql_install_db --basedir=/usr/local/mysql/ --datadir=/data/mysql/ --user=mysql

相应权限的修改
# chown -R root:mysql /usr/local/mysql/
# chown -R mysql:mysql /data/mysql/

配置文件
cp support-file/my-medium.cnf /etc/my.cnf
cp support-files/mysql/mysql.server /etc/init.d/mysqld
chmod 755 /etc/init.d/mysqld
chkconfig --add mysqld

# vim /root/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
# source /root/.bash_profile

启动数据库并初始化密码。
# service mysqld start Starting MySQL [ OK ]
# mysqladmin -u root password xxxx //设置成自己的密码



安装PHP
# tar xf php-5.2.9.tar.gz
php-5.2.9
 ./configure \
> --prefix=/usr/local/php \
> --with-config-file-path=/usr/local/php/etc \ //php5配置文件
> --with-apxs2=/usr/local/apache2work/bin/apxs \ //apahce2位置
> --with-mysql=/usr/local/mysql/ \ //mysql位置
> --with-libxml-dir=/usr/local/libxml2/ 
> --with-png-dir=/usr/local/libpng/ \
> --with-jpeg-dir=/usr/local/jpeg6/ \
> --with-freetype-dir=/usr/local/freetype/ \
> --with-gd=/usr/local/gd2/ \
> --with-zlib-dir=/usr/local/zlib/ \
> --with-mcrypt=/usr/local/libmcrypt/ \
> --with-mysqli=/usr/local/mysql/bin/mysql_config \ //激活mysqli的功能
> --enable-soap \ //变量激活SOAP和WEB servers
> --enable-mbstring=all \ //多字节穿支持
> --enable-sockets //变量激活socket通信

+--------------------------------------------------------------------+
| License:                                                           |
| This software is subject to the PHP License, available in this     |
| distribution in the file LICENSE.  By continuing this installation |
| process, you are bound by the terms of this license agreement.     |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point.                            |
+--------------------------------------------------------------------+

Thank you for using PHP.

make && make install

报错
/usr/bin/ld: cannot find -lltdl
collect2: ld returned 1 exit status
make: *** [libphp5.la] Error 1

解决方案;安装libtool-ltdl-devel
安装完成后可使用 make test 测试

配置文件
# cp php.ini-dist /usr/local/php/etc/php.ini

与apache整合
在编译时我们使用了--with-apxs2=/usr/local/apache2work/bin/apxs ,将php作为apache功能模块使用
但是还需要修该配置文件,添加支持php解析。使用vi 编译http.conf
在AddTyep application/x-gzip .gz .tgz下添加
AddType application/x-httpd-php .php .phtml

  # If the AddEncoding directives above are commented-out, then you
    # probably should define those extensions to indicate media types:
    #
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddType application/x-httpd-php .php .phtml
找到:
&lt;IfModule dir_module&gt;
DirectoryIndex index.html
&lt;/IfModule&gt;
将该行改为
&lt;IfModule dir_module&gt;
DirectoryIndex index.html index.htm index.php
&lt;/IfModule&gt;
找到:
#Include conf/extra/httpd-mpm.conf
#Include conf/extra/httpd-info.conf
#Include conf/extra/httpd-vhosts.conf
#Include conf/extra/httpd-default.conf
去掉前面的“#”号,取消注释。
注意:以上 4 个扩展配置文件中的设置请按照相关原则进行合理配置!

在htdocs下创建test.php
<?php
phpinfo();
?>
重启apache测试



安装zend 加速器
为了提高php速度,理论上zend加速器可以提高40%-100%的速度。
tar xf ZendOptimizer-3.3.0a-linux-glibc21.i386
./install.sh

会出现图形界面
安装提示:输入Zend安装的位置 /usr/local/zend
询问php.ini的所在位置 /usr/local/php/etc
询问是否安装apache及其启动文件位置 /usr/local/apache2work/bin/apachectl
询问是否重启apache服务

最后在test.php页面上可以看到Zend的信息



安装phpMyAdmin
phpmyadmin是使用php语言开发的一个mysql管理软件,通过web形式管理mysql。

# tar xf phpMyAdmin-3.2.0-all-languages.tar.bz2 
# mv phpMyAdmin-3.2.0-all-languages /usr/local/apache2work/htdocs/phpmyadmin

在使用前。需要配置下创建config.inc.php,可以复制模板config.sample.inc.php
# cp config.sample.inc.php config.inc.php

配置phpmyadmin
通过身份验证模式,可以有2种方案。一种是http和cookie身份验证模式。
这种做法的好处是,登录时在对话框中提示输入密码。mysql数据库密码没有出现在
config.inc.php文件里,而且可以支持多用户管理。
第二种方案是:config验证模式。密码以明文写在配置文件中。不会提示输入密码。

HTTP验证模式
vi config.inc.php

$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'http'; //把cookie换成http
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysqli if your server has it */
$cfg['Servers'][$i]['extension'] = 'mysql'

保存退出后,进去IP/phpmyadmin即可

COOKIE模式
vi config.inc.php

$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie'; //cookie模式
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysqli if your server has it */
$cfg['Servers'][$i]['extension'] = 'mysql'

这样启动phpmyadmin还是需要输入密码用户名

如果需要cookie模式
在配置文件中加入

$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysqli if your server has it */
$cfg['Servers'][$i]['extension'] = 'mysql';

//加入这两行
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'zhang';