前提说明
企业中,随着用户的增长,数据量也几乎成几何增长,数据越来越大,随之也就出现了各种应用的瓶颈问题。
问题出现了,我们就得想办法解决,一般网站环境,均会使用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.confLogFormat "%{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.htmlThis is static1 Server
[root@static /]# cat /web/static2/index.htmlThis 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.
问题二:各服务器时间同步的问题,遇到各种奇葩的问题都是因为时间同步,一定要记住多主机搭建环境首先确保多机之间的时间要保持一致