A Docker of LAMP & Wordpress扩展1
架构逻辑
一个nginx调度器,提供缓存、反响代理功能,一方面提升响应速度,另一方面提供负载能力,都是为了减轻服务器压力,提升用户体验感。
两个后端服务器,提供httpd功能和php解析功能。两个httpd的默认发布目录都挂在到一个nfs服务器共享目录上。
一个nfs服务器,同时提供一个mysql(应该拆分),保证php调度到mysql上获取数据。
拓扑图
由于服务器不足,后端的nfs和mysql是性能瓶颈,合理状态下,可以使用分布式存储和mysql主从复制+读写分离,甚至文件存储和mysql也应该继续拆分、httpd和php继续拆分
针对上图:一个预想的完整的访问流程:
客户端只知道服务器的ip地址时172.25.254.11,进行访问,请求到达nginx调度器
nginx服务器上使用nginx缓存模块,先去检查是否有缓存,如果有直接返回给客户端
如果没有缓存,则通过nginx的反响代理和负载均衡模块将请求转发给后端RS集群
后端的RS集群同时将自己的httpd发布目录挂载到nfs服务器上,nfs服务器共享的目录里面存放这wordpress所有php文件。当请求被httpd接收,发现是php动态请求,则调用php解释器去解析php脚本,同时,php解释器还需要调用后端mysql获取数据(没有缓存前提下),之后响应给客户端
IP分配
服务器 | IP | 主机名 |
---|---|---|
nginx调度器 | 172.25.254.11 | |
RS1(httpd+php) | 172.25.254.141 | fsx_1 |
RS2(httpd+php) | 172.25.254.142 | fsx_2 |
nfs+mysql | 172.25.254.140 | fsx_master |
nfs+mysql服务器
安装配置nfs
nfs配置成功,为后面RS1、RS2提供httpd默认发布目录,RS1、RS2通过nfs将自己默认发布目录挂载到nfs服务器共享出来的目录(/nfsshare)上,从而保证数据同步。
[root@fsx_master /]# yum install nfs-utils > /dev/null
[root@fsx_master /]# echo "/nfsshare 172.25.254.0/24(rw,no_root_squash)" > /etc/exports
[root@fsx_master /]# exportfs -a
[root@fsx_master /]# exportfs -r
[root@fsx_master /]# systemctl start nfs
[root@fsx_master /]# systemctl enable nfs
安装配置mysql
[root@fsx_master /]# yum install mariadb* -y > /dev/null 2>&1
[root@fsx_master /]# systemctl start mariadb
mysql里面配置:
[root@fsx_master /]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.56-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
MariaDB [(none)]> create database wordpress;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> GRANT ALL ON wordpress.* TO "wordpress"@"172.25.254.%" IDENTIFIED BY "fsx123.456";
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> DELETE FROM mysql.user where User="";
Query OK, 2 rows affected (0.00 sec)
MariaDB [(none)]> UPDATE mysql.user SET Password=PASSWORD("fsx123.456") where User="root";
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4 Changed: 4 Warnings: 0
为了方便fsx_master方便登陆管理mysql服务器,在root加目录下添加.mycnf文件
[root@fsx_master ~]# cat <<eof >.my.cnf
[mysql]
name="root"
host="localhost"
password="fsx123.456"
eof
[root@fsx_master ~]# systemctl restart mariadb
解压wordpress-4.9.4-zh_CN.zip安装包需要unzip命令
[root@fsx_master ~]# yum install unzip
解压数据,修改wordoress内容
[root@fsx_master nfsshare]# pwd
/nfsshare
[root@fsx_master nfsshare]# unzip wordpress-4.9.4-zh_CN.zip >/dev/null
[root@fsx_master nfsshare]# cd wordpress
[root@fsx_master wordpress]# cp wp-config-sample.php wp-config.php
修改wp-config.php中内容:
[root@fsx_master wordpress]# cat wp-config.php | grep -v '^\s*$'
<?php
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress'); //在mysql上创建了一个wordpress的库,用来存放数据
/** MySQL数据库用户名 */
define('DB_USER', 'wordpress'); //在mysql上创建了wordpress用户,用于用户登陆操作自己博客空间
/** MySQL数据库密码 */
define('DB_PASSWORD', 'fsx123.456'); //wordpress用户密码(mysql)
/** MySQL主机 */
define('DB_HOST', '172.25.254.140'); //可以远程端登陆(mysql从httpd服务器上拆分出来,需要远程登陆)
/** 创建数据表时默认的文字编码 */
define('DB_CHARSET', 'utf8');
/** 数据库整理类型。如不确定请勿更改 */
define('DB_COLLATE', '');
/**#@+
* 身份认证密钥与盐。
*
* 修改为任意独一无二的字串!
* 或者直接访问{@link https://api.wordpress.org/secret-key/1.1/salt/
* WordPress.org密钥生成服务}
* 任何修改都会导致所有cookies失效,所有用户将必须重新登录。
*
* @since 2.6.0
*/
define('AUTH_KEY', 'lr%mV&y*-k4x7V#)NiN8bZ/!nrS jG7NH+$+<{D|J&/zePr>d9vv{r|hI7I37idz');
define('SECURE_AUTH_KEY', 'h7ye9^-ULwK$rM#!Iml ,zs<eN&^ es-r-:`pKe{7u;[YBY3W|/MFY*{Xs%w=6b*');
define('LOGGED_IN_KEY', 'cHULjszdJ@Wd?Qv,=/1fs/#L+GQ@P#-G+-?0M1o2sp8r-wn`)#z/[s_7:&CZ)t<p');
define('NONCE_KEY', 'ID;Ji_{HSetSXa|}pK2GR`TG*._5o@-j6Wu(+SjpO>mjF?SOqT4ixsUvB3:W]S3_');
define('AUTH_SALT', ':tVfCz}$n{AX;/@|yBQ;}@~G;+a+v,YU%M>Ne!F85b{*g||qJRJ eSN:E+!bv1b4');
define('SECURE_AUTH_SALT', '*4Y04M+tTed7*RQ!e]0kE]AN:SAN}/D[6Za)~%bn-8oaApB:|||Y*Y&pMaBmA[@&');
define('LOGGED_IN_SALT', 'hTO]^Am`G,LyI5!bK8Mq(W+KcQDy-aQ7~{lb+//AtA#Ys`}U2ccc]_Yk/cQT-D]e');
define('NONCE_SALT', '!u?w,#z5,-2Z)80H#sjOewY4U{?Ay)7-G ;<B!*cw<x9(ay9D:,7QtIM{KZwd,dM');
/**#@-*/
/**
* WordPress数据表前缀。
*
* 如果您有在同一数据库内安装多个WordPress的需求,请为每个WordPress设置
* 不同的数据表前缀。前缀名只能为数字、字母加下划线。
*/
$table_prefix = 'wp_';
/**
* 开发者专用:WordPress调试模式。
*
* 将这个值改为true,WordPress将显示所有用于开发的提示。
* 强烈建议插件开发者在开发环境中启用WP_DEBUG。
*
* 要获取其他能用于调试的信息,请访问Codex。
*
* @link https://codex.wordpress.org/Debugging_in_WordPress
*/
define('WP_DEBUG', false);
/**
* zh_CN本地化设置:启用ICP备案号显示
*
* 可在设置→常规中修改。
* 如需禁用,请移除或注释掉本行。
*/
define('WP_ZH_CN_ICP_NUM', true);
/* 好了!请不要再继续编辑。请保存本文件。使用愉快! */
/** WordPress目录的绝对路径。 */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** 设置WordPress变量和包含文件。 */
require_once(ABSPATH . 'wp-settings.php');
RS1配置
下载安装httpd服务器、php解释器等
[root@fsx_1 ~]# yum install php* httpd -y >/dev/null 2>&1
[root@fsx_1 ~]# cat <<eof >/var/www/html/index.php
> <?php
> phpinfo();
> ?>
> eof
[root@fsx_1 ~]# systemctl restart httpd
测试php是否成功:
浏览器访问http://172.25.254.141/index.php,如果返回php发布页面,则成功
下载nfs(在这里只是做客户端,为了识别nfs文件系统),保证可以挂载nfs
[root@fsx_1 ~]# yum install nfs-utils -y > /dev/null 2>&1
//通过nfs挂载保证两个RS数据一致,nfs目的是让两个RS(httpd服务)的发布目录数据同步
[root@fsx_1 ~]# mount -t nfs 172.25.254.140:/nfsshare /var/www/html/
RS2配置
下载安装httpd服务器、php解释器等
[root@fsx_2 ~]# yum install nfs-utils php* -y > /dev/null
[root@fsx_2 ~]# systemctl restart httpd
[root@fsx_2 ~]# cat <<eof > /var/www/html/index.php
> <?php
> phpinfo();
> ?>
> eof
//这里是为了做测试查看httpd是否可以调用php解释器
[root@fsx_2 ~]# mount -t nfs 172.25.254.140:/nfsshare /var/www/html/
nginx调度器
nginx调度器暴露给客户端,让客户端直接访问,通过nginx的反响代理功能,将请求发送给后端的真正服务器,同时nginx提过了proxy_pass模块,用来做缓存服务器。
安装配置nginx
略
修改nginx主配置文件
[root@localhost nginx]# pwd
/etc/nginx
[root@localhost nginx]# awk NF nginx.conf
user nginx;
worker_processes 1;
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
pid logs/nginx.pid;
worker_rlimit_nofile 10000;
events {
worker_connections 9999;
}
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 65;
gzip on;
upstream php {
server 172.25.254.141:80 weight=3;
server 172.25.254.142:80 weight=2;
}
proxy_cache_path /nginx/cache levels=1:2:1 keys_zone=cache:30m max_size=1g;
server {
listen 80;
server_name localhost;
charset utf-8;
access_log logs/host.access.log main;
location / {
root /nginx;
index index.html index.htm;
rewrite index.html /wordpress;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#location ~ \.php$ {
location /wordpress {
proxy_pass http://php; //实现反响代理,将请求转发给上游服务器
proxy_cache cache; //缓存功能
proxy_cache_valid 200 304 1d; //缓存对象,缓存时长
proxy_cache_valid 301 302 1d;
proxy_buffering on;
}
add_header X-Via $server_addr; //添加两个响应头对象
add_header X-hit $upstream_cache_status;
}
}
启动nginx服务器
[root@localhost nginx]# nginx
//如果之前已经启动了nginx,则修改主配置文件后使用nginx -s reload命令,当然可以自己编写SystemV风格启动脚本
问题集合
到这里,基本上就配置结束了。过程中遇到了一些问题,在此总结:
-
httpd将nfs服务器的分享目录挂载到/var/www/html/下,发现浏览器访问时出现403状态码
403状态码标示虽然请求的资源存在,但是服务器拒绝提供服务,一般原因可能是:httpd主配置文件配置有问题、访问的文件权限设置有问题、selinux开启、nfs服务器共享出来的目录权限问题等 在这里就遇到了selinux未关闭的问题,纠结了好久。。。
-
nginx配置文件中的问题
起始nginx里面还是有问题,location里面做了一次rewrite,比较生硬,就是为了能将过来的请求扔给后端服务器
-
待定
测试
进行了多次压力测试,看看结果
测试1
无nginx缓存的情况
[root@localhost nginx]# ab -n 10000 -c 1000 http://172.25.254.11/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 172.25.254.11 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/fsx-1.1.0
Server Hostname: 172.25.254.11
Server Port: 80
Document Path: /index.html
Document Length: 229 bytes
Concurrency Level: 1000
Time taken for tests: 4.149 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Non-2xx responses: 10000
Total transferred: 4880000 bytes
HTML transferred: 2290000 bytes
Requests per second: 2410.21 [#/sec] (mean)
Time per request: 414.901 [ms] (mean)
Time per request: 0.415 [ms] (mean, across all concurrent requests)
Transfer rate: 1148.62 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 9.1 0 37
Processing: 0 280 662.8 52 3289
Waiting: 0 279 662.9 52 3289
Total: 0 283 666.5 52 3320
Percentage of the requests served within a certain time (ms)
50% 52
66% 58
75% 113
80% 253
90% 1004
95% 1311
98% 3076
99% 3294
100% 3320 (longest request)
测试2
[root@localhost nginx]# ab -n 10000 -c 1000 http://172.25.254.11/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 172.25.254.11 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/fsx-1.1.0
Server Hostname: 172.25.254.11
Server Port: 80
Document Path: /index.html
Document Length: 229 bytes
Concurrency Level: 1000
Time taken for tests: 0.853 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Non-2xx responses: 10000
Total transferred: 4870001 bytes
HTML transferred: 2290000 bytes
Requests per second: 11717.51 [#/sec] (mean)
Time per request: 85.342 [ms] (mean)
Time per request: 0.085 [ms] (mean, across all concurrent requests)
Transfer rate: 5572.68 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 7.6 0 34
Processing: 7 12 8.9 9 211
Waiting: 7 12 8.8 9 211
Total: 8 15 15.0 9 216
Percentage of the requests served within a certain time (ms)
50% 9
66% 10
75% 10
80% 11
90% 51
95% 54
98% 62
99% 66
100% 216 (longest request)
测试3
[root@localhost nginx]# ab -n 100000 -c 100 http://172.25.254.11/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 172.25.254.11 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/fsx-1.1.0
Server Hostname: 172.25.254.11
Server Port: 80
Document Path: /index.html
Document Length: 229 bytes
Concurrency Level: 100
Time taken for tests: 10.217 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Non-2xx responses: 100000
Total transferred: 48700000 bytes
HTML transferred: 22900000 bytes
Requests per second: 9787.38 [#/sec] (mean)
Time per request: 10.217 [ms] (mean)
Time per request: 0.102 [ms] (mean, across all concurrent requests)
Transfer rate: 4654.74 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 4
Processing: 1 10 1.4 10 15
Waiting: 0 10 1.4 10 15
Total: 5 10 1.4 10 15
Percentage of the requests served within a certain time (ms)
50% 10
66% 11
75% 11
80% 11
90% 11
95% 12
98% 14
99% 15
100% 15 (longest request)
测试4
[root@localhost nginx]# ab -n 100000 -c 300 http://172.25.254.11/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 172.25.254.11 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/fsx-1.1.0
Server Hostname: 172.25.254.11
Server Port: 80
Document Path: /index.html
Document Length: 229 bytes
Concurrency Level: 300
Time taken for tests: 13.577 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Non-2xx responses: 100000
Total transferred: 48700000 bytes
HTML transferred: 22900000 bytes
Requests per second: 7365.27 [#/sec] (mean)
Time per request: 40.732 [ms] (mean)
Time per request: 0.136 [ms] (mean, across all concurrent requests)
Transfer rate: 3502.82 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 17 217.7 0 7019
Processing: 6 19 65.3 16 6430
Waiting: 0 18 65.3 16 6430
Total: 8 36 237.4 17 7433
Percentage of the requests served within a certain time (ms)
50% 17
66% 19
75% 20
80% 21
90% 24
95% 27
98% 31
99% 39
100% 7433 (longest request)
总结图:
请求/并发 | RPS | TPR | TFR | |
---|---|---|---|---|
测试1 | 10000/1000 | 2410.21 | 414.901 | 1148.62 |
测试2 | 10000/1000 | 11717.51 | 85.342 | 5572.68 |
测试3 | 10万/100 | 9787.38 | 10.217 | 4654.74 |
测试4 | 10万/300 | 7365.27 | 40.732 | 3502.28 |
其中:RPS标示每秒的请求数、TPR标示用户平均请求等待时间,TFR标示响应速度
测试1统计的是没有开启nginx缓存功能的数据,测试2-4都开启了缓存,可以看出来:每秒响应的请求数增加了将近5倍(测试1和测试2比较)。
测试3和4,请求数量相同,并发不同,可以看出,在一万个请求到达时,并发达到300服务性能已经出现下滑(主要原因还是因为笔记本作为服务器(i5三代处理器,两颗cpu,4g内存),这样的处理动态请求的并发能力已经很好了)
ab -n 1000 -c 100 http://www.baidu.com
其中-n表示请求数,-c表示并发数
用户平均请求等待时间(Time per request)
计算公式:处理完成所有请求数所花费的时间/ (总请求数 / 并发用户数),即
Time per request = Time taken for tests /( Complete requests / Concurrency Level)
服务器平均请求等待时间(Time per request: across all concurrent requests)
计算公式:处理完成所有请求数所花费的时间 / 总请求数,即
Time taken for / testsComplete requests
可以看到,它也=用户平均请求等待时间/并发用户数,即
Time per request / Concurrency Level
同时,它也是吞吐率的倒数。
根据计算公式,可知 用户平均请求等待时间 = 服务器平均请求等待时间 * 并发数
这里你的并发是-c100,所以27.3=0.273100*100
总结
在上次优化过程中,只做了nginx缓存,这次增加了nginx负载,让两个RS处理请求,效率提高了不少,但是后端的共享存储很不好,应该采取更加优化的分布式存储服务,mysql也应该被独立出来等。这都是之后优化需要考虑的点,当然,还有后端mysql的主从复制+读写分离+redis也可以缓解mysql瓶颈问题。包括nginx主配置文件参数优化并不完善、httpd服务器准配置文件也不完善、nginx和httpd的内核虽然添加了重用和快速回收time_wait参数,但是内核参数还是需要进一步研究。
当然,很重要的一点,所有的服务节点目前都是单节点,特别是调度器,合理状态下,应该有高可用保证(双机热备)