nginx动静分离,session共享,nginx基础扩展
目录
一.LNMP架构与session不同步解决方案
二.Nginx知识点延伸
一丶LNMP架构与session不同步解决方案
1.原理
动静分离的工作原理:
- Nginx 接收到客户端发起的请求。
- 如果请求的资源是静态文件,比如图片、CSS、JavaScript 文件等,Nginx 根据配置对应的静态资源的目录,直接返回对应的文件给客户端。这样可以充分利用 Nginx 的高性能静态文件服务能力。
- 如果请求的资源是动态请求,如 PHP 脚本,Nginx 将把请求转发给后端的应用服务器(如 PHP-FPM)进行处理。通常,Nginx 会使用代理模块(如
proxy_pass
)将请求转发到指定的后端服务器。 - 后端应用服务器(如 PHP-FPM)接收到转发的动态请求后,执行相应的脚本处理,并生成动态内容。
- 后端应用服务器将处理后的结果返回给 Nginx。
- Nginx 将获取到的动态内容返回给客户端。
通过动静分离,可以充分发挥 Nginx 在处理静态文件时的优势,同时将动态请求交给后端应用服务器进行处理,提高整个系统的并发处理能力和性能。这种优化策略常用于高流量和负载较大的网站,以提高用户体验和系统性能。
关于nginx的session不同步问题有两种解决方案
方案一:
使用ip_hash算法解决Session不同步问题,ip_hash算法会根据用户的IP地址将其请求分配给特定的服务器,这样可以确保同一个用户的请求始终被分发到同一台服务器上,从而保证Session数据的一致性。然而,如果使用ip_hash算法的请求源IP的分布不均匀,可能会导致许多用户只访问后端其中一台服务器。造成某些服务器的负载较高,而其他服务器的负载较低。例如,如果大多数用户来自同一个地区或使用同一个出口IP,那么这些用户的请求可能会被分发到同一台服务器上,导致该服务器的负载过高,其他服务器的负载则较低。
方案二:
session共享,使用redis来存储和管理Session数据,从而实现跨服务器的Session共享和同步。
LNMP架构中实现该原理的步骤:
-
安装Redis服务器:在Nginx服务器和PHP-FPM之外,需要安装和配置Redis服务器。Redis服务将作为Session数据的中心存储。
-
配置PHP-FPM:修改PHP-FPM的php.ini文件,设置session.save_handler为"redis",session.save_path为Redis服务器的连接地址和端口。这将使PHP将Session数据存储到Redis中。
-
配置Nginx:在Nginx的配置文件中,可以配置一个负载均衡器,将请求分发给多台后端PHP-FPM服务器。这可以使用Nginx的upstream模块来实现。
-
请求过程:当客户端发起请求时,Nginx负载均衡器会根据一定的算法将请求分发到一台后端的PHP-FPM服务器。
-
PHP-FPM:在后端PHP-FPM服务器中,使用PHP的内置函数将Session数据存储到Redis中。这可以使用Redis扩展库提供的函数。
-
其他后续请求:当其他请求到达不同的后端PHP-FPM服务器时,服务器会先从Redis中获取请求中的Session ID所对应的数据,然后根据Session数据来处理请求并返回响应。
通过使用Redis作为中心存储,LNMP架构中的多个PHP-FPM服务器可以共享和同步Session数据。Redis提供了高速且可扩展的存储和访问,确保了Session数据的可靠性和一致性。同时,通过在Nginx中配置负载均衡器,可以实现请求的分发和Session的负载均衡,提高系统的可靠性和性能。
session:存储在服务器端,存储了用户名,登陆状态等信息,session文件存放目录/var/lib/php/session/
cookies:由服务器下发给客户端,保存在客户端的文件里
sessionID(会话标识):cookies主要保存在客户端的内容,用于跟踪用户的登录状态和保存用户相关的数据。
2.LNMP搭建
2.1.环境准备
环境准备 | IP地址 | 安装与依赖 |
nginx-proxy | 192.168.99.5 |
gcc openssl-devel pcre-devel nginx-1.22.1 |
web1 | 192.168.99.100 |
gcc openssl-devel pcre-devel mariadb mariadb-server mariadb-devel php php-mysqlnd php-fpm nginx-1.22.1 phpredis-5.1.0-1.x86_64.rpm |
web2 | 192.168.99.200 |
gcc openssl-devel pcre-devel mariadb mariadb-server mariadb-devel php php-mysqlnd php-fpm nginx-1.22.1 phpredis-5.1.0-1.x86_64.rpm |
2.2.操作流程
web1与web2操作如下:
#安装nginx编译工具
# yum -y install make gcc openssl-devel pcre-devel
#安装mariadb服务 # yum -y install mariadb mariadb-server mariadb-devel
#安装php服务
# yum install -y php php-fpm php-mysqlnd
#启动mariadb
# systemctl restart mariadb
#进入到存放nginx源码编译安装包的路径,进行源码编译安装nginx.模块根据环境自行添加
# ./configure && make && make install
# cd /usr/local/nginx/
#修改Nginx配置文件(启用php页面,实现动静分离)
# vim conf/nginx.conf
43 location / {
44 root html;
45 index index.php index.html index.htm; #按顺序优先加载页面
46 }
65 location ~ \.php$ { 66 root html; 67 fastcgi_pass unix:/run/php-fpm/www.sock; ##nginx与php-fpm服务都在一台机器上,所以启用进程间通信 68 fastcgi_index index.php; 69 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #注释该行 70 include fastcgi.conf; 71 }
#启用nginx服务
# /usr/local/nginx/sbin/nginx
#添加nobody用户
# vim /etc/php-fpm.d/www.conf
listen.acl_users = apache,nginx,nobody
#启动php-fpm服务
# systemctl restart php-fpm
nginx-proxy操作如下:
# yum -y install make gcc openssl-devel pcre-devel
#进入到存放nginx源码编译安装包的路径,进行源码编译安装.模块根据环境自行添加
# ./configure && make && make install
# cd /usr/local/nginx/
# vim conf/nginx.conf
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #http段添加upstream模块,添加后端服务器群组 upstream webs { server 192.168.99.100:80; server 192.168.99.200:80; } server { listen 80; server_name localhost; location / {
#添加proxy_pass代理访问后端服务器群组webs
proxy_pass http://webs; root html; index index.php index.html index.htm; }
#启动nginx
# /usr/local/nginx/sbin/nginx
此时,通过代理访问后端服务器登陆页面的时候,点击提交查询,会再次跳转到下一个登陆页面,造成重复登陆的操作
如下图,如果有更多后端服务器,会继续往下跳转要求用户登陆
3.session共享(解决集群中客户重复登陆帐号的问题)
proxy-nginx安装redis
# yum install -y redis
# vim /etc/redis.conf
#bind 127.0.0.1 注释 #protected-mode no #关闭保护模式
# systemctl restart redis
web1与web2安装PHP扩展
# yum install -y phpredis-5.1.0-1.x86_64.rpm
web1与web2修改配置
# vim /etc/php-fpm.d/www.conf
431 php_value[session.save_handler] = redis #php会话程序将会以redis作为后端存储 432 php_value[session.save_path] = "tcp://192.168.99.5:6379" #redis服务器地址和端口,以tcp链接发送数据与redis进行通告 433 php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache 434 ;php_value[opcache.file_cache] = /var/lib/php/opcache
# systemctl restart php-fpm
最后结果是通过代理服务器访问登陆页面,登陆一次即可看到用户登陆后页面
二丶Nginx知识点延伸
什么是nginx正向代理与反向代理?
正向代理:nginx的正向代理是指通过nginx服务器转发客户端发起的请求到后端服务器,这样做可以隐藏客户端的存在.
反向代理:客户端发送请求由代理服务器进行接收,再根据配置的负载均衡规则将请求转发给后端服务器。客户端只会获得代理服务器的地址,从而隐藏了后端服务器的真实地址,提高了安全性。
1.用户页面认证
# vim /usr/lcoal/nginx/conf/nginx
server { listen 80; server_name localhost; auth_basic "Input Password:"; #设置HTTP Basic身份验证的提示信息。要求输入用户名和密码认证 auth_basic_user_file "/usr/local/nginx/pass"; #认证的密码文件,包含用户名和密码 location / { root html; index index.html index.htm; }
# yum -y install httpd-tools
#启动nginx或者重新加载配置文件
#/usr/local/nginx/sbin/nginx
浏览器访问nginx页面结果如下
2.基于域名访问
# vim /usr/local/nginx/conf/nginx.conf
#http模块配置
server { listen 80; #监听端口 server_name www.b.com; #虚拟主机域名 location / { root html_b; #指定网站根路径 index index.html index.htm; #默认页面 } } server { listen 80; server_name www.a.com; location / { root html; index index.html index.htm; }
# echo 192.168.99.5 www.a.com www.b.com >> /etc/hosts #本地域名解析
# midir /usr/local/nginx/html_b
# echo I am a.com > html/index.html
# echo I am b.com > html_b/index.html
#域名访问测试结果如下
3.基于端口配置
# vim /usr/local/nginx/conf/nginx.conf
#http模块配置 server { listen 8888; #监听端口 server_name www.a.com; #虚拟主机域名 location / { root html_b; #指定网站根路径 index index.html index.htm; #默认页面 } } server { listen 8000; server_name www.a.com; location / { root html; index index.html index.htm; }
# echo 192.168.99.5 www.a.com www.b.com >> /etc/hosts #本地域名解析
# midir /usr/local/nginx/html_b
# echo I am a.com > html/index.html
# echo I am b.com > html_b/index.html
端口访问测试结果如下
4.加密网站配置
源码安装Nginx时必须使用--with-http_ssl_module参数
4.1添加nginx模块
当前的已安装的nginx未编译模块
在nginx源码包目录下添加模块
#./configure --with-stream --with-http_stub_status_module --with-http_ssl_module
# make #编译
在编译完成后,生成的Nginx可执行文件将被放置在"objs"目录下,名称通常为"nginx"
可通过以下查询已编译的nginx可执行文件详细信息
-s stop停掉nginx服务之后,覆盖可执行文件即可完成比nginx模块添加
4.2开启ssl加密配置
# vim /usr/local/nginx/conf/nginx/conf
server { listen 443 ssl; server_name localhost; ssl_certificate cert.pem; #证书文件 ssl_certificate_key cert.key; #私钥文件 ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root https; #加密网站根目录 index index.html index.htm; } }
生成私钥,证书
# openssl genrsa > conf/cert.key #生成私钥
# openssl req -x509 -key conf/cert.key > conf/cert.pem ##生成证书,生成过程会询问一些国家,公司的问题,测试可以随意回答
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:aa State or Province Name (full name) []:aa Locality Name (eg, city) [Default City]:aa Organization Name (eg, company) [Default Company Ltd]:aa Organizational Unit Name (eg, section) []:aa Common Name (eg, your name or your server's hostname) []:aa Email Address []:aa
curl方式或https方式访问浏览器即为成功设置ssl加密
# mkdir https # echo "加密https~" > https/index.html # sbin/nginx # curl -k https://192.168.99.5 #客户端访问,看到此结果即为成功设置 加密https~
5.404错误页面自定义
5.1状态码功能描述
5.2错误404页面配置
下载一个提示的图片存放在html目录下
[root@proxy nginx]# vim conf/nginx.conf
server {
listen 80;
server_name localhost;
#定义字符编码,支持中文
charset utf-8;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#404错误页面提示
error_page 404 /404.webp; ##错误页面图片名称
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
[root@proxy nginx]# sbin/nginx -s reload
访问一个不存在的目录结果如下
6.开启Status功能
编译译安装时需要--with-http_stub_status_module开启状态页面模块
配置文件server模块添加以下内容
# vim /usr/local/nginx/conf/nginx.conf
server { listen 80; server_name localhost; charset utf-8; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } location /status { stub_status on; #开启status服务 allow 192.168.99.5; #只允许xxx访问 deny all; #拒绝所有 }
7.配置文件设置的是除了自己以外所有人不能访问status,因此
客户端浏览器查看status结果如下
8.本机上访问自己的status信息
Active connections:当前活动的连接数量。
Accepts:已经接受客户端的连接总数量。
Handled:已经处理客户端的连接总数量。
Requests:客户端发送的请求数量。
Reading:当前服务器正在读取客户端请求头的数量。
Writing:当前服务器正在写响应信息的数量。
Waiting:当前多少客户端在等待服务器的响应。
7.地址重写
7.1 设置页面跳转
# vim /usr/local/nginx/conf/nginx.conf
server { listen 80; server_name localhost; rewrite /a.html /b.html; #a页面跳转到b页面 location / { root html; index index.html index.htm; }
# /usr/local/nginx/sbin/nginx -s reload 结果如下
此时用浏览器访问会发现一个问题,访问的a页面地址虽然跳转了,但是地址栏没有改变
因此对nginx.conf配置文件,地址重写配置进行以下修改
server { listen 80; server_name localhost; rewrite ^/a.html$ /b.html redirect;
# /usr/local/nginx/sbin/nginx -s reload
此时浏览器访问a页面后,进行页面跳转后
地址栏也会变化
7.2 不同网站间跳转
server { listen 80; server_name localhost; rewrite / https://www.baidu.com/;
# /usr/local/nginx/sbin/nginx -s reload
访问本机192.168.99.5会跳转到百度页面
7.3 不同浏览器访问跳转到不同页面
server { listen 80; server_name localhost; if ($http_user_agent ~* firefox) { rewrite (.*) /firefox/$1; }
# mkdir html/firefox # echo firefox > html/firefox/a.html # echo otehers > html/a.html # sbin/nginx -s reload
其他浏览器访问nginx
火狐浏览器访问nginx
8.反向代理
# vim /usr/local/nginx/conf/nginx.conf
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream webservers { #定义服务器集群 server 192.168.99.10:80; server 192.168.99.11:80; } server { listen 80; server_name localhost; location / { root html; index index.html index.htm; proxy_pass http://webservers; #proxy_pass代理用户访问服务器集群 } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }
# /usr/local/nginx/sbin/nginx -s reload
默认采用轮询代理
9.设置健康检查
max_fails设置后台服务器的失败次数,fail_timeout可以设置后台服务器的失败超时时间
# vim /usr/local/nginx/conf/nginx.conf
upstream webserver { server 192.168.99.100; server 192.168.99.200 max_fails=3 fail_timeout=30; }
10.添加down标记
down标记可以让集群主机暂时不参与集群活动
# vim /usr/local/nginx/conf/nginx.conf
upstream webserver { server 192.168.99.100 ; server 192.168.99.200 down; }
11.优化nginx并发量
出现以下原因是Linux无法同时打开这么多的文件
# ab -n 2000 -c 2000 http://192.168.99.5/ #-n任务量,-c连接数 This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.99.5 (be patient) socket: Too many open files (24)
优化Linux内核参数(最大文件数)
# vim /etc/security/limits.conf .. .. * soft nofile 100000 * hard nofile 100000 #该配置文件分4列,分别如下: #用户或组 硬限制或软限制 需要限制的项目 限制的值
优化nginx核心与并发连接数
# vim /usr/local/nginx/conf/nginx.con
.. .. worker_processes 2; #与CPU核心数量一致 events { worker_connections 50000; #每个worker最大并发连接数 } .. ..
再次进行并发量测试
# ab -n 2000 -c 2000 http://192.168.99.5/ This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.99.5 (be patient) Completed 200 requests ...... Finished 2000 requests ...... Time per request: 111.481 [ms] (mean) Time per request: 0.056 [ms] (mean, across all concurrent requests) Transfer rate: 4223.13 [Kbytes/sec] received ....... 100% 80 (longest request)
12.nginx隐藏版本号
1.命令行访问不存在的路径,查看版本号
2.修改配置文件
[root@web1 ~]# vim /etc/nginx/nginx.conf ... ... 17 http { 18 server_tokens off; ... ... [root@web1 ~]# systemctl restart nginx.service
3.再次访问不存在路径,版本号已隐藏
13.防止DOS、DDOS攻击
DDOS:分布式拒绝服务
压力测试
# ab -c 100 -n 200 http://192.168.88.100/ ......... Benchmarking 192.168.88.100 (be patient) Completed 100 requests Completed 200 requests Finished 200 requests Server Software: nginx Server Hostname: 192.168.88.100 Server Port: 80 Complete requests: 200 #0次失败
修改配置文件
# vim /etc/nginx/nginx.conf 17 http { 18 limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; # 添加配置nginx连接共享内存为10M,每秒钟只接收一个请求
... ... 40 server { 41 listen 80 default_server; 42 listen [::]:80 default_server; 43 server_name _; 44 root /usr/share/nginx/html; 45 limit_req zone=one burst=5; # 添加最多有5个请求排队,多余的拒绝
[root@web1 ~]# systemctl restart nginx.service
再次压力测试
# ab -c 100 -n 200 http://192.168.88.100/ Completed 100 requests Completed 200 requests Finished 200 requests Server Software: nginx Server Hostname: 192.168.88.100 Server Port: 80 Concurrency Level: 100 Time taken for tests: 5.002 seconds Complete requests: 200 Failed requests: 194 ##失败194次 一个请求处理了,4个在排队 100% 5000 (longest request)