PHP5.4(php-fpm)+Nginx1.3.7+MySQL5.5(phpmyadmin-3.5.3)+Redis-2.4.17(Discuz使用)


PHP

下载 :
wget php-5.4.7.tar.gz
安装 :
tar -zxvf php-5.4.7.tar.gz
cd php-5.4.7
./configure   --prefix=/root/web/php/ --enable-fpm --with-config-file-path=/root/web/php/etc
make
make test
make install
配置 :
cp php.ini-production /root/web/php/etc/php.ini
vi /root/web/php/etc/php.ini ( 如下修改 )
;date.timezone   ==> date.timezone = PRC
mv /root/web/php/etc/php-fpm.conf.default /root/web/php/etc/php-fpm.conf
vi /root/web/php/etc/php-fpm.conf (如下修改)
; pid = run/php-fpm.pid    ==>   pid = run/php-fpm.pid
; error_log = log/php-fpm.log     ==>   error_log = log/php-fpm.log
启动 :
/root/web/php/sbin/php-fpm
设置服务自启动 :
cp /root/web/setup/php-5.4.7/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod 755 /etc/init.d/php-fpm
chkconfig --add php-fpm
service php-fpm start
Zend Guard Loader 目前不支持 php5.4

Nginx

下载
wget nginx-1.3.7.tar.gz
安装
tar -zxvf nginx-1.3.7.tar.gz
cd nginx-1.3.7
./configure --prefix=/root/web/nginx/
make
make install
配置 ( 增加 php 支持 ):
vi /root/web/nginx/conf/nginx.conf ( 蓝色部分为 server 段修改部分 )
server {
        listen        10026;
        server_name   localhost;
        location / {
            root    /usr/share/nginx/html;
            index   index.html index.htm index.php;
        }
        error_page    500 502 503 504   /50x.html;
        location = /50x.html {
            root    html;
        }
        location ~ \\.php$ {
            root            /root/web/nginx/html;
            fastcgi_pass    127.0.0.1:9000;
            fastcgi_index   index.php;
            fastcgi_param   SCRIPT_FILENAME     /root/web/nginx/html/$fastcgi_script_name;  #网站根目录路径
            include         fastcgi_params;
        }
}
启动 :
/root/web/nginx/sbin/nginx

MySQL

下载 :
wget mysql-5.5.28.tar.gz
安装 :
yum install cmake (mysql 5.5.x 不再用 configure, 而用 cmake)
tar -zxvf mysql-5.5.28.tar.gz
cd mysql-5.5.28
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/root/web/mysql/data -DSYSCONFDIR=/root/web/mysql/etc -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1 -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DMYSQL_TCP_PORT=13306-DMYSQL_USER=root
make
make install
配置 :
mkdir /root/web/mysql/etc;mkdir /root/web/mysql/var;chown mysql:root /root/web/mysql/var
cp /root/web/mysql/support-files/my-huge.cnf /root/web/mysql/etc/my.cnf // 复制配置文件
cp /root/web/mysql/support-files/mysql.server /etc/init.d/mysqld // 设置开机启动 mysql
chmod 755 /etc/init.d/mysqld;chkconfig mysqld on // 开机启动
useradd mysql // 创建 mysql 用户
/root/web/mysql/scripts/mysql_install_db --user=mysql --basedir=/root/web/mysql --datadir=/root/web/mysql/data // 初始化数据库
vi /root/web/mysql/etc/my.cnf
[client] 处修改 :
socket=/root/web/mysql/var/mysql.sock
[mysqld] 处增加 :
basedir=/root/web/mysql
datadir=/root/web/mysql/data
plugin-dir=/root/web/mysql/lib/plugin
log-error=/root/web/mysql/var/error.log
pid-file=/root/web/mysql/var/mysqld.pid
socket=/root/web/mysql/var/mysql.sock    //( 改行修改 )

