【Nginx】ngx_http_upstream_module

目录

0.http_upstream的用途和意义

1.一些概念

2.扩展方法

3.ngx_http_upstream_module

4.指定上游服务器

5.Round-Robin相关

6.对上游服务使用keepalive长连接相关

7.resolver相关

8.ip_hash

9.hash与一致性hash

10.least_conn

11.zone

12.upstream模块提供的变量(不含cache)


 

 

0.http_upstream的用途和意义

官方给出的用途:
The ngx_http_upstream_module module is used to define groups of servers that can be 
referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, 
and grpc_pass directives.
翻译:
ngx_http_upstream_module这个模块用来定义可以被 proxy_pass, fastcgi_pass, uwsgi_pass, 
scgi_pass, memcached_pass以及grpc_pass等指令所引用的服务集群.

意义:
   Nginx模块一般被分成三大类:handler,filter和upstream.利用handler,filter这两个模块,可以使
Nginx轻松完成任何单机工作.数据量激增时upstream模块,将使Nginx跨越单机的限制,完成网络数据的接
收,处理和转发.数据转发功能,为Nginx提供了跨越单机的横向处理能力,使 Nginx摆脱只能为终端节点提
供单一功能的限制,而使它具备了网路应用级别的拆分,封装和整合的战略功能.在云模型大行其道的今天,
具有数据转发能力的Nginx是构建一个网络应用的关键组件。



1.一些概念

1.反向代理与反向代理服务器
反向代理的方向与正向代理相反,指代表外部网络用户向内部服务器发出请求,即接收来自Internet上用
户的连接请求,并将这些请求转发给内部网络上的服务器,然后将从内部服务器上得到的响应返回给
Internet上请求连接的客户:执行反向代理服务的服务器称为反向代理服务器,反向代理服务器对外部用
户表现为一个服务器.

2.负载均衡(load balance)
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企
业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务.

3.缓存
所谓的缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创
建新的重复的实例。这样做可以减少系统开销,提高系统效率。
(1)通过文件缓存;顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格
式还是其它文件格式;
(2)内存缓存;也就是创建一个静态内存区域,将数据存储进去,例如我们B/S架构的将数据存储在
Application中或者存储在一个静态Map中。
(3)本地内存缓存;就是把数据缓存在本机的内存中。
(4)分布式缓存机制;可能存在跨进程,跨域访问缓存数据
对于分布式的缓存,此时因为缓存的数据是放在缓存服务器中的,或者说,此时应用程序需要跨进程的去
访问分布式缓存服务器。


缓存也可以分类为:
(1)时间缓存;
(2)空间缓存(加速预期结果).

2.扩展方法

AKF扩展你模型:
(1)X轴扩展:基于Round-Robin或者least-connected算法分发请求,服务是无状态的,
   无论启动多少服务,它们都是同等地为用户请求服务,这种扩展成本最低,
   也是我们常常所说的水平扩展.
(2)Y轴扩展:从功能上进行拆分,原先由一台应用服务处理的功能分为两台或更多台,处理不同的API,
   在Nginx可以通过location配置,有一些功能代理到server1中,另外一些功能代理到server2
   中,这种往往需要改代码重构,成本较大,但能够解决数据量上升问题.
(3)Z轴扩展:基于用户的信息进行扩展,比如说基于用户的IP地址和CON的关系,当我们发现某些IP地址
   比较靠近某个CDN中心,我们就把这样的请求引流到这个CDN上.为了分离减小数据的容量,可以根据
   username将其引流到固定的集群上.


可以组合使用这些扩展方法.

3.ngx_http_upstream_module

Module ngx_http_upstream_module的官方学习网址,可根据这个去系统学习
http://nginx.org/en/docs/http/ngx_http_upstream_module.html

Example Configuration
Directives
     upstream
     server
     zone
     state
     hash
     ip_hash
     keepalive
     keepalive_requests
     keepalive_timeout
     ntlm
     least_conn
     least_time
     queue
     random
     resolver
     resolver_timeout
     sticky
     sticky_cookie_insert
