Nginx TCP和UDP负载均衡

1    介绍

负载均衡是指有效的经过多个后端服务器分发网络流量。正则表达式

Nginx能代理和负载均衡TCP、UDP通讯。TCP(传输控制协议)、UDP(用户数据包协议)是许多流行应用程序和服务的协议,例如LDAP、MySQL和RTMP使用TCP协议,DNS、syslog和RADIUS。算法

2    须要

  • 使用--with-stream配置标记构建最新Nginx,或最新的Nginx+(不须要额外构建步骤)数据库

  • 应用程序、数据库或服务基于TCP或UDP通讯后端

  • Upstream服务器运行相同的应用程序、数据库或服务实例缓存

3    配置反向代理

首先,你须要配置反向代理,所以,Nginx转发来自客户端的TCP链接或UDP数据包到upstream组或一个代理服务器。服务器

打开Nginx配置文件并执行如下步骤:网络

  • 建立顶级stream {}块app

stream {负载均衡

...tcp

}

 在顶级stream {}上下文中为每一个虚拟主机定义一个或多个server {}配置块。

  • 在每一个server {}配置块中包括listen指令定义服务器监听的IP地址和/或端口。对于UDP通讯,也包括udp参数。TCP是stream上下文的默认协议:

stream {

    server {

        listen 12345;

        ...

    }

    server {

        listen 53 udp;

        ...

    }

    ...

}

  •  包括proxy_pass指令定义代理服务器或upstream组

stream {

    server {

        listen     12345;

        proxy_pass stream_backend;

    }

 

    server {

        listen     12346;

        proxy_pass backend.example.com:12346;

    }

 

    server {

        listen     53 udp;

        proxy_pass dns_servers;

    }

    ...

}

  •  可选,若是你的代理服务器多个网络接口,你能配置Nginx选择源IP地址链接到upstream服务器。代理服务器在Nginx后面配置为从特定IP网络或IP地址范围接收链接是有用的。

 指定proxy_bind指令和必要的网络接口的IP地址:

stream {

    ...

    server {

        listen     127.0.0.1:12345;

        proxy_pass backend.example.com:12345;

        proxy_bind 127.0.0.1:12345;

    }

}

  • 可选,你能调整两个内存缓存,Nginx能从客户端和upstream链接放入数据。若是有一个体积小的数据,减小缓存能够节约内存资源。若是有大量数据,增长缓存大小减小套接字读写操做次数。一旦在一个链接接收到数据,Nginx读取它并在其它链接转发。缓存使用proxy_buffer_size指令控制:

stream {

    ...

    server {

        listen            127.0.0.1:12345;

        proxy_pass        backend.example.com:12345;

        proxy_buffer_size 16k;

    }

}

4    配置TCP和UDP负载均衡

为了配置负载均衡:

一、建立服务器组,或upstream组将负载均衡通讯。定义一个或多个upstream {}配置块在顶级steam {}上下文,设置upstream组的名字,例如,TCP服务器steam_backed和UDP服务器dns_servers:

stream {

    upstream stream_backend {

        ...    

    }

 

    upstream dns_servers {

        ...    

    }

    ...

}

二、在upstream组中填充upstream服务器。upstream {}块中,为每一个upstream服务器添加server指令,指定IP地址或主机名(解析多个IP地址)和必须的端口号。 

 stream {

    upstream stream_backend {

        server backend1.example.com:12345;

        server backend2.example.com:12345;

        server backend3.example.com:12346;

        ...

    }

    upstream dns_servers {

        server 192.168.136.130:53;

        server 192.168.136.131:53;

        ...

    }

    ...

}

三、配置负载均衡方法

  • round-robin(轮询)——默认,Nginx使用轮询算法负载均衡通讯。由于是默认方法,因此没有round-robin指令;只建立upstream配置块在顶级stream上下文并像以前步骤添加server指令。

  • last_conn(最少链接)——Nginx选择当前活跃链接数较少的服务器。

  • least_tome——Nginx选择最低平均延迟和最少活跃链接的服务器。最低活跃链接基于least_time指令的如下参数计算:

    • connect——链接upstream服务器的时间

    • first_byte——接收第一个数据字节的时间

    • last_byte——从服务器接收完整响应的时间

upstream stream_backend {

    least_time first_byte;

 

    server backend1.example.com:12345;

    server backend2.example.com:12345;

    server backend3.example.com:12346;

}

  • hash——Nginx基于用户定义键选择服务器,例如,源IP地址

upstream stream_backend {

    hash $remote_addr;

 

    server backend1.example.com:12345;

    server backend2.example.com:12345;

    server backend3.example.com:12346;

}

