文章目录
文章目录
LNMP+Redis实验
实验环境要求
- nginx1台,php各两台,MySQL各两台,Redis各两台
- nginx与php做分离多实例
- MySQL做双主配置
- Redis做主从配置
实际实验是只用3台虚机:
nginx单独一台虚机21.8,MySQL-M、Redis-M、PHP共用一台虚机21.9,MySQL-S、Redis-S、PHP共用一台虚机21.10
实验步骤
安装过程
nginx安装过程
[root@nginx tar]# tar -zxf nginx-1.22.1.tar.gz
[root@nginx tar]# cd nginx-1.22.1
[root@nginx nginx-1.22.1]# useradd -s /sbin/nologin www -M
[root@nginx nginx-1.22.1]# yum install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel -y
[root@nginx nginx-1.22.1]# ./configure --prefix=/usr/local/nginx --user=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx nginx-1.22.1]# make -f objs/Makefile
[root@nginx nginx-1.22.1]# make -j4 install -f objs/Makefile
[root@nginx nginx-1.22.1]# /usr/local/nginx/sbin/nginx
MySQL安装过程
MySQL主库
[root@mysql ~]# rpm -qa | grep mysql
[root@mysql ~]# rpm -qa | grep mariadb
[root@mysql ~]# find / -name mysql
[root@mysql ~]# tar -Jxf mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz
[root@mysql ~]# \mv mysql-8.0.31-linux-glibc2.12-x86_64 /usr/local/mysql
[root@mysql ~]# cd /usr/local/mysql
[root@mysql mysql]# groupadd mysql
[root@mysql mysql]# useradd -r -g mysql -s /bin/false mysql
[root@mysql mysql]# tail -2 /etc/profile
export MYSQL_HOME=/usr/local/mysql
export PATH=$MYSQL_HOME/bin:$PATH
[root@mysql mysql]# source /etc/profile
[root@mysql mysql]# grep -v "#" /etc/my.cnf | grep -v "^$"
[mysqld]
server-id = 1
log-bin = mysql-bin
auto-increment-increment=2
auto-increment-offset=1
log-slave-updates=true
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
log-error=/usr/local/mysql/data/error.log
pid-file=/usr/local/mysql/data/mysqld.pid
[root@mysql mysql]# chown -R mysql:mysql /usr/local/mysql/*
[root@mysql mysql]# cd bin
[root@mysql bin]# mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysql bin]# cd ../support-files
[root@mysql support-file]# cp mysql.server /etc/init.d/mysql.server
[root@mysql support-file]# service mysql.server start
[root@mysql support-file]# ps -ef | grep mysql
root 1579 1 0 13:47 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/usr/local/mysql/data --pid-file=/usr/local/mysql/data/localhost.localdomain.pid
mysql 1779 1579 0 13:47 pts/0 00:00:51 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/data/error.log --pid-file=/usr/local/mysql/data/localhost.localdomain.pid --socket=/tmp/mysql.sock
root 17404 1481 0 16:14 pts/0 00:00:00 grep --color=auto mysql
MySQL从库
[root@mysql ~]# rpm -qa | grep mysql
[root@mysql ~]# rpm -qa | grep mariadb
[root@mysql ~]# find / -name mysql
[root@mysql ~]# tar -Jxf mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz
[root@mysql ~]# \mv mysql-8.0.31-linux-glibc2.12-x86_64 /usr/local/mysql
[root@mysql ~]# cd /usr/local/mysql
[root@mysql mysql]# groupadd mysql
[root@mysql mysql]# useradd -r -g mysql -s /bin/false mysql
[root@mysql mysql]# tail -2 /etc/profile
export MYSQL_HOME=/usr/local/mysql
export PATH=$MYSQL_HOME/bin:$PATH
[root@mysql mysql]# source /etc/profile
[root@mysql mysql]# grep -v "#" /etc/my.cnf | grep -v "^$"
[mysqld]
server-id = 2
log-bin = mysql-bin
auto-increment-increment=2
auto-increment-offset=2
log-slave-updates=true
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
log-error=/usr/local/mysql/data/error.log
pid-file=/usr/local/mysql/data/mysqld.pid
[root@mysql mysql]# chown -R mysql:mysql /usr/local/mysql/*
[root@mysql mysql]# cd bin
[root@mysql bin]# mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysql bin]# cd ../support-files
[root@mysql support-file]# cp mysql.server /etc/init.d/mysql.server
[root@mysql support-file]# service mysql.server start
[root@mysql support-file]# ps -ef | grep mysql
root 2427 1 0 13:46 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/usr/local/mysql/data --pid-file=/usr/local/mysql/data/mysqld.pid
mysql 2639 2427 0 13:46 pts/0 00:00:43 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/data/error.log --pid-file=/usr/local/mysql/data/mysqld.pid --socket=/tmp/mysql.sock
root 24515 1549 0 16:15 pts/0 00:00:00 grep --color=auto mysql
Redis安装过程
- Redis主从库看配置一样,只有主库需要修改绑定地址,允许从库访问主库
- 因为与mysql共用一台虚机所以主机名显示MySQL
[root@mysql ~]# wget http://download.redis.io/releases/redis-6.2.4.tar.gz
[root@mysql ~]# yum install gcc gcc-c++ epel-release jemalloc jemalloc-devel -y
[root@mysql ~]# tar -zxf redis-6.2.4.tar.gz
[root@mysql ~]# cd redis-6.2.4
[root@mysql redis-6.2.4]# make PREFIX=/usr/local/redis install
[root@mysql redis-6.2.4]# cp redis.conf /usr/local/redis/
#在输入redis-cli未找到命令时,可在redis的bin目录下拷贝执行文件到/usr/local/bin目录下
#或者做个软连接 ln -s /usr/local/redis/bin/redis-* /usr/bin/
[root@mysql redis-6.2.4]# cp /usr/local/redis/bin/redis-cli /usr/local/bin
#在从库上指定主库的地址和端口,还有日志的保存路径
[root@mysql redis-6.2.4]# cat /usr/local/redis/redis.conf | grep -E "replicaof" | grep -v "#"
replicaof 192.168.21.9 6379
[root@mysql redis-6.2.4]# cat /usr/local/redis/redis.conf | grep "logfile"
logfile "/var/log/redis.log"
#在Redis主库上修改监听端口
[root@mysql redis-6.2.4]# cat /usr/local/redis/redis.conf | grep -E "0.0.0.0" | grep "bind"
bind 0.0.0.0
[root@mysql redis-6.2.4]# nohup /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf &
[root@mysql redis-6.2.4]# redis-cli
127.0.0.1:6379> keys *
1) "web2"
2) "web1"
[root@mysql redis-6.2.4]# redis-cli
127.0.0.1:6379> keys *
1) "web2"
2) "web1"
PHP安装过程
[root@mysql ~]# yum remove php* -y
#添加php7.x源
[root@mysql ~]# rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
#添加web组件源
[root@mysql ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
#安装php72w软件
[root@mysql ~]# yum install php72w php72w-cli php72w-common php72w-devel php72w-embedded php72w-fpm php72w-gd php72w-mbstring php72w-mysqlnd php72w-opcache php72w-pdo php72w-xml -y
#在有redis的环境下需要装php-redis,但php-redis需要安装epel扩展源后才能安装,当前实验在redis阶段已安装epel
[root@mysql ~]# yum install php-redis -y
#新版本安装完成后启动php-fpm和重新加载nginx
[root@mysql ~]# systemctl start php-fpm
[root@nginx ~]# /usr/local/nginx/sbin/nginx -s reload
discuz论坛部署过程
以下部署两台php都是一样配置
#mysql创建用户、数据库及授权,两台MySQL都是一样的配置
mysql> create user 'discuz'@'%' identified with identified with mysql_native_password by 'Admin@123';
mysql> create database ultrax;
mysql> grant all on ultrax.* to 'discuz'@'%';
mysql> flush privileges;
#为了统一发布目录路径及名称,在php上创建发布目录
[root@mysql ~]# mkdir -p /usr/local/nginx/html
[root@mysql ~]# unzip Discuz_X3.4_SC_UTF8_20220811.zip
[root@mysql ~]# \mv discuz/* /usr/local/nginx/html
[root@mysql ~]# cd /usr/local/nginx/html
[root@mysql html]# chown -R apache:apache data/*
[root@mysql ~]# tail -1 /etc/hosts
192.168.21.10 192.168.21.9 mysql.net
#nginx虚拟主机及配置文件配置
#nginx虚拟主机做了动静分离
[root@nginx ~]# cd /usr/local/nginx/conf/domains
[root@nginx domains]# cat v1_discuz
server {
listen 80;
server_name v1_discuz.com;
#location / {
# root /usr/local/nginx/html/;
index index.php index.html index.htm;
#}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php$ {
root /usr/local/nginx/html;
fastcgi_pass web;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
root /usr/local/nginx/html/;
expires 30d;
}
}
#在nginx配置文件中做了负载均衡,模式改为ip_hash
[root@nginx domains]# cd ../
[root@nginx conf]# cat nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
upstream web {
ip_hash;
server 192.168.21.9:9000 weight=100 max_fails=2 fail_timeout=15;
server 192.168.21.10:9000 weight=100 max_fails=2 fail_timeout=15;
}
include domains/*;
}
[root@nginx conf]# /usr/local/nginx/sbin/nginx -s reload
#在discuz配置文件中填写redis主库的地址,两台redis的discuz配置文件都要填
[root@mysql config]# pwd
/usr/local/nginx/html/config
[root@mysql config]# cat config_global.php | grep 192.168
$_config['memory']['redis']['server'] = '192.168.21.9';
#在两台MySQL中查看ultrax数据库表的数量是否一致
[root@mysql config]# mysql -uroot -pAdmin@123 -e "use ultrax;" -e "show tables;"
#查看redis是否有产生新的key,主从redis都有相同的key存在
[root@mysql redis]# redis-cli
127.0.0.1:6379> keys *
1) "0Fx3xG_magic"
2) "0Fx3xG_pluginlanguage_system"
3) "0Fx3xG_cronnextrun"
4) "0Fx3xG_historyposts"
5) "0Fx3xG_common_member_count_3"
6) "0Fx3xG_fields_register"
7) "0Fx3xG_stamptypeid"
8) "0Fx3xG_common_member_count_2"
9) "0Fx3xG_setting"
10) "0Fx3xG_creditrule"
11) "0Fx3xG_userstats"
12) "0Fx3xG_home_follow_2"
13) "0Fx3xG_common_member_2"
14) "0Fx3xG_fields_optional"
15) "0Fx3xG_onlinelist"
16) "0Fx3xG_usergroups"
17) "0Fx3xG_common_member_field_home_2"
18) "0Fx3xG_forum_index_page_10"
19) "0Fx3xG_common_member_3"
20) "0Fx3xG_usergroup_10"
21) "0Fx3xG_usergroup_7"
22) "0Fx3xG_heats"
23) "0Fx3xG_common_member_field_home_3"
24) "0Fx3xG_onlinerecord"
25) "0Fx3xG_modreasons"
26) "0Fx3xG_diytemplatename"
27) "0Fx3xG_common_member_status_3"
28) "web1"
29) "0Fx3xG_cronpublish"
30) "0Fx3xG_seccodedata"
31) "0Fx3xG_ipctrl"
32) "0Fx3xG_common_member_newprompt_3"
33) "0Fx3xG_diytemplatenameforum"
34) "0Fx3xG_common_member_status_2"
35) "web2"
36) "0Fx3xG_diytemplatenamehome"
37) "0Fx3xG_fields_required"
38) "0Fx3xG_forumlinks"
39) "0Fx3xG_style_default"
40) "0Fx3xG_plugin"
41) "0Fx3xG_announcements"
127.0.0.1:6379>
实验总结
- 在类似这种各个中间件和数据库分离的场景下搭建网站,需要先从后端开始配置,保证后端配置无误后再配前端;否则前端配置好,后端没有配置完成没有数据,是呈现不出网站页面
实验结果
验证Redis和MySQL切换效果
验证过程
- 停掉Redis主库,在MySQL上把ultrax数据库里的pre_common_member表中的sunlit账号信息删除
- 再进入discuz登录sunlit账号时,会出现激活页面;在这情况下不要激活
- 启动Redis主库,再重新登录sunlit账号,会变回正常登录,没有激活页面弹出
#把redis主库停掉
[root@mysql ~]# ps -ef | grep redis
root 1976 1491 0 10:33 pts/0 00:00:05 /usr/local/redis/bin/redis-server 0.0.0.0:6379
root 2778 1491 0 11:42 pts/0 00:00:00 grep --color=auto redis
[root@mysql ~]# kill 1976
[root@mysql ~]# echo $?
0
[1]+ 完成 nohup /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
#在21.9的MySQL中的ultrax的库中找到pre_common_member这份表;该表用于存储账号信息
[root@mysql ~]# mysql -uroot -pAdmin@123 -e "use ultrax;" -e "show tables;" | grep "pre_common_member" | awk 'NR==1'
mysql: [Warning] Using a password on the command line interface can be insecure.
pre_common_member
[root@mysql ~]# mysql -pAdmin@123
#进入ultrax数据库
mysql> use ultrax;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
#查看表格式
mysql> desc pre_common_member;
+--------------------+--------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------------+------+-----+---------+----------------+
| uid | mediumint unsigned | NO | PRI | NULL | auto_increment |
| email | char(40) | NO | MUL | | |
| username | char(15) | NO | UNI | | |
| password | char(32) | NO | | | |
| status | tinyint(1) | NO | | 0 | |
| emailstatus | tinyint(1) | NO | | 0 | |
| avatarstatus | tinyint(1) | NO | | 0 | |
| videophotostatus | tinyint(1) | NO | | 0 | |
| adminid | tinyint(1) | NO | | 0 | |
| groupid | smallint unsigned | NO | MUL | 0 | |
| groupexpiry | int unsigned | NO | | 0 | |
| extgroupids | char(20) | NO | | | |
| regdate | int unsigned | NO | MUL | 0 | |
| credits | int | NO | | 0 | |
| notifysound | tinyint(1) | NO | | 0 | |
| timeoffset | char(4) | NO | | | |
| newpm | smallint unsigned | NO | | 0 | |
| newprompt | smallint unsigned | NO | | 0 | |
| accessmasks | tinyint(1) | NO | | 0 | |
| allowadmincp | tinyint(1) | NO | | 0 | |
| onlyacceptfriendpm | tinyint(1) | NO | | 0 | |
| conisbind | tinyint unsigned | NO | MUL | 0 | |
| freeze | tinyint(1) | NO | | 0 | |
+--------------------+--------------------+------+-----+---------+----------------+
23 rows in set (0.00 sec)
#根据表格是查找对应表的内容信息
mysql> select uid,username,email,password,status from pre_common_member;
+-----+----------+-----------------+----------------------------------+--------+
| uid | username | email | password | status |
+-----+----------+-----------------+----------------------------------+--------+
| 2 | admin | admin@admin.com | 316fac3b8e06930e288c22d8e5543f76 | 0 |
| 3 | sunlit | sunlit@qq.com | 55dcf0077ad50f41697116327c03bf4e | 0 |
+-----+----------+-----------------+----------------------------------+--------+
2 rows in set (0.00 sec)
#指定删除对应表中的sunlit账号信息
mysql> delete from pre_common_member where username='sunlit';
Query OK, 1 row affected (0.00 sec)
mysql> select uid,username,email,password,status from pre_common_member;
+-----+----------+-----------------+----------------------------------+--------+
| uid | username | email | password | status |
+-----+----------+-----------------+----------------------------------+--------+
| 2 | admin | admin@admin.com | 316fac3b8e06930e288c22d8e5543f76 | 0 |
+-----+----------+-----------------+----------------------------------+--------+
1 row in set (0.00 sec)
mysql>
#在redis从库中查看存有账号信息的key
127.0.0.1:6379> keys *
1) "0Fx3xG_diytemplatename"
2) "0Fx3xG_common_member_field_home_2"
3) "0Fx3xG_heats"
4) "0Fx3xG_style_default"
5) "0Fx3xG_pluginlanguage_system"
6) "0Fx3xG_fields_optional"
7) "0Fx3xG_plugin"
8) "0Fx3xG_common_member_status_3"
9) "0Fx3xG_diytemplatenameforum"
10) "0Fx3xG_common_member_3"
11) "0Fx3xG_ipbanned"
12) "0Fx3xG_seccodedata"
13) "web1"
14) "0Fx3xG_creditrule"
15) "0Fx3xG_common_member_field_home_3"
16) "0Fx3xG_magic"
17) "0Fx3xG_common_member_status_2"
18) "0Fx3xG_diytemplatenamehome"
19) "0Fx3xG_common_member_count_3"
20) "web2"
21) "0Fx3xG_userstats"
22) "0Fx3xG_cronnextrun"
23) "0Fx3xG_common_member_count_2"
24) "0Fx3xG_usergroup_7"
25) "0Fx3xG_forumlinks"
26) "0Fx3xG_onlinerecord"
27) "0Fx3xG_common_member_2"
28) "0Fx3xG_usergroup_10"
29) "0Fx3xG_home_follow_3"
30) "0Fx3xG_setting"
31) "0Fx3xG_cronpublish"
32) "0Fx3xG_onlinelist"
33) "0Fx3xG_usergroups"
34) "0Fx3xG_announcements"
35) "0Fx3xG_historyposts"
36) "0Fx3xG_stamptypeid"
37) "0Fx3xG_fields_register"
38) "0Fx3xG_ipctrl"
39) "0Fx3xG_modreasons"
40) "0Fx3xG_fields_required"
127.0.0.1:6379> get 0Fx3xG_common_member_3
"a:23:{s:3:\"uid\";s:1:\"3\";s:5:\"email\";s:13:\"sunlit@qq.com\";s:8:\"username\";s:6:\"sunlit\";s:8:\"password\";s:32:\"55dcf0077ad50f41697116327c03bf4e\";s:6:\"status\";s:1:\"0\";s:11:\"emailstatus\";s:1:\"0\";s:12:\"avatarstatus\";s:1:\"0\";s:16:\"videophotostatus\";s:1:\"0\";s:7:\"adminid\";s:1:\"0\";s:7:\"groupid\";s:2:\"10\";s:11:\"groupexpiry\";s:1:\"0\";s:11:\"extgroupids\";s:0:\"\";s:7:\"regdate\";s:10:\"1673709963\";s:7:\"credits\";d:4;s:11:\"notifysound\";s:1:\"0\";s:10:\"timeoffset\";s:4:\"9999\";s:5:\"newpm\";s:1:\"0\";s:9:\"newprompt\";i:1;s:11:\"accessmasks\";s:1:\"0\";s:12:\"allowadmincp\";s:1:\"0\";s:18:\"onlyacceptfriendpm\";s:1:\"0\";s:9:\"conisbind\";s:1:\"0\";s:6:\"freeze\";s:1:\"0\";}"
127.0.0.1:6379>
验证结果
实验期间遇到的报错
discuz论坛页面显示不完整
-
discuz论坛搭建完成后页面显示不完整,出现该种情况是因为nginx与php分开部署,静态文件都存放在php设备上,需要在php设备上把发布目录拷贝一份到nginx的发布目录中
-
如在nginx与php分离且在负载均衡的情况下,因为负载均衡默认是轮询模式,访问时会在两台php之间轮流跳,那么这样会在两台php上各写一部分,导致静态文件不完整;在此环境下需要先把负载均衡中的21.10的php注释掉,让静态文件全部写在21.9 php上。
upstream web { #ip_hash; server 192.168.21.9:9000 weight=100 max_fails=2 fail_timeout=15; #server 192.168.21.10:9000 weight=100 max_fails=2 fail_timeout=15; }
-
然后在php发布目录上把配置后生成的文件删除;以discuz论坛为例:discuz会在发布目录下的data文件中生成一个install.lock文件,删除后再次访问就会进入discuz安装界面,反之如果没有生成这个文件则直接在浏览器上地址栏后面加上/install/即可重新安装论坛
-
重装后把php上的完整discuz论坛文件拷贝到nginx和另一台在负载均衡上被注释的php
- 当把discuz的数据拷贝到21.10 php设备后,出现以下报错
- 是因为拷贝后发布目录下的data目录中的文件没有访问权限,需要重新加权限
7.重新加权限后,可正常访问discuz论坛;最后再把负载均衡打开,经验证负载均衡下可正常访问