第十二篇:Nginx反向代理、负载均衡、phpMyAdmin会话共享/会话共享
反向代理⭐⭐⭐⭐⭐
反向代理服务器的配置命令 | 说明 |
proxy_pass http://10.0.0.7:80; | 将客户端的请求转发到指定的服务器 |
proxy_set_header Host $http_host; |
修改发往后端服务器的HTTP头部 $http_host的值为原始客户端请求中的Host头地址 |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | 将客户端真实的ip地址传递给服务端,只记录客户端ip地址 |
proxy_set_header X-Real-IP $remote_addr; | 将客户端真实的ip地址传递给服务端,记录客户端ip地址和所有代理服务器的IP地址 |
代理分类
代理分类 | 本质 | 应用场景 |
正向代理 | 代替客户端发送请求 | 公司内容部署的服务器软件访问外网、FQ |
反向代理 | 代替服务端接收请求 | 负载均衡、隐藏后端服务器增强安全、缓存优化 |
反向代理的使用
环境准备
角色 | 主机名 | ip |
代理 | lb01 | 10.0.0.5/172.16.1.5 |
web | web01 | 10.0.0.7/172.16.1.7 |
域名:proxy.Linux.cn | ||
站点目录:/app/code/proxy/ | ||
首页文件:index.html |
# 配置nginx的yum源安装nginx [root@web01 ~]# scp -r /etc/yum.repos.d/nginx.repo root@172.16.1.5:/etc/yum.repos.d/ yum install -y nginx systemctl enable nginx systemctl start nginx # 站点目录文件 [root@web01 /etc/nginx/conf.d]# mkdir -p /app/code/proxy [root@web01 /etc/nginx/conf.d]# echo proxy.linux.cn web01 >/app/code/proxy/index.html # nginx默认启动后为web服务器 需要使用对应的模块: proxy模块(代理) upstream模块(负载均衡模块)
虚拟主机
- web01服务器
[root@web01 /etc/nginx/conf.d]# cat proxy.linux.cn.conf server{ listen 80; server_name proxy.linux.cn; error_log /var/log/nginx/proxy-error.log notice; access_log /var/log/nginx/proxy-access.log main; location / { index index.html; } }
- lb01代理服务器
[root@lb01 /etc/nginx/conf.d]# cat proxy.linux.cn.conf server{ listen 80; server_name proxy.linux.cn; error_log /var/log/nginx/proxy-error.log notice; access_log /var/log/nginx/proxy-access.log main; location / { # 将客户端的请求转发到指定的服务器 proxy_pass http://10.0.0.7:80; # 修改发往后端服务器的HTTP头部,$http_host的值为原始客户端请求中的Host头地址 proxy_set_header Host $http_host; } }
测试
# 注意配置host文件时:一个域名只能对应一个IP地址 # 由于请求最先到达的时代理服务器,所以hosts文件配置: 10.0.0.5 proxy.linux.cn # 命令行测试 [C:\~]$ curl -H Host:proxy.linux.cn http://10.0.0.5 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 21 100 21 0 0 10714 0 --:--:-- --:--:-- --:--:-- 21000 proxy.linux.cn web01
proxy_pass指令:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
代理案例01:web有多个虚拟主机故障案例⭐⭐⭐⭐⭐
- 故障现象:web服务器有多个虚拟主机时,通过代理服务器访问获取的不是想要的虚拟主机
- 原因:代理服务器向后端web节点发送请求时,请求头中的Host被修改为ip地址的形式
- 解决:
- 思路:修改代理服务器访问web节点的请求头中的Host部分
- proxy_set_header Host $http_host;
- 修改发往后端服务器的HTTP头部
- $http_host的值为原始客户端请求中的Host头地址
代理案例02:web记录用户真实ip地址⭐⭐⭐⭐⭐
- 现象:web服务器没有记录客户端真实的ip地址,只记录了代理服务器的ip地址
- 解决:
- 思路:修改代理服务器访问web节点的请求头中的Host部分
- proxy_set_header X-Real-IP $remote_addr;
- 将客户端的IP地址设置为X-Real-IP请求头
- 请求头只包含客户端的ip地址,不会记录中间经过的代理服务器
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 将客户端的IP地址设置为X-Forwarded-For请求头
- 请求头中包含客户端的ip地址和其上游所有代理服务器ip地址
- 最后在web服务器上面记录真实的ip地址(在访问日志中设置):$http_x_porwarded_for
server{ listen 80; server_name proxy.linux.cn; error_log /var/log/nginx/proxy-error.log notice; access_log /var/log/nginx/proxy-access.log main; location / { proxy_pass http://10.0.0.7:80; proxy_set_header Host $http_host; # 将客户端真实的ip地址传递给服务端 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
负载均衡⭐⭐⭐⭐⭐
负载均衡vs反向代理
共同点 | 区别 | 服务 | |
负载均衡 | 用户的请求分发到后端节点上 |
用户-->lb-->web 负载均衡做的是数据的转发,不会产生新的请求 |
lvs |
反向代理 | 用户的请求分发到后端节点上 | 代理代替用户去找web服务器,会产生新的请求 | nginx、tengine、openresty、haproxy |
负载均衡模块的选项
# upstream模块中server支持的选项 upstrem pools { server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=10s; server 10.0.0.8:80 weight=1 max_fails=3 fail_timeout=10s; server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=10s; server 10.0.0.8:80 weight=1 max_fails=3 fail_timeout=10s; server 10.0.0.9:80 backup; server 10.0.0.9:80 backup; server 10.0.0.9:80 badkup; }
upstream | 说明 | 应用场景 |
weight(权重) | nginx根据权重分配请求 | 根据后端服务器的处理能力不同,调整权重实现负载均衡 |
max_fails | nginx的健康检查功能,指定fail_timeout时间段内允许的最大失败请求次数 | 适用于需要监控后端服务器健康状况的场景 |
fail_timeout | 认为节点挂了之后间隔多长时间再次检查健康情况 | |
backup | 用于指定备份服务器(当所有的服务器都挂了,备份服务器才启动) | 适用于高可用性场景 |
负载均衡配置
# upstream模块的upstream指令 创建一个池塘(分组),存放主机 # upstream创建池塘,proxy_pass将数据丢向池塘 upstream wordpress_pools { server 10.0.0.7:80; server 10.0.0.8:80; } server { listen 80; server_name blog.wordpress.cn; access_log /var/log/nginx/blog.wordpress.cn-access.log main; error_log /var/log/nginx/blog.wordpress.cn-error.log notice; location / { proxy_pass http://wordpress_pools; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
wordpress接入负载均衡
web01接入负载均衡
# nfs存储 [root@nfs01 ~]# tail -2 /etc/exports # wordpress上传数据存储点 /wordpress_uploads/ 172.16.1.0/24(rw,all_squash) [root@nfs01 ~]# mkdir -p /wordpress_uploads/ [root@nfs01 ~]# chown nfsnobody.nfsnobody /wordpress_uploads/ # 数据库db01 MariaDB [(none)]> create database wordpress; MariaDB [(none)]> create user 'wordpress'@'172.16.1.%' identified by 'wordpress123'; MariaDB [(none)]> create user 'wordpress'@'localhost' identified by 'wordpress123'; MariaDB [(none)]> grant all privileges on wordpress.* to 'wordpress_user'@'172.16.1.%'; MariaDB [(none)]> grant all privileges on wordpress.* to 'wordpress_user'@'localhost'; MariaDB [(none)]> flllush privileges; MariaDB [(none)]> select user,host from mysql.user; +------------+------------+ | user | host | +------------+------------+ | wordpress | 172.16.1.% | | wordpress | localhost | +------------+------------+ # 如果修改了数据库名、数据库用户名、数据库密码、数据库主机、休要对wordpress配置文件进行修改 [root@web01 /app/code/blog]# egrep '^define' wp-config.php define( 'DB_NAME', 'wordpress' ); # 数据库名 define( 'DB_USER', 'wordpress_user' ); # 数据库用户名 define( 'DB_PASSWORD', 'wordpress123' ); # 数据库密码 define( 'DB_HOST', '172.16.1.51' ); # 数据库主机

server{ listen 80; server_name blog.wordpress.cn; root /app/code/blog; error_log /var/log/nginx/blog-error.log notice; access_log /var/log/nginx/blog-access.log main; location / { index index.php; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_buffering on; # 启动或禁用fastcgi响应的缓冲 fastcgi_buffers 64 64k; # 设置nginx用户缓冲fastcgi响应的缓冲区数量和大小 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
# 挂载nfs mkdir -p /app/code/blog/wp-content/uploads mount -t nfs 172.16.1.31:/wordpress_uploads/ /app/code/blog/wp-content/uploads/(注意永久挂载)
web02接入负载均衡
配置好对应的环境:nginx、php(统一好对应的用户)
进行scp传输时,排除上传文件目录
[root@web01 /app/code]# scp -r /app/code/blog root@172.16.1.8:/app/code/
[root@web01 /etc/nginx/conf.d]# scp -r /etc/nginx/conf.d/blog.wordpress.cn.conf root@172.16.1.8:/etc/nginx/conf.d/
[root@web02 ~]# mount -t nfs 172.16.1.31:/wordpress_uploads/ /app/code/blog/wp-content/uploads/
lb01接入负载均衡

upstream blog_pools { server 10.0.0.7:80; server 10.0.0.8:80; } server { listen 80; server_name blog.wordpress.cn; access_log /var/log/nginx/blog.wordpress.linux.cn-access.log main; error_log /var/log/nginx/blog.wordpress.linux.cn-error.log notice; location / { proxy_pass http://blog_pools; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
Nginx处理静态/动态请求流程
老男孩教育-最新架构-Ngx处理用户请求流程-动态-无负载| ProcessOn免费在线作图,在线流程图,在线思维导图
负载均衡处理用户请求流程
老男孩教育-最新架构-综合架构-Ngx-处理用户请求流程-含负载均衡| ProcessOn免费在线作图,在线流程图,在线思维导图
phpMyAdmin会话共享/会话共享⭐⭐⭐⭐⭐
- 用户进行登录请求时,通过负载均衡将登录的状态/信息记录再web服务器上,就会导致不同的web服务器上登录状态不统一,造成用户频繁登录
- 会话:用户的登录状态/信息
cookie vs session⭐⭐⭐⭐⭐
技术点 | 共同点 | 区别 |
cookie | 存放用户数据(登录信息) | 存放在浏览器 |
服务器给客户端响应,响应头中包括Set-Cookie指令 客户端接收到Set-Cookie后将其保存 客户端再次访问时,浏览器会自动携带Cookie,服务器根据Cookie识别用户身份 |
||
session | 存放用户数据(登录信息) | 存放在服务器 |
服务器接收到客户端请求会生成一个session(通常会分配一个唯一标识符session ID) 服务器将 session ID 通过Set-Cookie发送给客户端,客户端保存Session ID 再次请求时自动携带Session ID 服务器解析请求中的 session ID,查找对应的 session 数据,以识别用户状态和管理会话 |
会话保持方案
- 登录状态存储在Cookie(WordPress)
- 结合Cookie与Session的会话管理方案
- 基于OAuth 2.0协议的Token身份验证
- IP Hash负载均衡算法
- 使用Redis实现phpMyAdmin/Kodbox的会话共享
使用Redis实现phpMyAdmin/Kodbox的会话共享⭐⭐⭐⭐⭐
流程
- db01:创建一个数据库用户,要求权限非常的大(phpmyadmin)
- web:部署代码,再通过scp传输到另外的web服务器上面(确保nginx、php的用户一致)
- lb01:接入负载均衡
- db01:部署redis实现会话共享
- web:修改php配置(创建新的端口)
db准备phpmyadmin用户(权限大)
grant all privileges on *.* to 'phpmyadmin'@'172.16.1.%' identified by '123';
部署代码



# 手动创建连接数据库的配置文件 [root@web01 /app/code/phpmyadmin]# cp config.sample.inc.php config.inc.php [root@web01 /app/code/phpmyadmin]# grep -wn host config.inc.php 30:$cfg['Servers'][$i]['host'] = 'localhost'; [root@web01 /app/code/phpmyadmin]# vim config.inc.php [root@web01 /app/code/phpmyadmin]# grep -wn host config.inc.php 30:$cfg['Servers'][$i]['host'] = '172.16.1.51';
部署redis服务(由于机器有限,会话共享部署在db01上)
# 部署redis [root@db01 ~]# yum install -y redis # 修改/etc/redis.conf(设置允许访问redis的ip) [root@db01 ~]# vim /etc/redis.conf bind 127.0.0.1 172.16.1.51 # 本地网卡的ip # 立刻启动并开启自启动 [root@db01 ~]# systemctl enable --now redis # 检查进程与端口 [root@db01 ~]# ps -ef |grep redis [root@db01 ~]# ss -lntup |grep redis
php配置文件指定会话存放位置
# 创建新的子配置文件 [root@web01 /etc/php-fpm.d]# cp www.conf session.conf # 修改/etc/php-fpm.d/session.conf [root@web01 /etc/php-fpm.d]# egrep -v '^$|;' session.conf [session] user = nginx group = nginx listen = 127.0.0.1:9001 # 记得修改web服务器虚拟主机的端口号 listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 slowlog = /var/log/php-fpm/www-slow.log php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_flag[log_errors] = on php_value[session.save_handler] = redis php_value[session.save_path] = tcp://172.16.1.51:6379 php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache # 检查语法和重启 [root@web01 /etc/php-fpm.d]# php-fpm -t [root@web01 /etc/php-fpm.d]# systemctl reload php-fpm.service # 检查端口和进程 [root@web01 ~]# ss -lnutp |grep php-fpm tcp LISTEN 0 128 127.0.0.1:9000 tcp LISTEN 0 128 127.0.0.1:9001 [root@web01 ~]# ps -ef |grep php-fpm root 1958 1 0 18:25 ? 00:00:00 php-fpm: master process (/etc/php-fpm.conf) nginx 3042 1958 0 20:53 ? 00:00:00 php-fpm: pool session nginx 3046 1958 0 20:53 ? 00:00:00 php-fpm: pool session nginx 3047 1958 0 20:53 ? 00:00:00 php-fpm: pool www nginx 3048 1958 0 20:53 ? 00:00:00 php-fpm: pool www
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界