Embedded Variables
     $upstream_addr
     $upstream_bytes_received
     $upstream_bytes_sent
     $upstream_cache_status
     $upstream_connect_time
     $upstream_cookie_name
     $upstream_header_time
     $upstream_http_name
     $upstream_queue_time
     $upstream_response_length
     $upstream_response_time
     $upstream_status
     $upstream_trailer_name

4.指定上游服务器

利用upstream和server完成对上游服务器的配置

upstream backend {
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

注意:
upstream的作用是指定一组上游服务器,其中,地址可是域名,IP地址或者unix socket
的地址,可以在域名或者IP地址后面加端口,如果不加端口,那么默认使用80端口.

upstream中server的通用参数:
backup 指定当前server为备份服务,仅仅当非备份server不可用的时候,请求才会转发到该server.
down   标识某台服务已经下线,不在服务,相当于一个注释,方便我们管理

5.Round-Robin相关

全称是:
加权Round-Robin负载均衡算法
功能:
以加权轮训的方式访问server指令指定的上游服务.
这个算法默认集成在Nginx的upstream模块,一般情况下没有办法对齐做出添加或移除.


名词解释:
加权:服务器的配置不均衡,有的4核8G,有的8核16G,配置高的能够处理的QPS更强一些,通过权重来标
识这台服务不同于其它服务,可以给更大的权重,此时Round-Robin就可以按照权重值将更多的请求发给
权重更大的服务器.
Round-Robin:依次轮训,挨个进行.


与Round-Robin相关的指令:
(1)weight
(2)max_conn
(3)max_fails
(4)fail_timeout
具体的含义可以看下图.


配置示例:
upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;

    server backup1.example.com  backup;
}

【Nginx】ngx_http_upstream_module_第1张图片

6.对上游服务使用keepalive长连接相关

功能:通过复用连接,降低Nginx与上游服务器建立,关闭连接的消耗,提升吞吐量的同时降低时间延迟.
模块:ngx_http_upstream_keepalive_module是默认编入到Nginx中的,如果不想编进去可以用
      --without-http_upstream_keepalive_module对这个模块进行移除.
(/home/muten/module/nginx-1.13.7中执行./configure --help |more 搜索http_upstream_keepalive_module可验证)


对上游连接的http头部设定:
proxy_http_version 1.1;
proxy_set_header Connection "";

因为http1.0协议是不支持长连接的,为了防止用户发来的是http1.0,我们需要重置http版本,将其
置成1.1,这样就可以一直使用keep_alive长连接;
为了防止用户的Connection头部给我们传递的是Close而不是Keepalive,我们主动设置向上游发送
的connection.



关于upstream_keepalive的指令:
(1)keepalive

Activates the cache for connections to upstream servers.
The connections parameter sets the maximum number of idle keepalive connections to 
upstream servers that are preserved in the cache of each worker process. When this 
number is exceeded, the least recently used connections are closed.
表示上游服务器中最多保持多少个用于keepalive请求的空闲的连接.
这个命令会促使上游服务器中每个worker进程中开辟出来一块缓存用于keepalive连接,
当超过这个数字的时候,将会利用LRU算法将一些连接关闭.

Syntax:	keepalive connections;
Default:	—
Context:	upstream
This directive appeared in version 1.1.4.


(2)keepalive_requests
Sets the maximum number of requests that can be served through one keepalive connection. 
After the maximum number of requests is made, the connection is closed.

Closing connections periodically is necessary to free per-connection memory allocations. 
Therefore, using too high maximum number of requests could result in excessive memory 
usage and not recommended.


Syntax:	keepalive_requests number;
Default:	
keepalive_requests 100;
Context:	upstream
This directive appeared in version 1.15.3.


