2.2.1 Nginx高性能负载均衡器

目录

2.2.1.1 Nginx负载均衡

1、Nginx简介

    1.1、Nginx作为负载均衡的8个原因

2、正向代理和反向代理

    2.1、正向代理

    2.2、反向代理(Reverse Proxy)

    2.3、反向代理的作用

3、负载均衡原理

4、Nginx负载均衡的4种配置方案

    1、轮询(Round Robin)【默认】

    2、最少连接least_conn

    3、IP地址哈希ip_hash

    4、基于权重weight

2.2.1.2 代理缓存机制

1、Nginx缓存简介

        1.1、缓存文件放在哪里?

        1.2、如何指定哪些请求被缓存?

        1.3、缓存的有效期是多久?

        1.4、对于某些请求,是否可以不走缓存?

2.2.1.3 通过Lua拓展Nginx

1、ngx_lua模块

2、协程(Coroutine)

3、Nginx进程模型

4、HTTP请求处理11个阶段

5、ngx_lua指令

6、OpenResty

7、ngx_lua指令示例

    7.1、content_by_lua

2.2.1.4 高性能Nginx最新实践

1、Nginx监听端口

2、Nginx虚拟主机

3、Nginx配置location

4、Nginx常规配置

    4.1、定义环境变量

    4.2、嵌入其他配置文件

    4.3、pid文件

    4.4、Nginx worker进程运行的用户和用户组

    4.5、指定Nginx worker进程可以打开的最大句柄描述符个数

    4.6、限制信号队列

5、Nginx高性能配置

    5.1、nginx worker进程个数

    5.2、绑定Nginx worker进程到指定的CPU内核

    5.3、SSL硬件加速

    5.4、Nginx worker进程优先级设置

6、Nginx事件配置

    6.1、是否打开accept锁

    6.2、使用accept锁后到真正建立连接之间的延迟时间

    6.3、批量建立新连接

    6.4、选择事件模型(这个使用最多)

    6.5、每个worker的最大连接数

7、Nginx事件模型

8、Nginx配置示例


2.2.1.1 Nginx负载均衡

1、Nginx简介

    Nginx是一款轻量级的web(静态)服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD协议下发行,几乎可以在所有操作系统中运行。

Nginx做web服务器:比如Html解析、JS静态文件解析......
        由俄罗斯程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站、搜索引擎Rambler使用。
    特点占有内存少、高性能、高并发性(最初用于解决C10K问题,现在可以C100K)

主要用epoll方式

C10K:C-----Concurrent(并发),10K-----一万,C10K-----并发1万
        据统计,世界上最繁忙的网站中有11.48%使用Nginx作为服务器或者代理服务器

    1.1、Nginx作为负载均衡的8个原因

        高并发连接、内存消耗少配置文件非常简单、成本低廉、
        支持Rewrite重写规则、内置的健康检查功能、节省带宽、稳定性高

    Nginx的强的功能是:反向代理

2、正向代理和反向代理

    2.1、正向代理

        类似一个跳板机,代理访问外部资源

    2.2、反向代理(Reverse Proxy)

        实际运行方式是指以代理来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,
        并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器

    2.3、反向代理的作用

        1、保证内网的安全

            可以使用反向代理提供WAF功能,阻止web攻击。
            通常将反向代理作为公网访问地址,Web服务器放在内网

        2、负载均衡

            通过反向代理服务器来优化网站的负载

3、负载均衡原理

    可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机和某台服务器闲置的情况。
    负载均衡的前提:要2台以上的服务器才能实现

4、Nginx负载均衡的4种配置方案

    1、轮询(Round Robin)【默认

        根据Nginx配置文件中的顺序,依次把客户端的Web请求分发到不同的后端服务器上。
    注意事项
        1、默认配置就是轮询策略;
        2、nginx负载均衡支持http和https协议,只需要修改proxy_pass后协议即可;
        3、nginx支持FastCGI、uwsgi、SCGI、memcached的负载均衡,
            只需将proxy_pass改为fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass即可
        4、此策略适合服务器配置相当,无状态且短平快的服务使用。

    2、最少连接least_conn

        Web请求会被转发到连接数最少的服务器上
    注意事项
        1、最少链接负载均衡通过lease_conn指令定义
        2、此负载均衡策略适合请求处理时间长短不一,造成服务器过载的情况

    3、IP地址哈希ip_hash

        前述的两种负载均衡方案中,同一客户端连续的Web请求可能会被分发到不同的后端服务器进行处理,
            因此如果涉及到会话Session,那么会话会比较复杂。
        常见的是基于数据库的会话持久化。
        要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。
            这样的话,同一客户端连续的Web请求都会被分发到同一服务器进行处理
    注意事项
        1、ip哈希负载均衡使用ip_hash指令定义
        2、nginx使用请求客户端的ip地址进行哈希计算,确保使用同一个服务器响应请求
        3、此策略适合有状态服务,eg:session

    4、基于权重weight

        基于权重的负载均衡即Weighted Load Balancing,这种方式下,我们可以配置Nginx把请求更多地分发到高配置的后端服务器上,
        把相对较少的请求分发到低配服务器。
    注意事项
        1、权重负载均衡需要使用weight指令定义
        2、权重越高分配到需要处理的请求越多
        3、此策略可以与最少链接负载、ip哈希策略结合使用
        4、此策略比较适合服务器的硬件配置差别比较大的情况