检查 mysql 配置文件唯一 :
ls -alh /etc/my.cnf /etc/mysql/my.cnf /root/web/mysql/etc/my.cnf ~/.my.cnf
确保只有 /root/web/mysql/etc/my.cnf 其它删除 .

/root/web/mysql/bin/mysqld_safe & // 启动 mysqld
/root/web/mysql/binmysqladmin   // 检查
/root/web/mysql/binmysqladmin shutdown   // 停止 mysqld
/root/web/mysql/bin/mysqladmin -u root password 'ivgivgivg' // 初始化 mysql 密码
vi /root/web/mysql/bin/mysql_secure_installation   // 修改安全检查配置
找到 make_config() 函数 , 在里面最后增加 echo "socket=/root/web/mysql/var/mysql.sock" >>$config
/root/web/mysql/bin/mysql_secure_installation // 安全设置

登录 :
/root/web/mysql/bin/mysql -uroot -pivgivgivg
mysql> SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;   // 查看用户
mysql> show databases;    // 查看库

phpMyAdmin

下载 :
wget phpMyAdmin-3.5.3-all-languages.tar.gz
安装 :
tar -zxvf phpMyAdmin-3.5.3-all-languages.tar.gz
cp -a phpMyAdmin-3.5.3-all-languages /root/web/nginx/html/phpmyadmin
cd   /root/web/nginx/html/phpmyadmin
mkdir config;cp config.sample.inc.php config/config.inc.php;chmod -R 777 config
配置 :
浏览器访问配置 :
http://192.168.1.210:10026/phpmyadmin/setup
配置好后保存 .
mv /root/web/nginx/html/phpmyadmin/config/config.inc.php ../;chomd 704 /root/web/nginx/html/phpmyadmin/config.inc.php
rm -rf /root/web/nginx/html/phpmyadmin/config/
增加多库支持 :
vi config.inc.php
在最后一行 ?> 上面加入 :
//223 mysql
$i++;
$cfg['Servers'][$i]['host'] = '192.168.1.223';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'ivgivgivg';
$cfg['Servers'][$i]['port'] = '3306';

//224 mysql
$i++;
$cfg['Servers'][$i]['host'] = '192.168.1.224';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'ivgivgivg';
$cfg['Servers'][$i]['port'] = '3306';

访问 :
http://192.168.1.210:10026/phpmyadmin

phpmyadmin 需要的 php 扩展 :
mbstring.so
mcrypt.so
mysqli.so
zip.so
bz2.so
mysql.so
zlib.so
gd.so
php 添加 mysql 扩展方法 (mysql 扩展为例 ):
cd /root/web/setup/php-5.4.7/ext/mysql
/root/web/php/bin/phpize
./configure --with-php-config=/root/web/php/bin/php-config --with-mysqli=/root/web/mysql/bin/mysql_config
make;make install
把安装好的 so 文件都在 /root/web/php/lib/php/extensions/no-debug-non-zts-20100525, 可以移动到上一级目录 /root/web/php/lib/php/extensions/
其它扩展类似安装方法
yum install libmcrypt* gd libjpeg* libpng* freetype freetype-devel   // 部分扩展需要安装库支持
./configure --with-php-config=/root/web/php/bin/php-config --with-mysql=/root/web/mysql/ --with-mysql-sock=/root/web/mysql/var/mysql.sock
./configure --with-php-config=/root/web/php/bin/php-config --with-mysqli=/root/web/mysql/bin/mysql_config
./configure --with-php-config=/root/web/php/bin/php-config --enable-mbstring
./configure --with-php-config=/root/web/php/bin/php-config --enable-zip

PHP 中增加扩展支持 :
vi /root/web/php/etc/php.ini ( 修改如下 )
;  extension_dir    ==> extension_dir = "/root/web/php/lib/php/extensions/"
; Dynamic Extensions ; 下面增加 :
extension=mysql.so
extension=zip.so
extension=zlib.so
extension=bz2.so
extension=mysqli.so
extension=mbstring.so
extension=mcrypt.so
extension=gd.so

