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请求
      
      <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 也可以
         }
        
  • 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匹配 支持 不支持
  • 延申阅读
    haproxy
    nginx
    LVS

网关

nginx 具有丰富的插件,也可以执行lua 或 js脚本,可以通过脚本处理系统的限流,鉴权等任务,所以nginx 也经常作为网关服务,如openresty ,kong,阿里云的waf等都是基于nginx 二次开发的产品

  • 延伸阅读
    openresty
    kong

总结

nginx 是个强大的中间件,除了以上介绍的常用功能,只要你愿意,还可以用nginx做很多事情,比如直接在nginx 中编写业务,api 监控,日志分析,防盗链等等,但是常用的还是上面的功能,专业的工具做专业的事情,在其他方面,有对应领域更好的工具

你可能感兴趣的:(运维组件,nginx,运维,web开发)