hash负载均衡方法也用于配置回话持久化。哈希函数基于客户端IP地址,来自指定客户端的链接老是传递给相同的服务器,除非服务器宕机或不可用。指定一个可选的consistent参数应用ketama一致性哈希方法

hash $remote_addr consistent; 

四、可选,指定最大链接数、服务器权重等

 upstream stream_backend {

    hash   $remote_addr consistent;

    server backend1.example.com:12345 weight=5;

    server backend2.example.com:12345;

    server backend3.example.com:12346 max_conns=3;

}

 

upstream dns_servers {

    least_conn;

    server 192.168.136.130:53;

    server 192.168.136.131:53;

    ...

}

若是你经过主机名标识服务器,配置主机名解析多个IP地址,而后Nginx经过IP地址使用轮询算法负载均衡。在这种状况下,你必须在proxy_pass指令中指定服务器的端口号,没必要指定协议:

stream {

    ...

    server {

        listen     12345;

        proxy_pass backend.example.com:12345;

    }

}

5    被动健康检查

若是试图链接upstream服务器超时或出错,Nginx标记服务器为不可用并在指定时间内中止发送请求给该服务器。为了定义不可用条件,包括如下参数到server指令:

  • fail_timeout——同Nginx负载均衡章节

  • max_fails——同Nginx负载均衡章节

fail_timeout默认为10秒,max_fails默认为1次。所以,若是链接10秒内尝试至少一次失败,Nginx标记服务器10秒内不可用。

upstream stream_backend {

    server backend1.example.com:12345 weight=5;

    server backend2.example.com:12345 max_fails=2 fail_timeout=30s;

    server backend3.example.com:12346 max_conns=3;

}

6    主动健康检查

健康检查能配置测试广范围的错误类型。例如,Nginx能不断测试upstream服务器的响应能力并避免服务器故障。

6.1    工做原理

Nginx发送特定健康检查请求到每一个upstream服务器并检查响应知足某一条件。若是不能链接到服务器,那么健康检查失败,服务器不健康。Nginx不代理客户端链接到不健康的服务器。若是多个健康检查定义在服务器组中,相应服务器的任意一个检查不经过该服务器都是不健康的。

6.2    预备条件

  • 你在stream上下文中配置upstream服务器组

stream {

    upstream stream_backend {

 

    server backend1.example.com:12345;

    server backend2.example.com:12345;

    server backend3.example.com:12345;

   }

}

  • 你配置一台服务器传递通讯(在这种状况下,是TCP链接)到服务器组

server {

    listen     12345;

    proxy_pass stream_backend;

}

6.3    基础配置

  • 指定共享内存区域

stream {

    upstream stream_backend {

 

        zone   stream_backend 64k;

        server backend1.example.com:12345;

        server backend2.example.com:12345;

        server backend3.example.com:12345;

   }

}

  • 启用健康检查 

server {

    listen        12345;

    proxy_pass    stream_backend;

    health_check;

    health_check_timeout 5s;

}

health_check指令启用健康检查功能,health_check_timeout覆盖健康检查的proxy_timeout。

为了启用健康检查UDP通讯,为health_check指令指定udp参数:

server {

    listen       5053;

    proxy_pass   dns_servers;

    health_check udp;

    health_check_timeout 5s;

}

 6.4    健康检查调优

默认,Nginx尝试每5秒链接upstream服务器组中的每台服务器。若是不能创建链接,Nginx认为健康检查失败,标记为不健康,中止转发客户端链接到服务器。

为了改变默认行为,包括参数到health_check指令:

  • interval——Nginx多久发送一次健康检查请求(默认5秒)

  • passes——服务器连续多少次响应健康检查认为是健康(默认是1次)

  • fails——服务器连续多少次健康检查失败认为是不健康(默认是1次)

server {

    listen       12345;

    proxy_pass   stream_backend;

    health_check interval=10 passes=2 fails=3;

}

在例子中,TCP健康检查时间间隔增长到10秒,服务器认为连续3次健康检查失败是不健康,服务器须要连续2次经过健康检查才再次认为是健康的。

默认,Nginx发送健康检查消息给upstream块中的server指令的特定端口。你能指定其它的健康检查端口,当许多服务在相同主机检查健康时很是有用。为了覆盖端口,指定health_check指令的port参数:

server {

    listen       12345;

    proxy_pass   stream_backend;

    health_check port=8080;

}

 6.5    使用match配置块调优健康检查

你能经过配置大量健康检查测试验证服务响应。这些测试放置在stream{}上下文中的match {}配置块。指定match {}块并设置它的名字,例如,tcp_test:

stream {

    ...

    match  tcp_test {

        ...

    }

}

而后在health_check指令包括match参数和match块相同名称引用块: 