检查扩展安装情况 (mysql 为例 ):
/root/web/php/bin/php -c /root/web/php/etc/php.ini -i|grep mysql

重启 php-fpm 生效 :
pkill php-fpm
/root/web/php/sbin/php-fpm

Redis

下载 :
wget  http://redis.googlecode.com/files/redis-2.4.17.tar.gz
安装 :
tar -zxvf redis-2.4.17.tar.gz
cd redis-2.4.17
make
mkdir /root/web/redis;cd /root/web/redis;mkdir bin   etc   log   var;
cd /root/web/setup/redis-2.4.17/src
cp redis-benchmark   redis-cli   redis-server    /root/web/redis/bin
cp ../redis.conf /root/web/redis/etc/
配置 :
vi /root/web/redis/etc/redis.conf ( 需要修改的几个地方 )
daemonize yes     // 后台运行
logfile /root/web/redis/log/redis.log   // 日志保存位置
dir /root/web/redis/var/     // 数据保存目录
maxmemory 1024000000    // 分配最大内存 1G

内存配置 :
echo 1 > /proc/sys/vm/overcommit_memory
内核参数说明如下:
overcommit_memory 文件指定了内核针对内存分配的策略,其值可以是 0 、 1 、 2 。
0 , 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1 , 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2 , 表示内核允许分配超过所有物理内存和交换空间总和的内存
启动 :
/root/web/redis/bin/redis-server /root/web/redis/etc/redis.conf
测试 :
/root/web/redis/bin/redis-cli    // 命令行操作写入数据
redis> set foo bar
OK
redis> get foo
"bar"
/root/web/redis/bin/redis-benchmark   // 性能测试

Redis PHP 扩展安装 :
https://github.com/nicolasff/phpredis/downloads
tar -zxvf nicolasff-phpredis-2.2.2-51-g3a3ee37.tar.gz
cd nicolasff-phpredis-2.2.2-51-g3a3ee37
/root/web/php/bin/phpize
./configure --with-php-config=/root/web/php/bin/php-config
make;make install
安装之后 , 把 extension=redis.so 写入 php.ini 内,查找: output_buffering = Off   修改成: output_buffering = On ,重启php-fpm.
页面测试写入 redis 库 :
vi test.php
<?php
echo " 随机写入 100 次 100 内的数<br/>";
for($i=0;$i<100;++$i)
{
$number=(mt_rand()%100)+1;
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->setex('key', 3600, 'value'); // sets key → value, with 1h TTL.
$redis->set("$number", "$number");
echo $redis->get("$number")."\\n" ;
$redis->delete("$number");
}
?>
curl http://192.168.1.210:10026/redis/test.php
tail -200f /root/web/redis/log/redis.log   // 查看日志

配置 Discuz 支持 Redis

vi /root/web/nginx/html/bbs/config/
$_config['memory']['redis']['server'] = '127.0.0.1';   // 修改这行 , 写入 IP 即可 .

