Nginx
https://www.cnblogs.com/knowledgesea/category/789005.html
https://www.jianshu.com/p/849343f679aa
https://www.cnblogs.com/yougewe/p/6281811.html
https://www.bilibili.com/video/av16937594
https://www.bilibili.com/video/av35430025
功能:
反向代理(内网集群/服务器):监听转发,负载均衡(需要共享session,统一认证token),
静态代理(文件):动静分离(图片、js、不变的html),减少Tomcat IO处理。
Nginx并发达到5万,远大Tomcat。结合网页静态化技术,部署静态网页,可以大大提高访问量。
解决跨域:欺骗浏览器,实现跨域请求、跨域cookie
压缩:GZIP
限流:
https://www.cnblogs.com/devinzhang/p/7735397.html
https://blog.csdn.net/myle69/article/details/83512617
缓存:
https://www.jianshu.com/p/6db58cce7c8d
https://www.cnblogs.com/wangzhisdu/p/7771069.html
nginx监听所在服务器端口(例如:111.111.111.111:80),客户端访问111.111.111.111:80后,nginx根据路由规则,将请求转发给对应服务器
nginx只能有一个生效,其他的可以做备用(高可用 安装keepalived 备用nginx通过心跳 监控)
配置:
注意:nodepad 修改conf可能会出BUG
0 配置整体
#运行用户
user nobody;
#启动进程,通常设置成和cpu的数量相等
worker_processes 1;
#全局错误日志及PID文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#工作模式及连接数上限
events {
#epoll是多路复用IO(I/O Multiplexing)中的一种方式,
#仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
#单个后台worker process进程的最大并发链接数
worker_connections 1024;
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535
}
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
#开启gzip压缩
gzip on;
gzip_disable "MSIE [1-6].";
#设定请求缓冲
client_header_buffer_size 128k;
large_client_header_buffers 4 128k;
1 server 虚拟服务主机配置
1个http模块可以有多个server,一个server可以有多个location路由
监听端口+域名,路由转发
server 中: 端口listen + 域名/地址server_name +路由规则location 都可以影响转发目的地
//若不设置默认是轮询。但是chorme浏览器有时会出现BUG,解决方法是指定权重 1:1强制轮询
upstream mysvr { #可以做负载均衡
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址 NGINX监听本机,请求发到NGINX主机:4545端口,nginx接收并转发
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #代理路径 请求转向发给mysvr 定义的服务器列表
proxy_set_header X-Real-IP $remote_addr; #客户端IP 放在header中转发
proxy_set_header Host $host; #域名转发
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
#proxy_set_header Cookie "$http_cookie; node_id=018" # 这里增加了名为node_id的一个cookie进去
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
server {
listen 80; #监听本机80端口 ipv4
listen [::]:80; #监听本机80端口 ipv6
server_name example.com www.example.com; #请求HOST中对应域名
#客户端host,可以多个域名对应本NGINX服务器IP
# 定义服务器的默认网站根目录位置
root /var/www/example/;
# access log file 访问日志
access_log logs/nginx.access.log main;
# 禁止访问隐藏文件
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 默认请求
location / {
# 首先尝试将请求作为文件提供,然后作为目录,然后回退到显示 404。
# try_files 指令将会按照给定它的参数列出顺序进行尝试,第一个被匹配的将会被使用。
# try_files $uri $uri/ =404;
try_files $uri $uri/ /index.php?path_info=$uri&$args =404;
access_log off;
expires max;
}
# 静态文件,nginx 自己处理
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
#过期 30 天,静态文件不怎么更新,过期可以设大一点,
#如果频繁更新,则可以设置得小一点。
expires 30d;
}
# 拒绝访问. htaccess 文件,如果 Apache 的文档根与 nginx 的一致
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
2 路由规则
https://www.cnblogs.com/feiyuanxing/p/4668818.html
3 cookie 跨域转发丢失与共享(设置proxy_cookie_path ; proxy_set_header Cookie $http_cookie;)
https://blog.csdn.net/isyoungboy/article/details/81382193
https://blog.csdn.net/yakson/article/details/46683285
https://www.cnblogs.com/hujunzheng/p/5744755.html
cookie 丢失首先检查 cookie的域名+路径 是否与请求匹配
upstream集群分配模式:经测试nginx的upstream中的集群服务,即使只配置路由未加任何特殊配置,都可以正常转发header+cookies给后端被代理服务,后端被代理服务也正常set-cookie
//测试配置,nginx成功转发header+cookie,到mysvr中
//配合postman发送请求到nginx
upstream mysvr {
server 192.168.1.129:8787; //192.168.1.129 是本机外网IP
server 192.168.1.129:8788;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://mysvr;
}
}
cookie认IP地址/域名,不区别端口。同IP/域名下的请求浏览器都会携带相同的cookie。
但是注意浏览器发送请求时,IP地址 和 localhost会被认为是两个域,所以浏览器携带的cookie也会不同。
比如:第一次请求http://localhost/get ,第二次请求http://本机Ip/get 。第二次请求时,浏览器不会携带第一次请求取得的cookies
Location路由分配模式:经测试分别用传统方法在a或b中添加cookie值,a/b之间是不能共享的。因为这样设置cookie时会产生不同路径(/a 或是 /b)。需要手动设置cookie的域名(nginx的域名/IP)和路径(“/” 标识任何路径都携带cookies)。这样就可以共享cookie了。不需要共享的可以使用默认域名和路径。灵活的选择cookie值是共享还是独立。
经测试cookie中的SESSIONID的默认路径就是"/",只要其域名与NGINX相同则全路径携带。无需特殊设置,可以直接通过nginx转发实现共享。
https://blog.csdn.net/shanchahua123456/article/details/85341383
#场景:假设/a、/b代表两个不同的功能,分发到两个不同的分布式服务中
server {
listen 80;
server_name localhost;
location /a {
proxy_pass http://192.168.1.129:8788;
#默认产生的cookie path=/a
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
}
location /b {
proxy_pass http://192.168.1.129:8787;
#默认产生的cookie path=/b
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
}
}
}
手动设置生成cooke的域和路径,保证共享
//登录后把用户信息写入cookie,我这里是存进去一个token值这里就当做token=user1
Cookie user_cookie = new Cookie("token","user1");
//设置cookie的domain这里注意写的是主域名
//(a.test.com,b.test.com的主域名就是.test.com。若有NGINX代理,则可以设置为NGINX的域名)
//写入这个参数之后所有主域名为.test.com的项目都可以调用这个cookie
user_cookie.setDomain(".test.com"); //IP也可以
//设置cookie的path
//path这里直接写 / 表示所有路径都可以访问
user_cookie.setPath("/");
//然后返回cookie
response.addCookie(user_cookie);
可以通过为分布式项目配置各自的全局URL前缀,更好的结合location进行转发。
例如: 为以上配置中的 192.168.1.129:8787 项目配置全局URL前缀"/b",8788全局URL前缀"/a"。
以springboot2.0为例子,在8787项目配置server.servlet.context-path=/b。这样在8787项目开发中就不用把每一个@RequestMapping都写成("/b/XXX")了。因为默认所有@RequestMapping都自动补全前缀"/b"。
4 被代理服务器取得真正的客户端IP
因为请求是被nginx转发到后端服务器的,所以传统方法后端服务器会将nginx服务器IP当做客户端。
解决方法:proxy_set_header X-Real-IP $remote_addr; # NGINX设置 将客户端IP 放在header中转发,后端服务器通过header取得客户真实ip
5 使用Nginx过滤网络爬虫
其实Nginx可以非常容易地根据User-Agent过滤请求,我们只需要在需要URL入口位置通过一个简单的正则表达式就可以过滤不符合要求的爬虫请求
location / {
if ($http_user_agent ~* "python|curl|java|wget|httpclient|okhttp") {
return 503;
}
# 正常处理
...
}
启动停止:
start nginx
nginx -s stop
https://jingyan.baidu.com/article/39810a23b85dd4b636fda6eb.html
注意win不要直接双击nginx.exe,这样会导致很多问题。我们使用命令行工具进行nginx的启动、停止和重启工作。使用Win+R快捷键打开命令行窗口,并切换到nginx.exe所在的目录,我们使用start nginx命令来启动nginx,启动后我们查看任务管理器可以看到如下的界面。
启动后再任务管理器进程中可以看到两个nginx.exe
启动报错:配置文件53行 有错

高并发优化 :
链接优化
系统优化(nginx部署的主机linux)
1 增加socket链接数限制。(somaxconn)
2 加快tcp链接回收 (recycle),空tcp立即回收(reuse)
3 不做洪水攻击抵御
Nginx优化
1 nginx同样要增加链接数 (worker_connections),增加工作进程(worker_processes 不超过cpu核心数)
2 keepalive_timeout 适当缩短,因为对于高并发服务,链接珍贵,不推荐某一个客户端长时间保持链接,0-5秒即可
文件优化
若要读取静态文件,则修改同时打开文件数限制。
系统优化
1 (ulimit -n)
Nginx优化
1 worker_rlimit_noflie 增大
2 location ~* \.(jpg|gif|) { expires 30s } 设置静态资源缓存 1h,1d (匹配 .jpg .gif . )
AB测试
ab进行压测时,注意ab客户端也要优化(ulimit 、echo),否则ab端也可能出错,影响压测真实性
可多台ab一起测试,分担客户端压力
![]()
c:同时并发量 n:总请求次数 -k :长连接测试(可选) + 请求地址:nginx服务器 默认80端口
ab客户端测试结果示例:

高可用
可以通过keepailved配置主机和备用机nginx。

浙公网安备 33010602011771号