前提说明

企业中,随着用户的增长,数据量也几乎成几何增长,数据越来越大,随之也就出现了各种应用的瓶颈问题。

问题出现了,我们就得想办法解决,一般网站环境,均会使用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.

问题二:各服务器时间同步的问题,遇到各种奇葩的问题都是因为时间同步,一定要记住多主机搭建环境首先确保多机之间的时间要保持一致