Redis 配置文件说明 : - daemonize: 默认情况下, redis 不是在后台运行的,如果需要在后台运行,把该项的值更改为 yes 。 - pidfile 当 Redis 在后台运行的时候, Redis 默认会把 pid 文件放在 /var/run/redis.pid ,你可以配置到其他地址。当运行多个 redis 服务时,需要指定不同的 pid 文件和端口。 - bind 指定 Redis 只接收来自于该 IP 地址的请求,如果不进行设置,那么将处理所有请求,在生产环境中最好设置该项。 - port 监听端口,默认为 6379 。 - timeout 设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接。 - loglevel log 等级分为 4 级, debug, verbose, notice, 和 warning 。生产环境下一般开启 notice 。 - logfile 配置 log 文件地址,默认使用标准输出,即打印在命令行终端的窗口上。 - databases 设置数据库的个数,可以使用 SELECT 命令来切换数据库。默认使用的数据库是 0 。 - save 设置 Redis 进行数据库镜像的频率。 if( 在 60 秒之内有 10000 个 keys 发生变化时 ){ 进行镜像备份 }else if( 在 300 秒之内有 10 个 keys 发生了变化 ){ 进行镜像备份 }else if( 在 900 秒之内有 1 个 keys 发生了变化 ){ 进行镜像备份 }

  • rdbcompression 在进行镜像备份时,是否进行压缩。
  • dbfilename 镜像备份文件的文件名。
  • dir 数据库镜像备份的文件放置的路径。这里的路径跟文件名要分开配置是因为 Redis 在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,再把该该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中。
  • slaveof 设置该数据库为其他数据库的从数据库。
  • masterauth 当主数据库连接需要密码验证时,在这里指定。
  • requirepass 设置客户端连接后进行任何其他指定前需要使用的密码。警告:因为 redis 速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行 150K 次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解。
  • maxclients 限制同时连接的客户数量。当连接数超过这个值时, redis 将不再接收其他连接请求,客户端尝试连接时将收到 error 信息。
  • maxmemory 设置 redis 能够使用的最大内存。当内存满了的时候,如果还接收到 set 命令, redis 将先尝试剔除设置过 expire 信息的 key ,而不管该 key 的过期时间还没有到达。在删除时,将按照过期时间进行删除,最早将要被过期的 key 将最先被删除。如果带有 expire 信息的 key 都删光了,那么将返回错误。这样, redis 将不再接收写请求,只接收 get 请求。 maxmemory 的设置比较适合于把 redis 当作于类似 memcached 的缓存来使用。
  • appendonly 默认情况下, redis 会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。所以 redis 提供了另外一种更加高效的数据库备份及灾难恢复方式。开启 append only 模式之后, redis 会把所接收到的每一次写操作请求都追加到 appendonly.aof 文件中,当 redis 重新启动时,会从该文件恢复出之前的状态。但是这样会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对 appendonly.aof 进行重新整理。所以我认为推荐生产环境下的做法为关闭镜像,开启 appendonly.aof ,同时可以选择在访问较少的时间每天对 appendonly.aof 进行重写一次。
  • appendfsync 设置对 appendonly.aof 文件进行同步的频率。 always 表示每次有写操作都进行同步, everysec 表示对写操作进行累积,每秒同步一次。这个需要根据实际业务场景进行配置。
  • vm-enabled 是否开启虚拟内存支持。因为 redis 是一个内存数据库,而且当内存满的时候,无法接收新的写请求,所以在 redis 2.0 中,提供了虚拟内存的支持。但是需要注意的是, redis 中,所有的 key 都会放在内存中,在内存不够时,只会把 value 值放入交换区。这样保证了虽然使用虚拟内存,但性能基本不受影响,同时,你需要注意的是你要把 vm-max-memory 设置到足够来放下你的所有的 key 。
  • vm-swap-file 设置虚拟内存的交换文件路径。
  • vm-max-memory 这里设置开启虚拟内存之后, redis 将使用的最大物理内存的大小。默认为 0 , redis 将把他所有的能放到交换文件的都放到交换文件中,以尽量少的使用物理内存。在生产环境下,需要根据实际情况设置该值,最好不要使用默认的 0 。
  • vm-page-size 设置虚拟内存的页大小,如果你的 value 值比较大,比如说你要在 value 中放置博客、新闻之类的所有文章内容,就设大一点,如果要放置的都是很小的内容,那就设小一点。
  • vm-pages 设置交换文件的总的 page 数量,需要注意的是, page table 信息会放在物理内存中,每 8 个 page 就会占据 RAM 中的 1 个 byte 。总的虚拟内存大小 = vm-page-size * vm-pages 。
  • vm-max-threads 设置 VM IO 同时使用的线程数量。因为在进行内存交换时,对数据有编码和解码的过程,所以尽管 IO 设备在硬件上本上不能支持很多的并发读写,但是还是如果你所保存的 vlaue 值比较大,将该值设大一些,还是能够提升性能的。
  • glueoutputbuf 把小的输出缓存放在一起,以便能够在一个 TCP packet 中为客户端发送多个响应,具体原理和真实效果我不是很清楚。所以根据注释,你不是很确定的时候就设置成 yes 。
  • hash-max-zipmap-entries 在 redis 2.0 中引入了 hash 数据结构。当 hash 中包含超过指定元素个数并且最大的元素没有超过临界时, hash 将以一种特殊的编码方式 ( 大大减少内存使用 ) 来存储,这里可以设置这两个临界值。
  • activerehashing 开启之后, redis 将在每 100 毫秒时使用 1 毫秒的 CPU 时间来对 redis 的 hash 表进行重新 hash ,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能够接受 Redis 时不时的对请求有 2 毫秒的延迟的话,把这项配置为 no 。如果没有这么严格的实时性要求,可以设置为 yes ,以便能够尽可能快的释放内存。