2.2.1.2 代理缓存机制

1、Nginx缓存简介

    nginx的http_proxy模块,可以实现类似于Squid的缓存功能。
        Nginx对客户已经访问过的内容在Nginx服务器本地建立副本,这样在一段时间内再次访问改数据,
    就不需要通过Nginx服务器再次向后端服务器发出请求,所以能够减少Nginx服务器与后端服务器之间的网络流量,
    减轻网络拥塞,同时还能减小数据传输延迟,提高用户访问速度。
        同时,当后端服务器宕机时,Nginx服务器上的副本资源还能够回应相关的用户请求,这样能够提高后端服务器的鲁棒性。
鲁棒性:也叫“健壮性”(Robustness),是指一个计算机系统在执行过程中处理错误,或者算法在遭遇输入、运算等异常时继续正常运行的能力

    对于缓存,的4个问题:

        1.1、缓存文件放在哪里?

            proxy_cache_path:Nginx使用该参数指定缓存位置
            proxy_cache:该参数为之前指定的缓存名称
            proxy_cache_path有两个必填参数:
                第一个参数为缓存目录
                第二个参数keys_zone指定缓存名称和占用内存空间的大小

        1.2、如何指定哪些请求被缓存?

            1、Nginx默认会缓存所有get和head方法的请求结果,缓存的key默认使用请求字符串
            2、自定义key
                eg:proxy_cache_key "$scheme$request_method$request_uri";
            3、指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存
                eg:proxy_cache_min_uses 5;
            4、指定哪些方法的请求被缓存
                eg:proxy_cache_methods GET HEAD POST;

        1.3、缓存的有效期是多久?

            默认情况下,缓存内容是长期存留的,除非缓存的总量超出限制。
                eg:
                    响应状态码为200、302时,10分钟有效:proxy_cache_valid 200 302 10m;
                    对应任何状态码,5分钟有效:proxy_cache_valid any 5m;

        1.4、对于某些请求,是否可以不走缓存?

            proxy_cache_bypass:该指令响应来自原始服务器而不是缓存
                eg:proxy_cache_bypass $cookie_nocache $arg_nocache$arg_commet;
            如果任何一个参数值不为空,或者不等于0,nginx就不会查找缓存,直接进行代理转发
        

            网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,
                默认为private。其作用根据不同的重新浏览方式分为以下几种情况

web服务器响应nginx的响应头“Cache-control”为以下值时,对应的缓存方式

2.2.1.3 通过Lua拓展Nginx

1、ngx_lua模块

    1、Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。
    2、ngx_lua模块通过将lua解释器集成进Nginx,可以采用lua脚本实现业务逻辑。
        该模块具备以下特性:
            1、高并发、非阻塞的处理各种请求。
            2、Lua内建协程,这样就可以很好的将异步回调转换成顺序调用的形式。
            3、每个协程都有一个独立的全局环境(变量空间),继承于全局共享的、只读的"comman data"。
    3、得益于Lua协程的支持,ngx_lua在处理10000个并发请求时只需要很少的内存。
        根据测试,ngx_lua处理每个请求只需要2KB的内存,如果使用LuaJIT则会更少。
    4、ngx_lua非常适合用于实现可扩展的、高并发的服务

2、协程(Coroutine)

    协程类似一种多线程,协程与多线程的一些区别有:
        1、协程并非os线程,所以创建、切换开销比线程相对要小;
            os线程:操作系统线程
            操作系统分进程、线程:进程是资源分配的基本单位,线程是资源调度的基本单位
        2、协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。
            线程:线程可能会在用户进程、内核进程之间切换
        3、多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,
            只有当一个协程主动放弃执行权,另一个协程才能获取执行权,所以在某一瞬间,多个协程间只有一个在运行
        4、由于多个协程时只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。
        5、多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的
    Nginx的每个Worker进程都是在epoll或kqueue这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。
        这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但依然能保证高并发能力

