静态资源服务,通过本地文件系统提供服务;
反向代理服务,延伸出包括缓存、负载均衡等;
API 服务,OpenResty
同时满足下面两个条件
1)请求方法是 HEAD、GET、POST 三种之一;
2)HTTP 头信息不超过右边着几个字段:Accept、Accept-Language、Content-Language、Last-Event-ID
Content-Type 只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain;
不同时满足上述两个条件的
1)简单请求
对于简单请求,浏览器会在头信息中增加 Origin 字段后直接发出,Origin 字段用来说明,本次请求来自的哪个源(协议+域名+端口)。
如果服务器发现 Origin 指定的源不在许可范围内,服务器会返回一个正常的 HTTP 回应,浏览器取到回应之后发现回应的头信息中没有包含 Access-Control-Allow-Origin 字段,就抛出一个错误给 XHR 的 error 事件;
如果服务器发现 Origin 指定的域名在许可范围内,服务器返回的响应会多出几个 Access-Control- 开头的头信息字段。
2)非简单请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是 PUT 或 DELETE,或 Content-Type 值为 application/json。浏览器会在正式通信之前,发送一次 HTTP 预检 OPTIONS 请求,先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 请求方法和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XHR 请求,否则报错。
在浏览器上当前访问的网站向另一个网站发送请求获取数据的过程
跨域:浏览器的同源策略决定的,是一个重要的浏览器安全策略,用于限制一个 origin 的文档或者它加载的脚本与另一个源的资源进行交互,它能够帮助阻隔恶意文档,减少可能被攻击的媒介,可以使用 CORS 配置解除这个限制。
同源定义:
如果两个 URL 的 protocol、port (en-US) (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。
一般给客户端做代理的都是正向代理,给服务器做代理的就是反向代理。
负载均衡,核心是「分摊压力」。Nginx 实现负载均衡,一般来说指的是将请求转发给服务器集群。
由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。
使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。
user nginx; # 运行用户,默认即是nginx,可以不进行设置
worker_processes 1; # Nginx 进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
worker_connections 1024; # 每个进程允许最大并发数
}
http { # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
# 设置日志模式
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 /var/log/nginx/access.log main; # Nginx访问日志存放位置
sendfile on; # 开启高效传输模式
tcp_nopush on; # 减少网络报文段的数量
tcp_nodelay on;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒
types_hash_max_size 2048;
include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型
include /etc/nginx/conf.d/*.conf; # 加载子配置项
server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名
location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44; # 允许访问的ip地址,可以为all
}
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}
server 块可以包含多个 location 块,location 指令用于匹配 uri,语法:
location [ = | ~ | ~* | ^~] uri {
...
}
= 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;
^~ 用于不含正则表达式的 uri前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;
~ 表示用该符号后面的正则去匹配路径,区分大小写;
~* 表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;
如果 uri 包含正则表达式,则必须要有 ~ 或 ~* 标志。
比如监听 9001 端口,然后把访问不同路径的请求进行反向代理:
把访问 http://127.0.0.1:9001/edu 的请求转发到 http://127.0.0.1:8080
把访问 http://127.0.0.1:9001/vod 的请求转发到 http://127.0.0.1:8081
打开主配置文件,然后在 http 模块下增加一个 server 块:
server {
listen 9001;
server_name *.sherlocked93.club;
location ~ /edu/ {
proxy_pass http://127.0.0.1:8080;
}
location ~ /vod/ {
proxy_pass http://127.0.0.1:8081;
}
}
反向代理其他的指令:
proxy_set_header:在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息。
proxy_connect_timeout:配置Nginx与后端代理服务器尝试建立连接的超时时间。
proxy_read_timeout:配置Nginx向后端服务器组发出read请求后,等待相应的超时时间。
proxy_send_timeout:配置Nginx向后端服务器组发出write请求后,等待相应的超时时间。
proxy_redirect:用于修改后端服务器返回的响应头中的Location和Refresh。
upstream demo_name{
server ip:port; # ip1
server ip:port; # ip2
server ip:port; #ip3
}
1.1、 h t t p h o s t 与 http_host与 httphost与host区别
1、在使用Nginx做反向代理的时候,proxy_set_header功能可以设置反向代理后的http header中的host,
那么常用的几个设置中$proxy_host, h o s t , host, host,http_host又都表示什么意思呢?
Nginx的官网文档中说下面这两条是做反代时默认的,所以$proxy_host 自然是 proxy_pass后面跟着的host了
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
如果客户端发过来的请求的header中有’HOST’这个字段时,
h t t p h o s t 和 http_host和 httphost和host都是原始的’HOST’字段
比如请求的时候HOST的值是www.csdn.net 那么反代后还是www.csdn.ne
1.1.1、 不设置 proxy_set_header Host 时
浏览器直接访问 nginx,获取到的 Host 是 proxy_pass 后面的值,即 $proxy_host 的值,参考
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
server {
listen 8090;
server_name _;
location / {
proxy_pass http://172.31.5.0:5000;
}
}
1.1.2、 设置 proxy_set_header Host $host 时
浏览器直接访问 nginx,获取到的 Host 是 $host 的值,没有端口信息
server {
listen 8090;
server_name _;
location / {
proxy_set_header Host $host;
proxy_pass http://172.31.5.0:5000;
}
}
1.1.3、2.3 设置 proxy_set_header Host h o s t : host: host:proxy_port 时
浏览器直接访问 nginx,获取到的 Host 是 h o s t : host: host:proxy_port 的值
server {
listen 8090;
server_name _;
location / {
proxy_set_header Host $host:$proxy_port;
proxy_pass http://172.31.5.0:5000;
}
}
1.1.4、2.4 设置 proxy_set_header Host $http_host 时
浏览器直接访问 nginx,获取到的 Host 包含浏览器请求的 IP 和端口
server {
listen 8090;
server_name _;
location / {
proxy_set_header Host $http_host;
proxy_pass http://172.31.5.0:5000;
}
}
1.1.5、2.5 设置 proxy_set_header Host $host 时
浏览器直接访问 nginx,获取到的 Host 是 $host 的值,没有端口信息。此时代码中如果有重定向路由,那么重定向时就会丢失端口信息,导致 404
server {
listen 8090;
server_name _;
location / {
proxy_set_header Host $host;
proxy_pass http://172.31.5.0:5000;
}
}
1.1.6、X-Real-IP
下面我们看一下有多级代理存在时如何获取客户端真实IP.
首先要明确在header里面的 X-Real-IP只是一个变量,后面的设置会覆盖前面的设置(跟X-Forwarded-For的追加特性区别明显),所以我们一般只在第一个代理设置proxy_set_header X-Real-IP r e m o t e a d d r ; 就好了,然后再应用端直接引用 remote_addr;就好了,然后再应用端直接引用 remoteaddr;就好了,然后再应用端直接引用http_x_real_ip就行.
https://blog.csdn.net/xiaoxiao_yingzi/article/details/92835704
1、配置反向代理端的nginx服务器
在server后面增加如下这三个参数用于记录IP:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2、在后端服务器配置如下
在后端服务器的nginx_http处配置如下:
配置log_format信息, 后续的日志后面也需要加上main这个参数
log_format main '$remote_addr $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'$http_user_agent $http_x_forwarded_for $request_time $upstream_response_time $upstream_addr $upstream_status';
`参数 说明 示例`
`$remote_addr 客户端地址 211.28.65.253`
`$remote_user 客户端用户名称 --`
`$time_local 访问时间和时区 18``/Jul/2012``:17:00:01 +0800`
`$request 请求的URI和HTTP协议 ``"GET /article-10000.html HTTP/1.1"`
`$http_host 请求地址,即浏览器中你输入的地址(IP或域名) www.wang.com 192.168.100.100`
`$status HTTP请求状态 200`
`$upstream_status upstream状态 200`
`$body_bytes_sent 发送给客户端文件内容大小 1547`
`$http_referer url跳转来源 https:``//www``.baidu.com/`
`$http_user_agent 用户终端浏览器等信息 "Mozilla``/4``.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident``/4``.0; SV1; GTB7.0; .NET4.0C;`
`$ssl_protocol SSL协议版本 TLSv1`
`$ssl_cipher 交换数据中的算法 RC4-SHA`
`$upstream_addr 后台upstream的地址,即真正提供服务的主机地址 10.10.10.100:80`
`$request_time 整个请求的总时间 0.205`
`$upstream_response_time 请求过程中,upstream响应时间 0.002`
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = getRequest();
//获取所有请求头名称
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
//根据名称获取请求头的值
String value = request.getHeader(name);
System.out.println(name+"---"+value);
}
性能优化-开启高效文件传输模式sendfile on;
sendfile on; #特殊的数据传输功能
tcp_nopush on;
参数sendfile on 用于开启文件高效传输模式,同时将tcp_nopush on 和tcp_nodelay on 两个指令设置为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率
(1) 设置参数 sendfile on
参数语法 sendfile on | off;
放置位置 http,server,location,if in location
(2) 设置参数 tcp_nopush on 说明:当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
参数语法 tcp_nopush on | off;
放置位置 http,server,location
(3) 设置参数 tcp_nodelay on 说明:有时要抓紧发货, 确保数据尽快发送, 提高可数据传输效率
参数语法 tcp_nodelay on | off;
放置位置 http,server,location
sendfile on配合使用(2)(3) 但(2)(3)只能选其一特别注意
在主配置文件nginx.conf中配置
worker_processes 2;
worker_cpu_affinity 0101 1010;
error_log logs/error.log;
#配置Nginx worker进程最大打开文件数
worker_rlimit_nofile 65535;
user www www;
events {
#单个进程允许的客户端最大连接数
worker_connections 20480;
#使用epoll模型
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
#sendfile on;
keepalive_timeout 65;
#访问日志配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#虚拟主机
include /application/nginx/conf/extra/www.conf;
include /application/nginx/conf/extra/blog.conf;
include /application/nginx/conf/extra/bbs.conf;
include /application/nginx/conf/extra/edu.conf;
include /application/nginx/conf/extra/phpmyadmin.conf;
include /application/nginx/conf/extra/status.conf;
#nginx优化----------------------
#隐藏版本号
server_tokens on;
#优化服务器域名的散列表大小
server_names_hash_bucket_size 64;
server_names_hash_max_size 2048;
#开启高效文件传输模式
sendfile on;
#减少网络报文段数量
#tcp_nopush on;
#提高I/O性能
tcp_nodelay on;
}
./nginx -v
启动 nginx
./nginx
查看是否启动成功:ps -ef|grep nginx
3、停止 nginx
./nginx -s stop
4、重新加载 nginxv
./nginx -s reload
5、查看版本号
nginx -v
6、检查配置文件是否有误
nginx –t
log_format 有个默认的日志格式:
log_format combined '$remote_addr - $remote_user [$time_local] '
' "$request" $status $body_bytes_sent '
' "$http_referer" "$http_user_agent" ';
nginx 默认调用 combined 格式来记录日志,即默认调用:(默认记录在access.log文件中)
access_log logs/access.log combined;
nginx允许自定义日志格式,例如:
log_format main '$remote_addr - $remote_user [$time_local] "$http_host" "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for $request_time';
以上是自定义了日志格式:main(main名称可以自定义)
要想使其生效,就必须用access_log指定调用:
access_log logs/xx.log main;
否则,nginx仍然会去调用combined格式来记录日志。
注意,http段也必须明确指定调用main格式才会生效,否则还是会调用默认的combined格式。
1、nginx.conf
log_format accesslog '$http_x_forwarded_for`$remote_addr`$proxy_add_x_forwarded_for`[$time_local]`"$request"`'
'$status`$body_bytes_sent`"$http_referer"`'
'"$http_user_agent"`"$request_time"`'
'$request_id`$upstream_response_time`$upstream_addr`$upstream_connect_time`$upstream_status';
2、在自定义的conf/web.conf 中配置nginx 的server
server{
listen 80;
server_name _;
access_log /home/admin/logs/nginx/web_access.log accesslog;
location ~*~/login/{
rewrite ^/login/(.*) /$1 break;
proxy_pass http://xx.xx.xx.xx;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
注:
header必须用减号“-”分隔单词,nginx里面会转换为对应的下划线“_”连接的小写单词。
1、nginx是支持读取非nginx标准的用户自定义header的,但是需要在http或者server下开启header的下划线支持:
underscores_in_headers on;
2、比如我们自定义header为X-Real-IP,通过第二个nginx获取该header时需要这样:
$http_x_real_ip; (一律采用小写,而且前面多了个http_,减号转成下划线)
学习参考:
模块参考:
3) https://blog.csdn.net/u011897301/article/details/72486278
4) https://www.cnblogs.com/faberbeta/p/nginx008.html
5) http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
6) https://blog.csdn.net/diyiday/article/details/80827437
7) https://juejin.cn/post/7003639916139642893
8) https://blog.csdn.net/weixin_34209851/article/details/91681937
9) https://blog.csdn.net/xiaoxiao_yingzi/article/details/92835704
配置参考: