nginx 实用基础汇总
nginx 基础点汇总
nginx 是IT系统建设中,常用的中间件之一,本篇梳理nginx 常用的功能点
静态资源服务
nginx ,apache, tomcat 是常见的web引擎,都可以用来做http网站的静态资源服务
反向代理
nginx 除了基本的web 静态服务功能,也支持反向代理,通过反向代理,屏蔽服务器的信息
作为反向代理,nginx 的配置项简化如下:
server {
listen 9001; #监听的端口
server_name *.sherlocked93.club; # 请求目标的ip 或域名
location ~ /edu/ { # 路由匹配,支持正则
proxy_pass http://127.0.0.1:8080; # 将请求转发到对应的后端服务器
}
location ~ /vod/ {
proxy_pass http://127.0.0.1:8081;
}
}
以上只是简化的反向代理配置,nginx 本身提供了丰富的配置项 和 插件库,用来丰富代理规则和处理请求异常的情况,以下介绍几种常见的问题处理
-
处理跨域问题
跨域问题是常见的web 问题之一,由于浏览器的同源策略(同端口,同host,同协议)限制,浏览器默认不允许前端的js代码获取不同域下的响应,但可以通过以下方式解决- jsonp
jsonp script标签可以获取非同源资源的特性,通过回调的方式,将资源返回到前端,再执行回调解析获取想要的信息, 但是这只能处理get请求<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script type='text/javascript'> // 后端返回直接执行的方法,相当于执行这个方法,由于后端把返回的数据放在方法的参数里,所以这里能拿到res。 window.jsonpCb = function (res) { console.log(res) } </script> <script src='http://localhost:9871/api/jsonp?msg=helloJsonp&cb=jsonpCb' type='text/javascript'></script> </body> </html>
- iframe
iframe 可以加载其他源下的资源,可以通过在iframe中嵌套form表单形式,处理跨域请求 - cors
cors 是跨域资源共享的标准,cors将http请求分为两种,简单请求和非简单请求, 同时满足(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
-
简单请求
浏览器对于简单cors请求,会在头信息中加上一个Origin 字段,标记了本次请求来自哪个源,服务端会根据这个源的值,判断是否允许这次跨域请求,如果origin 指定的源不在服务端许可范围内,服务端会返回一个正常的http响应,浏览器会检测到响应的头信息中没有
Access-Control-Allow-Origin
字段,从而抛出一个跨域错误如果origin 指定的域名在许可范围内,服务端返回的响应中,会多出几个头部字段
Access-Control-Allow-Origin: * # 它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求 Access-Control-Allow-Credentials: false # 是否允许发送cookie true时,origin 不能为* Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8
-
非简单请求
非简单请求在发送之前,会发送一次options预检请求,预检请求会在头部加上以下字段Origin: http://api.xxx.com # 标记请求来自哪个源 Access-Control-Request-Method: PUT # 浏览器请求的方法 Access-Control-Request-Headers: X-Custom-Header # 浏览器会额外发送哪些头部字段
询问当前网页所在的域名是否在服务器许可名单中,以及可以使用哪些http 方法和头信息,只有得到服务端的肯定响应,浏览器才会发送正式的XMLHttpRequest 请求,否则报错
服务端收到预检请求后,检查上面三个字段提供的信息,是否符合跨域请求的配置,从而做出响应。
如果服务器否定了预检请求,会返回一个正常的http响应,浏览器检测到响应没有origin相关的信息,就会抛出一个跨域请求的错误
如果服务端通过了预检请求,会响应如下字段
Access-Control-Allow-Origin: * # 允许该源跨域 Access-Control-Allow-Methods: GET, POST, PUT # 服务端允许发送的方法 Access-Control-Allow-Headers: X-Custom-Header # 服务端支持的头部字段 Access-Control-Allow-Credentials: true # 是否允许发送cookie Access-Control-Max-Age: 1728000 # 本次预检请求的有效时间
以后每次发送跨域请求,就和简单请求一样,会有一个origin头部字段,服务端的回应 也都会有一个
Access-Control-Allow-Origin
字段了解了上面的cors的处理过程,可通过服务端配置允许跨域来解决跨域问题,一般的http服务中,可以通过nginx 反代 或者 配置服务端如下参数来解决
add_header 'Access-Control-Allow-Origin' $http_origin; # 全局变量获得当前请求origin,带cookie的请求不支持* add_header 'Access-Control-Allow-Credentials' 'true'; # 为 true 可带上 cookie add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # 允许请求方法 add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers; # 允许请求的 header,可以为 * add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Max-Age' 1728000; # OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求 add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; # 200 也可以 }
-
- jsonp
-
gzip压缩数据
nginx 提供了gzip压缩功能,可以通过nginx压缩数据,浏览器解压数据,减少数据传输过程中的带宽占用,提高网站性能
已支持数据解压缩的浏览器,在请求头中会加上
Encoding: gzip
(有可能会有多个压缩格式) 字段,告诉服务端,自己支持哪些解压方式,服务端在响应头中会加上content-encoding: gzip
来通知浏览器,数据采用了哪种压缩方式,浏览器通过该压缩方式进行解压,得到源数据。在这个过程中,解压缩分别在客户端和服务端进行,通过两端的cpu资源来换取数据传输过程中的流量节约
-
延伸阅读
cors
负载均衡
负载均衡是通过一定的算法,将流量分发到 同一个服务集群的不同服务器上,负载均衡又分为软负载和硬负载,lvs和f5就是软硬负载的代表,一般负载均衡和反向代理是一起使用的
nginx ,haproxy,lvs 都是软负载的常见中间件,以下是对三者的分析
负载算法 | 七层/四层 | 健康检查 | 动静分离 | |
---|---|---|---|---|
nginx | 权重,连接最少,随机,ip_hash,轮询 , url_hash | nging 工作在7层,但可通过插件支持4层 | 支持基于ip 端口的健康检查 | 支持动静分离 ,缓存静态资源 |
haproxy | 基于权重的轮询,最少链接,ip_hash, uri_hash, cookie_hash | 七层和四层 | 支持健康检查 | 支持动静分离,但不可做web服务 |
lvs | 轮询,基于权重的轮询,源地址 hash,目标地址hash,最少链接 | 工作在四层,仅做分发, 不支持正则和URL匹配 | 支持 | 不支持 |
网关
nginx 具有丰富的插件,也可以执行lua 或 js脚本,可以通过脚本处理系统的限流,鉴权等任务,所以nginx 也经常作为网关服务,如openresty ,kong,阿里云的waf等都是基于nginx 二次开发的产品
总结
nginx 是个强大的中间件,除了以上介绍的常用功能,只要你愿意,还可以用nginx做很多事情,比如直接在nginx 中编写业务,api 监控,日志分析,防盗链等等,但是常用的还是上面的功能,专业的工具做专业的事情,在其他方面,有对应领域更好的工具