3、Nginx进程模型

    1、Nginx采用多进程模型,单Master---多Worker,Master进程主要用来管理Worker进程。
    2、Worker进程采用单线程、非阻塞的事件模型(Event Loop,事件循环)来实现端口的监听及客户端请求的处理和响应,
        同时Worker还要处理来自Master的信号。Worker进程个数一般设置为机器CPU核数。
    3、Master进程具体包括如下4个主要功能:
        (1)、接收来自外界的信号
        (2)、向各worker进程发送信号
        (3)、监控worker进程的运行状态
        (4)、当worker进程退出后(异常退出),会自动重新启动新的worker进程

4、HTTP请求处理11个阶段

 

5、ngx_lua指令

    ngx_lua属于nginx的一部分,它的执行指令都包含在nginx的11个步骤之中了,相应的处理阶段可以做插入式处理,
        即可插拔式架构,不过ngx_lua并不是所有阶段都会运行的;
        另外指令可以在http、server、server if、location、location if几个范围进行配置:

ngx_lua指令所处阶段及使用范围的说明

6、OpenResty

    1、概念
        OpenResty是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。
        用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。
    2、工作原理
        OpenResty通过汇聚各种设计精良的Nginx模块(主要由OpenResty团队自主开发),从而将Nginx有效地变成一个强大的通用Web应用平台。
        这样,Web开发人员和系统工程师可以使用Lua脚本语言调动Nginx支持的各种C以及Lua模块,
            快速构造出足以胜任10K乃至1000K以上单机并发连接的高性能Web应用系统。
    3、目标
        OpenResty的目标是让你的Web服务直接跑在Nginx服务内部,充分利用Nginx的非阻塞I/O模型,
            不仅仅对HTTP客户端请求,甚至于对远程后端(如:MySQL、PostgreSQL、Memcached、Redis等)都进行一致的高性能响应。

有了Lua以后,Nginx具备了动态脚本功能、动态计算、可以访问数据库,将Nginx变成了一个业务服务器了

7、ngx_lua指令示例

    7.1、content_by_lua

        内容处理器,接收请求处理并输出响应
            该指令工作在Nginx处理流程的content阶段,即内容产生阶段,是所有请求处理阶段中最为重要的阶段,
        因为这个阶段的指令通常是用来生成HTTP响应内容的;
        输出:
            $ curl http://127.0.0.1
            $ Hello,world

1、配置content_by_lua输出Hello world
2、异步输出Hello world
3、读取请求参数
4、通过lua在nginx访问redis
中国人开发的,更多示例参考OpenResty官网:http://openresty.org/cn/ 

2.2.1.4 高性能Nginx最新实践

1、Nginx监听端口

    基本语法:listen address:port
    默认:listen 80
    作用:listen参数决定Nginx服务器如何监听端口。在listen后可以加IP地址,端口和主机名,非常灵活。
    eg:
        listen 127.0.0.1:8000;
        listen 127.0.0.1;//默认80端口
        listen 8000;//listen *:8000;//listen licalhost:8000;
    扩展语法:listen address:port [default(deprecated in in 0.8.21)|default_server|[backlog=num|rcvbuf=size|sndbuf=size|accept_filter=filter|deferred|bind|ipv6only=[on|off]|ssl]]
listen可用参数的意义

2、Nginx虚拟主机

3、Nginx配置location

    语法:location[=|~*|^~|@]/uri/{...}
    配置块:server
    详情:location会尝试根据用户请求中的uri来匹配上面的uri表达式,
          如果可以匹配,就选择location块中的配置来处理用户请求。当然,匹配方式是多样的。
         1、= /uri表示完全匹配
         2、~ /uri表示匹配URI时,大小写敏感
         3、~* /uri表示匹配URI时,忽略大小写
         4、^~ /uri表示匹配URI时,只需要其前半部分匹配即可
         5、/uri不带任何修饰符,也表示前缀匹配,但是在正则匹配之后
         6、/通用匹配,任何未匹配到其它locatin的请求都会匹配到,相当于switch中的default
    注意location是有顺序的,如果一个请求有可能被多个location匹配,实际上这个请求会被第一个location处理
    最后location / {}会处理所有的请求

