前提说明
企业中,随着用户的增长,数据量也几乎成几何增长,数据越来越大,随之也就出现了各种应用的瓶颈问题。
问题出现了,我们就得想办法解决,一般网站环境,均会使用LAMP或者LNMP,而我们对于网站环境的优化,除了对源代码进行优化、SQL慢查询优化 、SQL创建索引等之外,我们还可以对环境架构进行优化与扩展。
因此,我们引入了 Nginx 对站点实现负载均衡和动静分离,来加快访问速度。
引入负载均衡技术后这里就有这么一个问题,如果我们登录了百度的一个账号,如网页的百度网盘,但是每次有可能请求的是不同的服务器,我们知道每个服务器都会有自己的会话session,所以会导致用户每次刷新网页又要重新登录,这是非常糟糕的体验,因此,根据以上问题,希望session可以共享,这样就可以解决负载均衡中同一个域名不同服务器对应不同session的问题;使用redis使php将session保存到redis中, 这样只要保证多台业务服务器能访问同一个redis服务器(群集)就行了
不说那么多了,接下来就跟我来配置吧
首先是架构环境介绍
本实验中:前端使用两台服务器配置nginx+keepalived实现高可用负载均衡和动静分离;后端php动态服务器使用lap服务搭建,负责解析php动态资源;由于虚拟机开不了太多,静态服务器就使用nginx的基于端口的虚拟主机来实现;mysql和redis放在一台服务器上来实现,现实要使用redis哨兵或集群,mysql使用mha主从复制和读写分离架构来实现
1、代理服务器:
服务:nginx,配置upstream模块实现负载均衡,配置location使用代理实现动静资源分离
2、动态服务器:
服务:httpd+PHP,负载处理客户端请求的php动态页面解析
3、静态服务器
服务:nginx,负载处理客户端请求的图片、js、css、html等静态资源
配置过程:
动态服务器配置
一、配置前的初始配置,配置好每台主机的ip地址,关闭防火墙和selinux,配置hosts解析文件(各主机间通信);这个步骤所有主机都操作,我这里只操作一台主机
[root@proxy-master /]# systemctl stop firewalld
[root@proxy-master /]# systemctl disable firewalld
[root@proxy-master /]# setenforce 0
[root@proxy-master /]# vim /etc/hosts
192.168.2.221 www.aa1.com
192.168.2.222 www.aa2.com
192.168.2.223 www.aa3.com
192.168.2.224 www.aa4.com
192.168.2.225 www.aa5.com
192.168.2.226 www.aa6.com
二、配置httpd+php服务器,实现动态请求的解析(两台lap主机都操作一样,我这里只操作一台)
①安装httpd和php需要的软件包
[root@lap-A /]# yum install -y httpd php php-mbstring php-mysql php-gd php-devel
②配置httpd支持php解析添加index.php首页支持,在配置文件中添加调用php5模块的配置、
[root@lap-A /]# vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxylog ##代理的请求日志格式
CustomLog "logs/access_log" proxylog ##调用代理的日志格式(显示真实客户端ip地址,默认日志只显示代理服务器ip)
DirectoryIndex index.php index.html
...略
AddType application/x-httpd .php ##此配置没有,需要新添加
LoadModule php5_module modules/libphp5.so ##此配置没有,需要新添加
...略
③创建info.php信息页面,将httpd服务加入到开机自启并启动httpd服务
[root@lap-A /]# vim /var/www/html/info.php
[root@centos02 /]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@lap-A /]# systemctl start httpd
④使用客户端添加hosts解析,浏览器访问http://www.aa3.com/info.php验证httpd与php协同工作是否正常
⑤另一台动态服务器使用同样的步骤安装httpd+php服务,并测试是否工作正常
静态服务器配置
正使用一台服务器安装nginx,基于不同端口的虚拟主机来实现模拟多台静态服务器
①使用yum安装nginx服务程序,新建两个虚拟主机,配置静态资源网站根目录,配置访问日志格式使用proxy格式(显示真实的客户端ip地址)
[root@static /]# yum install -y nginx ##通过yum安装nginx服务程序
[root@static /]# vim /etc/nginx/conf.d/static1.conf ##创建第一个虚拟主机
-----------------------------------------------------------------------------
server {
listen 8080;
server_name www.aa5.com;
root /web/static1/;
access_log /var/log/nginx/8080_access.log proxy; ##调用自定义日志格式proxy,用来显示真实客户端的ip地址
location / {
root /web/static1/;
index index.html;
}
}
[root@static /]# vim /etc/nginx/conf.d/static2.conf ##创建第二个虚拟主机
--------------------------------------------------------------------
server {
listen 8090;
server_name www.aa5.com;
root /web/static2/;
access_log /var/log/nginx/8090_access.log proxy;
location / {
root /web/static2/;
index index.html;
}
}
②修改nginx主配置文件,在http字段中添加一个自定义proxy日志配置(名称要和前面调用的格式名称一致)
[root@static /]# vim /etc/nginx/nginx.conf
-----------------------------------------------------------
http {
...略
log_format proxy '$http_x_forwarded_for - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
...略
}
③创建虚拟主机网站根目录,更改目录的属主与属组并生成测试首页
[root@static /]# mkdir -p /web/static{1,2} ##创建两个虚拟主机根目录
[root@static /]# chown -R nginx:nginx /web/static{1,2} ##更改两个虚拟主机目录属主属组为nginx
[root@static /]# for i in `seq 2`;do echo "This is static$i Server
" > /web/static$i/index.html;done ##生成两个测试主页文件
[root@static /]# cat /web/static1/index.html
This is static1 Server
[root@static /]# cat /web/static2/index.html
This is static2 Server
④检查nginx配置文件语法是否正确,将nginx服务加入到开机自启动并启动服务,使用客户端访问不同端口验证静态服务器是否访问正常
[root@static /]# nginx -t ##测试nginx配置文件语法是否正确
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@static /]# systemctl enable nginx ##将nginx服务加入到开机自启动
[root@static /]# systemctl start nginx ##启动nginx服务
[root@static /]# ss -ntl | egrep "8080|8090" ##查看8080和8090端口是否监听
nginx代理服务器配置
Nginx-master配置:
①安装nginx服务软件,安装keepalived软件包
[root@Nginx-master /]# yum install -y nginx keepalived
②修改nginx主配置文件,设置负载均衡upstream的动态服务器组和静态服务器组
[root@Nginx-master /]# vim /etc/nginx/nginx.conf
------------------------------------------------------------------
http{
....省略
upstream static {
server www.aa5.com:8080;
server www.aa5.com:8090;
}
upstream dong {
server www.aa3.com;
server www.aa4.com;
}
....省略
}
③新建反代虚拟主机文件,添加反代负载均衡和动静分离参数
[root@Nginx-master /]# vim /etc/nginx/conf.d/proxy.conf
---------------------------------------------------------------------------
server {
listen 80;
server_name www.aa1.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~* \.(png|jpg|jpeg|html|htm|js|css|xml)$ {
proxy_pass http://static;
}
location / {
proxy_pass http://dong;
}
}
④测试nginx配置文件语法是否正确,将nginx服务加入到开机自启并启动nginx服务
[root@Nginx-master /]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@Nginx-master /]# systemctl enable nginx
[root@Nginx-master /]# systemctl start nginx
[root@Nginx-master /]# netstat -anpt | grep nginx
⑤配置keepalived实现代理服务器的高可用性,防止单点故障发生
[root@Nginx-master /]# cd /etc/keepalived/
[root@Nginx-master /]# cd /etc/keepalived/
[root@Nginx-master keepalived]# vim keepalived.conf
---------------------------------------------------------
global_defs { ##全局配置项
router_id LVS_DEVEL1 ##设备名称表示
}
vrrp_instance VI_1 { ##热备实例名称
state MASTER ##此热备实例的状态(MASTER|BACKUP)
interface eth0 ##VIP要绑定的网卡名称
virtual_router_id 50 ##设置VRID,这里非常重要,相同的VRID为一个组,他将决定多播的MAC地址
priority 100 ##设置本节点的优先级,优先级高的成为master获得vip
advert_int 1 ##节点健康检查间隔时间
authentication { ##设置认证
auth_type PASS ##设置认证的方式(PASS|AH)
auth_pass putianhui ##认证的密码
}
virtual_ipaddress {
192.168.2.254 dev eth0 label eth0:1 ##设置vip地址,并添加一个网卡别名
}
}
⑥将keepalived服务加入到开机自启并启动服务,通过ifconfig命令查看vip是否配置成功
[root@Nginx-master /]# systemctl enable keepalived
[root@Nginx-master /]# systemctl start keepalived
⑦修改客户端的hosts文件,添加www.aa1.com域名对应代理服务器的vip地址
⑧在lap动态服务器创建分别创建php测试页面,客户端分别访问代理服务器index.html和index.php验证动静分离效果
[root@lap-A /]# vim /var/www/html/index.php
[root@lap-B /]# vim /var/www/html/index.php
客户端访问代理服务器index.php验证效果(index.php文件在静态服务器上面没有)
客户端访问代理服务器index.html静态页面效果(index.html只有8080虚拟主机和8090虚拟主机上面有)
通过验证可以看到以.php结尾的动态请求被轮循调度到2.223和2.224这两台动态服务器,客户端访问请求以.html结尾的被轮循调度到静态服务器的8080和8090不同虚拟主机上;负载均衡和动静分离配置完成
Nginx-backup配置:
由于backup服务器和master配置基本相同,只是个别配置项的参数不同,这里就只列出各配置文件的详细配置信息
nginx主配置文件添加内容
[root@Nginx-backup /]# vim /etc/nginx/nginx.conf
------------------------------------------------------------------
http{
....省略
upstream static {
server www.aa5.com:8080;
server www.aa5.com:8090;
}
upstream dong {
server www.aa3.com;
server www.aa4.com;
}
....省略
}
nginx虚拟主机配置文件添加内容
[root@Nginx-backup /]# vim /etc/nginx/conf.d/proxy.conf
--------------------------------------------------------------------
server {
listen 80;
server_name www.aa1.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~* \.(png|jpg|jpeg|html|htm|js|css|xml)$ {
proxy_pass http://static;
}
location / {
proxy_pass http://dong;
}
}
[root@Nginx-backup /]# systemctl enable nginx
[root@Nginx-backup /]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@Nginx-backup /]# systemctl start nginx
keepalived配置文件内容
[root@Nginx-backup /]# vim /etc/keepalived/keepalived.conf
-----------------------------------------------------------------
global_defs {
router_id LVS_DEVEL2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass putianhui
}
virtual_ipaddress {
192.168.2.254 dev eth0 label eth0:1
}
}
数据库服务器配置:
①使用yum安装mariadb服务,将其加入到开机自启然并启动服务
[root@database /]# yum install -y mariadb mariadb-server
[root@database /]# systemctl enable mariadb
[root@database /]# systemctl start mariadb
②创建ceshi数据库,并新建用户授予ceshi数据库所有权限
[root@database /]# mysql
MariaDB [(none)]> create database ceshi;
MariaDB [(none)]> grant all on ceshi.* to 'ceshi'@'%' identified by 'putianhui';
MariaDB [(none)]> flush privileges;
安装redis服务配置session会话
①下载redis安装包到本地目录,解压并编译安装(注意需要安装gcc编译器),执行初始化安装
[root@database /]# wget
[root@database /]# tar xzvf redis-5.0.5.tar.gz
[root@database /]# cd redis-5.0.5/
[root@database redis-5.0.5]# make && make install
[root@database redis-5.0.5]# ./utils/install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379] ##输入要监听的端口(默认是6379)
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] ##指定配置文件路径
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] ##指定日志存放路径
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] ##指定数据持久化存放目录
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] ##指定服务可执行文件存放路径
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
②修改redis主配置文件,将监听的地址改为0.0.0.0所有
[root@database /]# vim /etc/redis/6379.conf
-----------------------------------------------------
bind 0.0.0.0
③启动redis服务,查看端口监听
[root@database /]# /etc/init.d/redis_6379 start
[root@database /]# netstat -anpt | grep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 11718/redis-server
安装php-redis扩展插件(在httpd+php动态服务器上面安装)
配置php动态服务器修改session缓存设置(默认session存在在php本地磁盘文件中)
①下载php-redis扩展插件包到httpd+php动态服务器本地目录
[root@lap-A /]# wget https://pecl.php.net/get/redis-4.3.0.tgz
②安装php-redis,首先解压软件包,切换到解压后目录,使用phpize(由php软件包提供,如果没有请安装php)工具生成configure文件,编译并编译安装(安装完成模块在
/usr/lib64/php/modules目录下),(配置报错请安装gcc和php-devel)
[root@lap-A /]# tar xzvf redis-4.3.0.tgz
[root@lap-A /]# cd redis-4.3.0/
[root@lap-A redis-4.3.0]# phpize
Configuring for:
PHP Api Version: 20100412
Zend Module Api No: 20100525
Zend Extension Api No: 220100525
[root@lap-A redis-4.3.0]# ./configure --with-php-config=/usr/bin/php-config
[root@lap-A redis-4.3.0]# make && make install
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
Installing shared extensions: /usr/lib64/php/modules/
③修改httpd和php的配置信息,使其支持redis模块,并指定session到redis服务的地址
[root@lap-A /]# vim /etc/php.ini
--------------------------------添加和修改以下内容--------------------------------
extension_dir="/usr/lib64/php/modules/" ##默认没有在适当位置添加
extension=redis.so ##默认没有在适当位置添加
session.save_handler = redis ##默认有,查找修改为redis
session.save_path = "tcp://192.168.2.226:6379" ##默认有,查找修改为redis服务器地址和端口号
[root@lap-A /]# vim /etc/httpd/conf.d/php.conf
-----------------------------在最后两行修改为以下内容-------------------------------
php_value session.save_handler "redis"
php_value session.save_path "tcp://192.168.2.226:6379"
④重启httpd服务,单独访问主机的info.php页面查看redis模块是否加载成功,session会话保存地址是否配置成功
[root@lap-A /]# systemctl restart httpd
⑤上传phpMyAdmin源码包到动态服务器根目录,解压后将网站源码复制到httpd网站根目录,修改网站源码开启自定义数据库服务器登录
[root@lap-A /]# unzip phpMyAdmin-4.0.4-all-languages.zip
[root@lap-A /]# cp -rf phpMyAdmin-4.0.4-all-languages/* /var/www/html/
[root@lap-A /]# vim /var/www/html/libraries/config.default.php
---------------------------------------------------------------
$cfg['AllowArbitraryServer'] = false; ##修改前
$cfg['AllowArbitraryServer'] = true; ##修改后
⑥单独访问动态网站域名(不通过代理访问),测试phpMyadmin的session写入redis是否正常
[root@database /]# redis-cli -h 192.168.2.226
192.168.2.226:6379> KEYS *
1) "PHPREDIS_SESSION:h03uj561td63t40vicb1e07e12esaoab"
2) "a"
192.168.2.226:6379>
⑦在另外一台动态服务器先不安装redis插件(默认将session保存到服务器本地),然后上传phpMyadmin源码包到网站根目录,访问代理服务器域名登录测试
[root@lap-B /]# unzip phpMyAdmin-4.0.4-all-languages.zip
[root@lap-B /]# cp -rf phpMyAdmin-4.0.4-all-languages/* /var/www/html/
[root@lap-B /]# vim /var/www/html/libraries/config.default.php
---------------------------------------------------------------
$cfg['AllowArbitraryServer'] = false; ##修改前
$cfg['AllowArbitraryServer'] = true; ##修改后
访问代理服务器后发现图片无法加载(因为做了动静分离,将phpMYadmin源码包上传一份到静态服务器的8080和8090网站根目录各一份即可)
[root@static /]# unzip phpMyAdmin-4.0.4-all-languages.zip
[root@static /]# cp -rf phpMyAdmin-4.0.4-all-languages/* /web/static1/
[root@static /]# cp -rf phpMyAdmin-4.0.4-all-languages/* /web/static2/
再次访问或刷新页面即可显示图片等静态资源
访问代理服务器登录测试会话信息(发现一点登录就跳转到新的空白页面;是因为第一次处理请求的session没有保存到redis服务器,点击执行后调度器将请求调度到一台新的动态服务器进行处理,此服务器没有找到对应的session信息,所有就要重新登录)
⑦另一台动态服务器也是安装php-redis扩展插件,然后配置php和httpd加载redis模块,然后配置redis服务器地址(我这里就不重复写了,自行配置);
最终的结果验证:
验证代理高可用性:关闭nginx-master的keepalived服务和nginx服务,客户端重新访问www.aa1.com可正常访问(此时是nginx-backup提供服务)
验证动静分离:将静态服务器上的网站源码删除,客户端重新访问www.aa1.com可正常访问(图片、js、css等静态资源无法加载)
验证负载均衡:关闭其中一个动态服务器,客户端重新访问网站(可正常访问),将被关闭httpd启动,然后关闭另外一台客户端重新访问(可正常访问)
验证session共享:将两台动态服务器都启动服务,客户端访问网站并登陆成功测试;无限操作,不会提示session过期或无限登陆
遇到的一些坑以及解决办法
问题一:原因是没有安装php-devel软件包,使用yum安装一下就可以了
[root@Nginx-backup redis-4.3.0]# phpize
Can't find PHP headers in /usr/include/php
The php-devel package is required for use of this command.
问题二:各服务器时间同步的问题,遇到各种奇葩的问题都是因为时间同步,一定要记住多主机搭建环境首先确保多机之间的时间要保持一致