stream {

    server {

        listen       12345;

        health_check match=tcp_test;

        proxy_pass   stream_backend;

    }

}

健康检查的条件或测试使用send和expect参数设置:

  • send——发送给服务器文本字符串或十六进制字符(“/x”后面跟两个十六进制数字)
  • expect——服务器返回的数据匹配的字符串货正则表达式

这些参数能用于不一样的组合,但不能同时制定超过一个send和一个expect参数。参数配置也依赖于使用(TCP或UDP)的协议。

6.5.1    调优TCP健康检查

为了调优TCP健康检查,你能组合send和expect参数:

  • 若是没有send或expect参数指定,测试链接服务器能力。

  • 若是expect参数被指定,服务器指望无条件发送数据:

match pop3 {

    expect ~* "\+OK";

}

  • 若是send参数指定,它指望链接将成功创建并指定字符串发送给服务器: 

match pop_quit {

    send QUIT;

}

  • 若是send和expect参数被指定 

stream {

    upstream   stream_backend {

        zone   upstream_backend 64k;

        server backend1.example.com:12345;

    }

 

    match http {

        send      "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";

        expect ~* "200 OK";

    }

 

    server {

    listen       12345;

    health_check match=http;

    proxy_pass   stream_backend;

    }

}

例子显示为了健康检查传入,HTTP请求必须发送到服务器,并指望服务器结果包含”200 OK”表示HTTP响应成功。

6.5.2    UDP健康检查调优

为了调优UDP健康检查,你应该指定send和expect参数:

  • NTP例子

match ntp {

   send \xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;

   expect ~* \x24;

}

  • DNS例子

match dns {

   send \x00\x2a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x73\x74\x6c\x04\x75\x6d\x73\x6c\x03\x65\x64\x75\x00\x00\x01\x00\x01;

   expect ~* "health.is.good";

}

7    动态配置

Upstream服务器组能容易使用简单的HTTP接口从新动态配置。使用该接口,你能浏览全部服务器在upstream组或特定服务器,修改服务器参数,并添加或删除upstream服务器。

为了启用动态配置:

  • 建立顶级http {}块或确保在你的配置文件中存在

http {

    ...

}

  • 建立配置请求的location,例如,upstream_conf。

http {

 

    server {

        location /upstream_conf {

            ...

        }

   }        

}

  • 在该location中指定upstream_conf指令——一个能用于解释和从新配置upstream组的处理器

http {

 

    server {

        location /upstream_conf {

            upstream_conf;

            ...

        }

   }        

}

  • 限制该location的访问

 

http {

 

    server {

        location /upstream_conf {

            upstream_conf;

            allow 127.0.0.1;

            deny  all;

        }

   }        

}

  •  建立共享内存区域

stream {

    upstream stream_backend {

        zone backend 64k;

        ...

    }

}

7.1    动态配置例子

stream {

    ...

    upstream appservers {

        zone appservers 64k;

 

        server appserv1.example.com:12345 weight=5;

        server appserv2.example.com:12345 fail_timeout=5s;

 

        server backup1.example.com:12345 backup;

        server backup2.example.com:12345 backup;

    }

 

    server {

        proxy_pass appservers;

        health_check;

    }

}

 

http {

    ...

    server {

        location /upstream_conf {

            upstream_conf;

            allow 127.0.0.1;

            deny  all;

        }

    }

}

  •  浏览全部备机

http://127.0.0.1/upstream_conf?stream=&upstream=appservers&backup=

  •  添加新服务器到服务器组

http://127.0.0.1/upstream_conf?stream=&add=&upstream=appservers&server=appserv3.example.com:12345&weight=2&max_fails=3

  •  从服务器组删除服务器

http://127.0.0.1/upstream_conf?stream=&remove=&upstream=appservers&id=2

  • 修改指定服务器

 http://127.0.0.1/upstream_conf?stream=&upstream=appservers&id=2&down=

8    TCP和UDP负载均衡配置例子

stream {

    upstream stream_backend {

        least_conn;

        server backend1.example.com:12345 weight=5;

        server backend2.example.com:12345 max_fails=2 fail_timeout=30s;

        server backend3.example.com:12346 max_conns=3;

    }

 

    upstream dns_servers {

        least_conn;

        server 192.168.136.130:53;

        server 192.168.136.131:53;

        server 192.168.136.132:53;

    }

 

    server {

        listen        12345;

        proxy_pass    backend;

        proxy_timeout 3s;

        proxy_connect_timeout 1s;

    }

 

    server {

        listen     53 udp;

        proxy_pass dns_servers;

    }

 

    server {

        listen     12346;

        proxy_pass backend.example.com:12346;

    }

}

相关文章
相关标签/搜索