4、Nginx常规配置

    4.1、定义环境变量

        语法:evn VAR|VAR=VALUE
        作用:用户可以直接设置操作系统上的环境变量
        eg:evn TESTPATH=/tmp

    4.2、嵌入其他配置文件

        语法:include /path/file;
        作用:可以把其他配置文件引入进来,
              路径可以使用:绝对路径、相对路径、含有通配符*

    4.3、pid文件

        语法:pid path/file
        默认:pid logs/nginx.pid
        作用:保存master进程ID的pid文件存放路径

    4.4、Nginx worker进程运行的用户和用户组

        语法:user username [groupname]
        默认:user nobody nobody
        作用:master进程fork出的进程在哪个用户和用户组下

    4.5、指定Nginx worker进程可以打开的最大句柄描述符个数

        语法:worker_rlimit_nofile limit
        作用:设置一个worker可以打开的最大句柄数(一个worker可处理的最大连接数)

    4.6、限制信号队列

        语法:worker_rlimit_sigpending limit
        作用:设置每个用户发往Nginx的信号队列的大小。也就是说,当某个用户的信号队列满了,这个用户再发送的信号量就会被丢掉

5、Nginx高性能配置

    5.1、nginx worker进程个数

        语法:worker_processes number
        默认:worker_processes 1
        作用:在master_worker运行方式下,定义worker进程的个数。worker进程的数量会直接影响性能。
              每个worker都是单线程的进程,他会调用各个模块来实现各种功能。
              如果确定这些模块不会出现堵塞式调用,那么进程数可以和CPU核心数一样;
              反之,则稍少一些。

    5.2、绑定Nginx worker进程到指定的CPU内核

        语法:worker_cpu_affinity cpumask [cpumask...]
        作用:假设每个worker都是很繁忙的,如果多个进程都在抢同一个CPU,那么就会出现同步问题。
              反之,如果每个worker进程独享一个CPU,就实现了完美的并发。
        eg:worker_processes 4;
            worker_cpu_affinity 1000 0100 0010 0001;

    5.3、SSL硬件加速

        语法:ssl_engine device
        作用:如果服务器上有SSL硬件加速设备,那么就可以进行配置以加快SSL协议的处理速度。
              用户可以用OpenSSL提供的命令来查看是否有SSL硬件加速设备:openssl engine -t

    5.4、Nginx worker进程优先级设置

        语法:worker_priority nice
        默认:worker_priority 0
        作用:在Linux和Unix中,当许多进程都处于可执行状态时,按照优先级来决定本次内核选择哪一个进程执行。
              进程分配的CPU时间片大小也与优先级有关,优先级越高,时间片越长
                (eg:在默认情况下,最小时间片是5ms,最大则有800ms)。
              优先级由静态优先级和内核根据进程的执行情况所做的动态调整(目前只有+-5的调整)共同决定。
              nice是进程的优先级,他的取值范围是-20 ~ +19,
                -20是最高优先级
                +19是最低优先级
              不建议把nice的值设为比内核进程(t通常为-5)还要小。

6、Nginx事件配置

    6.1、是否打开accept锁

        语法:accept_mutex [on|off]
        默认:accept_mutex on
        作用:accept_mutex是Nginx的负载均衡锁。这把锁可以让多个worker进程轮流的,序列化的与新的客户端建立TCP连接。
              accept锁默认是打开的,如果关闭它,那么建立TCP连接的耗时会更短,但不利于负载均衡,因此不建议关闭。

    6.2、使用accept锁后到真正建立连接之间的延迟时间

        语法:accept_mutex_delay Nms
        默认:accept_mutex_delay 500ms
        作用:在使用accept锁后,同一时间只有一个worker进程能够取到accept锁。这个accept锁不是堵塞锁,
              如果取不到会立刻返回。如果只有一个worker进程试图取锁而没有取到,
              他至少要等待accept_mutex_delay定义的时间才能再次试图取锁。

    6.3、批量建立新连接

        语法:multi_accept[on|off]
        默认:multi_accept off
        作用:当事件模型有新连接时,尽可能的对本次调度中客户端发起的所有TCP请求都建立连接。

    6.4、选择事件模型(这个使用最多)

        语法:use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport]
        默认:Nginx会选出最合适的时间模型
        作用:对于Linux系统,可供选择的事件驱动模型有:
                poll、select、epoll三种,一般来说,epoll是性能最高的

    6.5、每个worker的最大连接数

        语法:worker_connections number
        作用:定义每个worker进程可以同时处理的最大连接数

7、Nginx事件模型

        epoll是Linux内核为处理大批量文件描述符而作了改进的poll,
    是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中
    只有少量活跃的情况下的系统CPU利用率。
        优点:
            1、支持一个进程打开大数目的socket描述符
            2、IO效率不随FD(文件描述符)数目增加而线性下降
            3、使用mmap加速内核与用户空间的消息传递

8、Nginx配置示例

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值