Nginx实用整理

1. nginx 简述

    1.1Nginx是轻量级高并发HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现,优点: 

  • Nginx使用基于事件驱动架构,使得其可以支持数以百万级别的TCP连接
  • 丰富的第三方模块
  • 跨平台

    1.2Nginx 架构

     Nginx采用异步非阻塞【https://www.cnblogs.com/wxl-dede/p/5134636.html】,好处有:

  • 不需要创建线程,每个请求只占用少量的内存
  • 没有上下文切换,事件处理非常轻量

       nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。当然nginx也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是nginx的默认方式。

  master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

  worker进程则是处理基本的网络事件。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。

  worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致。更多的worker数,只会导致进程来竞争cpu资源了,从而带来不必要的上下文切换。而且,nginx为了更好的利用多核特性,具有cpu绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。

  【惊群现象】每个worker进程都是从master进程fork过来。在master进程里面,先建立好需要listen的socket之后,然后再fork出多个worker进程,这样每个worker进程都可以去accept这个socket(当然不是同一个socket,只是每个进程的这个socket会监控在同一个ip地址与端口,这个在网络协议里面是允许的)。一般来说,当一个连接进来后,所有在accept在这个socket上面的进程,都会收到通知,而只有一个进程可以accept这个连接,其它的则accept失败。

2. nginx 正向代理与反向代理

  正向代理:替客户客户端访问明确已知的服务端地址(客户端非常明确要访问的服务器地址,而服务器端只知道请求来自哪个代理服务器),正向代理模式屏蔽或者隐藏了真实客户端信息。

       正向代理的用途:
             (1)访问原来无法访问的资源,如Google
             (2) 可以做缓存,加速访问资源
             (3)对客户端访问授权,上网进行认证
             (4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

       反向代理:"它代理的是服务端,代服务端接收请求",主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息

       反向代理的作用:
              (1)保证内网的安全,通常将反向代理作为公网访问地址,Web服务器是内网
              (2)负载均衡,通过反向代理服务器来优化网站的负载

3. nginx 负载均衡

  3.1 算法(如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器)

  1. weight轮询(默认,常用):接收到的请求按照权重分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,Nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
  2. ip_hash(常用):每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。
  3. fair:智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是Nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块。
  4. url_hash:按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在Nginx作为静态服务器的情况下提高缓存效率。同样要注意Nginx默认不支持这种调度算法,要使用的话需要安装Nginx的hash软件包。

  3.2 配置

            在http节点里添加:

            #定义负载均衡设备的 Ip及设备状态 

            upstream myServer {   

                 server 127.0.0.1:9090 down; 
                 server 127.0.0.1:8080 weight=2; 
                 server 127.0.0.1:6060; 
                 server 127.0.0.1:7070 backup; 
           }

          在需要使用负载的Server节点下添加

          proxy_pass http://myServer;

          upstream 每个设备的状态:

          down 表示单前的server暂时不参与负载 
          weight  默认为1.weight越大,负载的权重就越大。 
          max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误 
          fail_timeout:max_fails 次失败后,暂停的时间。 
          backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

4. nginx 常用配置规则

     server {
        listen       80;
        server_name  localhost;
        charset utf-8;
        client_max_body_size 100M; 
        client_body_buffer_size 1024M; 
        fastcgi_intercept_errors on;
        location / {
                        proxy_pass https://127.0.0.1/elastic/;
                        proxy_set_header Host $host;
                        proxy_http_version 1.1;
                        proxy_set_header Upgrade $http_upgrade;
                        proxy_set_header Connection "upgrade";
                        proxy_set_header X-real-ip $remote_addr;
                        proxy_set_header X-Forwarded-For $remote_addr;
        }
     }

 nginx location 配置规则:

  待完善...

5. nginx 进阶(openResty)【https://blog.csdn.net/y4x5M0nivSrJaY3X92c/article/details/81517950

    OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台。我们知道开发 Nginx 的模块需要用 C 语言,同时还要熟悉它的源码,成本和门槛比较高。国人章亦春把 LuaJIT VM 嵌入到了 Nginx 中,使得可以直接通过 Lua 脚本在 Nginx 上进行编程,同时还提供了大量的类库(如:lua-resty-mysql lua-resty-redis 等),直接把一个 Nginx 这个 Web Server 扩展成了一个 Web 框架,借助于 Nginx 的高性能,能够快速地构造出一个足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,worker 真正负责对客户端的请求处理,master 仅负责一些全局初始化,以及对 worker 进行管理。在 OpenResty 中,每个 worker 中有一个 Lua VM,当一个请求被分配到 worker 时,worker 中的 Lua VM 里创建一个 coroutine(协程) 来负责处理。协程之间的数据隔离,每个协程具有独立的全局变量 _G。

 

   1. OpenResty 请求处理流程,由于 Nginx 把一个请求分成了很多阶段,第三方模块就可以根据自己的行为,挂载到不同阶段处理达到目的。OpenResty 也应用了同样的特性。不同的阶段,有不同的处理行为,这是 OpenResty 的一大特色。OpenResty 处理一个请求的流程参考下图(从 Request start 开始)

   2. OpenResty 变量

   2.1 全局变量 

      在 OpenResty 中,只有在 init_by_lua* 和 init_worker_by_lua* 阶段才能定义真正的全局变量。因为在其他阶段,OpenResty 会设置一个隔离的全局变量表,以免在处理过程中污染了其他请求。即使在上述两个阶段可以定义全局变量,也尽量避免这么做。全局变量能解决的问题,用模块变量也能解决,而且会更清晰,干净。

   2.2 模块变量

    定义在 Lua 模块中的变量称为模块变量。Lua VM 会将 require 进来的模块换成到 package.loaded table 里,模块里的变量都会被缓存起来,在同一个 Lua VM下,模块中的变量在每个请求中是共享的,这样就可以避免使用全局变量来实现共享了。

  2.3 本地变量

   跟全局变量,模块变量相对,我们这里姑且把 *_by_lua* 里定义的变量称为本地变量。本地变量仅在当前阶段有效,如果需要跨阶段使用,需要借助 ngx.ctx 或者附加到模块变量里

5.1 jwt + openResty 【https://www.jianshu.com/p/66d5163b9e99

posted @ 2019-07-10 13:50  渊源、  阅读(288)  评论(0编辑  收藏  举报