(3)keepalive_timeout
Sets a timeout during which an idle keepalive connection to an upstream server will stay
 open.
如果一个连接上60秒还没有新的请求,就关闭这个连接.

Syntax:	keepalive_timeout timeout;
Default:	
keepalive_timeout 60s;
Context:	upstream
This directive appeared in version 1.15.3.



Round-Robin算法的限制:
无法保证某一类请求只能由某一台服务器处理,只能做AKF算法模型中的X轴拓展(水平扩展).


测试水平负载均衡:
curl 192.168.118.177:8080

7.resolver相关

8.ip_hash

--without-http_upstream_hash_module disable ngx_http_upstream_hash_module
--without-http_upstream_ip_hash_module disable ngx_http_upstream_ip_hash_module
这两个模块默认被编入Nginx中.


用法:
Syntax:	ip_hash;
Default:	—
Context:	upstream
Specifies that a group should use a load balancing method where requests are distributed 
between servers based on client IP addresses. The first three octets of the client IPv4 
address, or the entire IPv6 address, are used as a hashing key. The method ensures that 
requests from the same client will always be passed to the same server except when this 
server is unavailable. In the latter case client requests will be passed to another 
server. Most probably, it will always be the same server as well.


功能:
以客户端的IP地址($remote_addr)作为hash算法的关键字,映射到特定的上游服务器中.
说明:
对IPV4地址使用前三个字节作为关键字,对IPV6则使用完整地址;
可以基于realip模块修改用于算法的IP地址.


IPv6 addresses are supported starting from versions 1.3.2 and 1.2.2.
If one of the servers needs to be temporarily removed, it should be marked with the down 
parameter in order to preserve the current hashing of client IP addresses.

Example:

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com;
}
Until versions 1.3.1 and 1.2.2, it was not possible to specify a weight for servers 
using the ip_hash load balancing method.



测试ip_hash负载均衡:
curl 192.168.118.177:8080

9.hash与一致性hash

http://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash


--without-http_upstream_hash_module disable ngx_http_upstream_hash_module
这个模块默认被编入Nginx中


Syntax:	hash key [consistent];
Default:	—
Context:	upstream
This directive appeared in version 1.7.2.


Specifies a load balancing method for a server group where the client-server mapping is 
based on the hashed key value. The key can contain text, variables, and their combinations. 
Note that adding or removing a server from the group may result in remapping most of the 
keys to different servers. The method is compatible with the Cache::Memcached Perl library.

If the consistent parameter is specified, the ketama consistent hashing method will be used 
instead. The method ensures that only a few keys will be remapped to different servers when 
a server is added to or removed from the group. This helps to achieve a higher cache hit 
ratio for caching servers. The method is compatible with the Cache::Memcached::Fast Perl 
library with the ketama_points parameter set to 160.

功能:
通过制定关键字作为hash key,基于hash算法映射到特定的上游服务器中,关键字中可以含有变量,字符串.



测试水平负载均衡和ip_hash负载均衡:
curl 192.168.118.177:8080

测试hash负载均衡:
curl 127.0.0.1:8080?username=xxxsdw
curl 127.0.0.1:8080?username=x
curl 127.0.0.1:8080?username=bbbbb



hash算法的问题:

假设选中上游server的算法:key%5
kye=5  ----> server 0;
kye=6  ----> server 1;
kye=7  ----> server 2;
kye=8  ----> server 3;
kye=9  ----> server 4;

(宕机或者扩容的时候,hash算法引起大量的路由变更,可能导致缓存大范围失效)
当我们出现一台server宕机或者扩容一台server,都会导致以前的key路由的目标server发生变化,
比如说server4挂了,
此时选中上游server的算法是:key%4
kye=5  ----> server 1;
kye=6  ----> server 2;
kye=7  ----> server 3;
kye=8  ----> server 0;
kye=9  ----> server 1;
可以发现以上5个key对应的server全部发生了变化,这样的结果会导致在上游服务有缓存的情况下,
缓存大量失效,特别是在我们在面向大流量的场景下,每一台server的缓存经常被命中会使得server
可以服务大量用户,由于我们更改了server的数量以及hash算法,会导致几乎所有的缓存都失效了,
这样就会引发恶性后果.

