呵呵,终于在今天早上把论坛迁移完毕并且论坛批量用户导入。除去周末大概搞了3、4天。。



需求:公司论坛、官网是在apache上边的,其实之前的很复杂的逻辑,并且apache实现了诸多的转发功能,为了安全起见,打算把论坛及官网2个网站换一台机器。由于之前是apache,考虑了现在的状况打算启用nginx。这里面的某些原因就不具体说明了,这个文章不一定是好的文档,但是个人觉得经过很有意思。PS:感谢师兄;感谢师兄;感谢师兄;哈哈。



No.1:nginx; No.2:mysql; No.3:php;No.4:discuz;No.5:phpize-xcache;No.6:批量导入


So...

第一步肯定是搭建环境。

这里点区别。这个机器上不安装数据库,数据库在rds上边(这点差点被坑死),所以按照一般的流程:LEMP肯定是先nginx、mysql、php、xcache等等等

No.1

但是数据库不在这里该如何编译,编译安装php的时候需要特别注意。

基础一些东西的安装 开发组包"Development Tools"和 "Development Libraries"

and : yum -y install pcre-devel

nginx编译安装的选项:

./configure \
  --prefix=/usr \
  --sbin-path=/usr/sbin/nginx \
  --conf-path=/etc/nginx/nginx.conf \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx/nginx.pid  \
  --lock-path=/var/lock/nginx.lock \
  --user=root \ #当然你可以nginx去跑。担心nginx没权限的话setfacl 查下这个命令吧!
  --group=root \
  --with-http_ssl_module \
  --with-http_flv_module \
  --with-http_stub_status_module \
  --with-http_gzip_static_module \
  --http-client-body-temp-path=/var/tmp/nginx/client/ \
  --http-proxy-temp-path=/var/tmp/nginx/proxy/ \
  --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
  --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
  --http-scgi-temp-path=/var/tmp/nginx/scgi \
  --with-pcre

make && make install略过


然后给nginx提供sysV init脚本:

此脚本来自马哥教育-马哥

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
# Source function library.
. /etc/rc.d/init.d/functions
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
# Source networking configuration.
. /etc/sysconfig/network
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
nginx="/usr/sbin/nginx"
prog=$(basename $nginx)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
lockfile=/var/lock/subsys/nginx
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
make_dirs() {
   # make required directories
   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
force_reload() {
    restart
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
rh_status() {
    status $prog
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
rh_status_q() {
    rh_status >/dev/null 2>&1
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac


+执行权限and+开机自动启动(chkconfig nginx on )

然后就可以欢快的进行nginx的测试了。。


其实到这里都是很简单的事情,难办的下边就来了


No.2

mysql相关:这里我一共测试了2中方法

No.2.1 本地没有mysql的方法:

 直接略过,php编译的时候加上这3个选项


--with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd

这种方法造成的原因在php那边说明吧?


No.2.2本地装一个mysql:

原因:你放着他,不让他运行就行了~~(当时也是为了测试)

mysql编译的过程(我记得我写过相关的博客,地址贴上吧。)

http://407711169.blog.51cto.com/6616996/1186795


No.3


PHP部分:这点是重点。。前边都属于开胃菜。


No.3.1

  结合No2.1没有mysql的方法:

版本略过

编译选项:

./configure --prefix=/usr/local/php --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib-dir --with-libxml-dir=/usr --enable-xml  --with-mhash --with-mcrypt  --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --with-curl
说明:如果前面第1步解决依赖关系时安装mcrypt相关的两个rpm包,此./configure命令还可以带上--with-mcrypt选项以让php支持mycrpt扩展。--with-snmp选项则用于实现php的SNMP扩展,但此功能要求提前安装net-snmp相关软件包。


and make &&make install(过程报啥错你就装啥。)


为php提供配置文件:

# cp php.ini-production /etc/php.ini


为php-fpm提供Sysv init脚本,并将其添加至服务列表:

# cp sapi/fpm/init.d.php-fpm  /etc/rc.d/init.d/php-fpm

# chmod +x /etc/rc.d/init.d/php-fpm

# chkconfig --add php-fpm

# chkconfig php-fpm on


为php-fpm提供配置文件:

# cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf


编辑php-fpm的配置文件:

# vim /usr/local/php/etc/php-fpm.conf

配置fpm的相关选项为你所需要的值,并启用pid文件(如下最后一行):

pm.max_children = 150

pm.start_servers = 8

pm.min_spare_servers = 5

pm.max_spare_servers = 10

pid = /usr/local/php/var/run/php-fpm.pid


接下来就可以启动php-fpm了:

# service php-fpm start


使用如下命令来验正(如果此命令输出有中几个php-fpm进程就说明启动成功了):

# ps aux | grep php-fpm


整合nginx和php5


1、编辑/etc/nginx/nginx.conf,启用如下选项:

location ~ \.php$ {

           root           html;

           fastcgi_pass   127.0.0.1:9000;

           fastcgi_index  index.php;

           fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

           include        fastcgi_params;

       }


2、编辑/etc/nginx/fastcgi_params,将其内容更改为如下内容:

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;

fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  QUERY_STRING       $query_string;

fastcgi_param  REQUEST_METHOD     $request_method;

fastcgi_param  CONTENT_TYPE       $content_type;

fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;

fastcgi_param  REQUEST_URI        $request_uri;

fastcgi_param  DOCUMENT_URI       $document_uri;

fastcgi_param  DOCUMENT_ROOT      $document_root;

fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  REMOTE_ADDR        $remote_addr;

fastcgi_param  REMOTE_PORT        $remote_port;

fastcgi_param  SERVER_ADDR        $server_addr;

fastcgi_param  SERVER_PORT        $server_port;

fastcgi_param  SERVER_NAME        $server_name;


并在所支持的主页面格式中添加php格式的主页,类似如下:

location / {

           root   html;

           index  index.php index.html index.htm;

       }


而后重新载入nginx的配置文件:

# service nginx reload


3、在/usr/html新建index.php的测试页面,测试php是否能正常工作:

# cat > /usr/html/index.php << EOF

<?php

phpinfo();

?>

当然这个时候,这个页面是出来的!(这个时候phpinfo界面里面的支持mysql的几个选项都是Ok的!enable!!)


No.3.2

 PHP结合mysql编译的方式

./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-openssl --enable-fpm --enable-sockets --enable-sysvshm  --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib-dir --with-libxml-dir=/usr --enable-xml  --with-mhash --with-mcrypt  --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --with-curl


然后按照3.1的方式去继续往下走,走到最后也是ok的

可能上边php-fpm启动的时候会报错(dbase.so和ncurses.so提示加载不上)

Starting php-fpm [09-Dec-2013 17:27:27] NOTICE: PHP message: PHP Warning:  PHP Startup: dbase: Unable to initialize module

具体我也没看懂。但是你把他在/etc/php.d/下他的目录下把他注释就ok了。。


关于X Cache 以及phpize来安装PHP扩展的后边会说到。





No.4

首先扫下盲。DISCUZ迁移以后需要修改的几个地方(网友的智慧是无穷的。)


大概如下:

1、打开config文件下的config_global.php文件,查找下面几个修改为新空间的数据库用户名、数据库密码、数据库名。

    $_config['db']['1']['dbuser'] = '数据库用户名';

   $_config['db']['1']['dbpw'] = '数据库密码';

   $_config['db']['1']['dbname'] = '数据库名';


2、打开config文件下的config_ucenter.php,查找下面几个修改为新空间的数据库用户名、数据库密码、数据库名。

    define('UC_DBUSER', '数据库用户名');

   define('UC_DBPW', '数据库密码');

   define('UC_DBNAME', '数据库名');

   define('UC_DBTABLEPRE', '`数据库名`.pre_ucenter_');


3、打开uc_server\data下的config.inc.php,查找下面几个修改为新空间的数据库用户名、数据库密码、数据库名。

    define('UC_DBUSER', '数据库用户名');

   define('UC_DBPW', '数据库密码');

   define('UC_DBNAME', '数据库名');


然后config_ucenter.php 中我也修改成了新的域名newbbs。


但是当我把数据导入rds的时候,却报错了。。


Discuz! Database Error


(2806) notconnect

PHP Debug


No.        File        Line        Code

1        forum.php        49        discuz_application->init()

2        source/class/discuz/discuz_application.php        65        discuz_application->_init_db()

3        source/class/discuz/discuz_application.php        370        discuz_database::init(%s, Array)

4        source/class/discuz/discuz_database.php        23        db_driver_mysql->connect()

5        source/class/db/db_driver_mysql.php        74        db_driver_mysql->_dbconnect(%s, %s, %s, %s, %s, %s)

6        source/class/db/db_driver_mysql.php        87        db_driver_mysql->halt(%s, %d)

7        source/class/db/db_driver_mysql.php        218        break()



从上边看,像是由于php-mysql链接这点出了问题。但是出问题也很正常啊。。(没装mysql)

于是yum yum yum 查啊装啊 查啊 装啊。

其实这点算是最后才查的,因为当时观察phpinfo里面的内容,mysql是ok的。当时初步理解成了在nginx规则中调用fastcgi的时候调用失败!然后看了端口是开的,然后测试测试不通过。最后yumyumyum,还是不行后,直接 php 编译的卸了。。然后全部yum了一次(mysql与php)只要是他们的都装上了。。最后2B的(才想到)又去做了个测试(php)里面只写了数据库的连接方式,然后判断了下。最后打开是ok的(shit,但是这是yum装的。。)(php-mysql的脚本可以网上搜一下很多的)。这个过程我和我一个师兄搞了一个下午= =谢谢他的帮助。


当天晚上回去,不死心啊。。全删了。重新编译。。

这次为了测试一下我备份过来的数据的有效性(万一我倒过来的就是错的= =),我选择了No.3.2的方式,本地装了个mysql。然后编译方式上边= =。


然后官方下载了X2.5的discuz。然后一切流畅!

然后倒入了备份的数据库。一切流畅!

然后将discuz 的数据库指向了rds,重新安装一次!然后装完了,竟然打 不  开 了!!


擦。查了下报错日志如下,。

2013/**/** 21:36:14 [error] 6921#0: *21138 upstream timed out (110: Connection timed out) while connecting to upstream, client: 183.39.194.179, server: www.***.com, request: "GET /ajax/userinit?1306503433302 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.***.com", referrer: "网址”

然后搜了下,说是nginx的fastcgi调用内核时间。而内核有漏洞的问题!(rds..不是淘宝的吗。咋还漏洞)但是按照方法改了不管用。。,(为了别的可能是这个问题的 我把问题贴来了:from:http://zhengdl126.iteye.com/blog

大概解决方法:

从日志的表示来看应该不是nginx的问题,而是 fast-cgi 执行超时没有及时返回数据到ngnix的问题. 可web和数据库负载都不高,不应该是

程序超时的问题. 查资料也没有找到原因,网上于几个人说遇到同样问题,也没有好的解决方案. 后来仔细分析日志,发现出现错误的日志的时间都是大于当前时间 ,这点很奇怪,难道是系统时间的问题? 后来再仔细查资料,才找到原因. 原来是 centos 的一个内核bug, 调用gettimeofday()这个函数的时候会比当前时间快4398秒 .  具体原因是因为多核cpu,各核的TSC不一样造成的.  看来 fast-cgi 应该是调用了这个函数的.

解决方案是升级内核..  相信很多和我一样不是专业sa的兄弟对升级内核之类的事情还是比较犯怵的,不过不用担心有一个不用升级内核的解决方案. 在不升级kernel的情况下,可以考虑修改time source,来解决。修改kernel option。


vi /boot/grub/grub.conf 增加如下红色的参数, 重启后问题解决

kernel **** ro root=*****  rhgb quiet clock=pit


然后还是不行。挠头、、然后问题报给老大。他也很困惑。然后差点打算打消使用rds数据库调用本地数据库。然后有了个转机。原来问题果真还是出来rds上。。

http://blog.csdn.net/jasonzhangxian/article/details/11639669

在/source/class/db下面的db_driver_mysql.php文件 81-85行为如下代码

if($pconnect) {
    $link = @mysql_pconnect($dbhost, $dbuser, $dbpw, MYSQL_CLIENT_COMPRESS);
} else {
    $link = @mysql_connect($dbhost, $dbuser, $dbpw, 1, MYSQL_CLIENT_COMPRESS);
}


mysql_connect()函数使用了第四个和第五个参数


直接删掉这两个参数之后,访问网址,不会出现一直加载的情况了


但是样式和JS都没有加载到


再次源码调试


/source/class/discuz中discuz_application.php文件中,第66行加载$this->_init_setting()之后


很多默认的参数都没有加载成功


这个方法调用的是/source/class/table中的table_common_setting.php文件中的fetch_all方法


于是查看数据表common_setting,里面的配置比正确安装之后的少了很多


联想到前面mysql的问题,应该是在执行安装时,这些配置数据没有写入数据库


所以在执行安装之前,就去掉mysql_connect的那两个参数


去掉后。重新安装。问题解决了!




No.5


X-cache和phpize的使用。


No.5.1

安装xcache,为php加速:


1、安装

# tar xf xcache-2.0.0.tar.gz

# cd xcache-2.0.0

# /usr/local/php/bin/phpize

# ./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config

# make && make install


安装结束时,会出现类似如下行:

Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-zts-20100525/


2、编辑php.ini,整合php和xcache:


首先将xcache提供的样例配置导入php.ini

# mkdir /etc/php.d

# cp xcache.ini /etc/php.d


说明:xcache.ini文件在xcache的源码目录中。


接下来编辑/etc/php.d/xcache.ini,找到zend_extension开头的行,修改为如下行:

zend_extension = /usr/local/php/lib/php/extensions/no-debug-zts-20100525/xcache.so


注意:如果php.ini文件中有多条zend_extension指令行,要确保此新增的行排在第一位。


3、重新启动php-fpm

# service php-fpm restart


No.5.2

phpize

论坛装好后,需要导入用户。但是数据库里面很多张表对应的。然后单独测试的时候,发现竟然没有验证码(gd...)(这点也是我装成fpm的原因,装啥方面嘛。)


于是跑到编译安装的ext目录下去找gd。进去phpize报错(报错信息没了,但是记得是少了2个东西,yum找下装上去)。

在gd目录下面运行phpize命令。然后搞定后目录下回出现configure文件

然后就仿照编译的时候

./configure --with-php-config=/***/***/***/***/php-config (必要的时候上--enabl=/***)

make && make install


然后在你的/etc/php.d/下回出现一个以此命名的文件.这样大概就ok了的





No.6

discuz论坛用户批量导入


大概找了下。discuz的加密方式是这样的:md5(md5($password).$salt),$salt是一个6位随机数。


http://www.cnblogs.com/mooncher/archive/2011/04/21/2023091.html


这里有相关的函数,然后写一个轮询,然后将用户成批读入并导入:

REPLACE INTO pre_ucenter_members (username,password,salt) VALUES ('***','5d170a63975ebdb5a9ec3165e4d23b75','478860');

这个时候用户还是没有激活的。我这里有个激活的脚本:


<?php
$dbserver ='***';
$dbuser ='**';
$dbpwd ='***';
$dbname ='***';
$charset ='utf8';
$uc_pre ='pre_ucenter_';
$dx_pre ='pre_';
set_time_limit(0);
$connect=mysql_connect($dbserver,$dbuser,$dbpwd) or die("无法连接数据库");
@mysql_select_db($dbname,$connect);
mysql_query("set names $charset");
$query = mysql_query("SELECT * FROM `{$uc_pre}members`  WHERE  `uid` not in(select `uid` from `{$dx_pre}common_member`) ",$connect);
while($user = mysql_fetch_array($query)) {
#$password=$user[password]; 
#mysql_query(" replace INTO  `{$dx_pre}common_member` (uid,username,password,adminid,groupid,regdate,email) VALUES ('$user[uid]', '$user[username]', '$password','0','10','$user[regdate]','$user[email]') ");
mysql_query(" replace INTO  `{$dx_pre}common_member` (uid,username,password,adminid,groupid,regdate,email) VALUES ('$user[uid]', '$user[username]', '$user[password]','0','10','$user[regdate]','$user[email]') ");
mysql_query(" replace INTO  `{$dx_pre}common_member_field_forum` (uid) VALUES ('$user[uid]')");
mysql_query(" replace INTO  `{$dx_pre}common_member_field_home` (uid) VALUES ('$user[uid]')");
mysql_query(" replace INTO  `{$dx_pre}common_member_count` (uid) VALUES ('$user[uid]')");
mysql_query(" replace INTO  `{$dx_pre}common_member_profile` (uid) VALUES ('$user[uid]')");
mysql_query(" replace INTO  `{$dx_pre}common_member_status` (uid) VALUES ('$user[uid]')");
}
echo "已从UC批量导入激活成功";
?>


适用于 X2.5-X3.1 别的没测试过。。



可能这里PHPIZE的解释很少。搜一下吧,很多= =

END。。