nginx.conf(反向代理+http(php-fpm))


user   www  www;
worker_processes  8;
worker_rlimit_nofile 102400;

#error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

#pid        /var/db/nginx/nginx.pid;


events {
    # After increasing this value You probably should increase limit
    # of file descriptors (for example in start_precmd in startup script)
    worker_connections 102400;
    use /dev/poll;
}


http {
    include       /opt/local/etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    #sendfile        on;
    sendfile        off;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  40;
    client_header_buffer_size 4k;
    open_file_cache max=102400 inactive=20s;

    gzip  on;

        upstream riak_cluster {
             server 10.1.6.1:8098 weight=5;
             server 10.1.6.2:8098 weight=2; ## sns_server
             server 10.1.6.3:8098 weight=5;
             server 10.1.6.4:8098 weight=5;
        }   


    server {
        listen       8098;
        server_name  _;
        access_log  /var/log/nginx/riak.access.log  main;

        location /riak/ {
            proxy_set_header Host $host;
            proxy_redirect off;

            client_max_body_size       10m;
            client_body_buffer_size    128k;

            proxy_connect_timeout      90;
            proxy_send_timeout         90;
            proxy_read_timeout         90;

            proxy_buffer_size          64k;  # If the buffers are set to small, nginx will complain about "too large headers"
            proxy_buffers              4 64k;
            proxy_busy_buffers_size    64k;
            proxy_temp_file_write_size 64k;
            proxy_pass http://riak_cluster;
        }
    }


    server {
        listen       20080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  /var/log/nginx/host.access.log  main;

        location / {
                        #proxy_pass http://riak_cluster;
            root   /usr/local/nginx/billing;
            index  index.html index.htm;
        }


        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   share/examples/nginx/html;
        }
        location ~ \\.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/billing/$fastcgi_script_name;
            include        /opt/local/etc/nginx/fastcgi_params;
        }
    }
server {
        listen       8080;
        server_name  localhost;

        access_log  /var/log/nginx/bbs.access.log  main;

        location / {
            root   /usr/local/nginx/bbs;
            index  index.html index.htm index.php;
        }      

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   share/examples/nginx/html;
        }

        location ~ \\.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/bbs/$fastcgi_script_name;
            include        /opt/local/etc/nginx/fastcgi_params;
        }

    }
        upstream riak_admin {
             server 10.1.6.4:8169;
        }   

     #HTTPS server

    server {
        listen       8169;
        server_name  localhost;

        ssl                  on;
        ssl_certificate      cert.pem;
        ssl_certificate_key  key.pem;

        ssl_session_timeout  5m;

        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers   on;

        location /admin {
            if ($request_method != GET) {
              return 405;
            }
            if ($request_method = GET) {
                proxy_pass https://riak_admin;
            }
        }
    }

}