如何解决这个问题呢?一致性哈希算法帮我们做到了这个.
假设扩容前有4台server,把这4台server放在环上,任何一个key在计算之后都会有一个值,
我们把这4个结点(比如hash出来的全部是32位整型)均匀地放在这个环上,缓处理左右两边各
八分之一的key值.此时再扩容一个节点的时候,只会影响就近的基点,影响的范围就会少很多.
(还需探索举例测试)

一致性哈希算法能够帮助我们缓解由于宕机或者扩容时我们的路由不发生大规模的变化,当我们
的上游服务使用缓存的时候,不会导致大范围的缓存失效.它不能使得扩容或者宕机之后所有的
路由都不发生变化,但是能使得小范围的缓存失效而缓解由于扩容或宕机带来的问题.

对于Nginx使用hash一致性算法只要在hash key后面配置[consistent]即可.

10.least_conn

最小连接算法
使用的是upstream_least_conn模块

功能:
在所有上游服务器中,找出当前并发连接数最少的一个,将请求转发到它.
如果出现多个最少连接服务器的连接数都是一样的情况,使用round-robin算法.

模块:
ngx_http_upstream_least_conn_module,默认编入,
可通过--without-http_upstream_least_conn_module将其移除.


Syntax:	least_conn;
Default:	—
Context:	upstream
This directive appeared in versions 1.3.1 and 1.2.2.

Specifies that a group should use a load balancing method where a request is passed to the 
server with the least number of active connections, taking into account weights of servers. 
If there are several such servers, they are tried in turn using a weighted round-robin 
balancing method.


11.zone

使用共享内存是负载均衡策略对所有woker进程生效:upstream_zone模块

功能:
分享出共享内存,将其upstream模块定义的负载均衡策略数据,运行时每个上游服务器的状态数据存放到
共享内存上,以对所有nginx的worker进程生效.

模块:
stream_upstream_zone_module,默认编入nginx,
可通过--without-stream_upstream_zone_module禁用此模块.

Syntax:	zone name [size];
Default:	—
Context:	upstream
This directive appeared in version 1.9.0.

Defines the name and size of the shared memory zone that keeps the group’s configuration 
and run-time state that are shared between worker processes. Several groups may share the 
same zone. In this case, it is enough to specify the size only once.

Additionally, as part of our commercial subscription, such groups allow changing the group
 membership or modifying the settings of a particular server without the need of restarting 
nginx. The configuration is accessible via the API module (1.13.3).

Prior to version 1.13.3, the configuration was accessible only via a special location 
handled by upstream_conf.

12.upstream模块提供的变量(不含cache)

 

【Nginx】ngx_http_upstream_module_第2张图片

【Nginx】ngx_http_upstream_module_第3张图片

变量测试的配置示例:

worker_processes  1;  

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format varups '$remote_addr $upstream_connect_time $upstream_header_time $upstream_response_time'
                      '$upstream_response_length $upstream_bytes_received'
                      '$upstream_status $upstream_http_server $upstream_cache_status'
    proxy_cache_path /tmp/nginxcache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;    

    upstream local{
        server 127.0.0.1:8081;
        server 192.168.118.180:8082;
      }   
    sendfile        on;
    server {
        listen       8080;
        server_name localhost;
        access_log  logs/host.access.log  varups;
         location / { 
               proxy_set_header Host $host;
               proxy_set_header X-Real-IP $remote_addr;
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_pass http://local;
         }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

下面给出内嵌变量的access日志:

 

 【Nginx】ngx_http_upstream_module_第4张图片

 

你可能感兴趣的:(nginx,反向代理,负载均衡,Round-Robin)