折腾了几天的0构建LEMP-discuz论坛迁移+用户导入(php问题等各种问题)

需求:公司论坛、官网是在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编译安装的选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
. /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脚本:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/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个选项


1
--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的方法:

版本略过

编译选项:

1
2
. /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编译的方式

1
. /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行为如下代码

1
2
3
4
5
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');

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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。。


你可能感兴趣的:(PHP,discuz,LNMP,phpize)