Django-应用水平扩展

使用Tengine和负载均衡

简介

Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。

特性

  • 继承Nginx-1.17.3的所有特性,兼容Nginx的配置;
  • 支持HTTP的CONNECT方法,可用于正向代理场景;
  • 支持异步OpenSSL,可使用硬件如:QAT进行HTTPS的加速与卸载;
  • 增强相关运维、监控能力,比如异步打印日志及回滚,本地DNS缓存,内存监控等;
  • Stream模块支持server_name指令;
  • 更加强大的负载均衡能力,包括一致性hash模块会话保持模块还可以对后端的服务器进行主动健康检查,根据服务器状态自动上线下线,以及动态解析upstream中出现的域名
  • 输入过滤器机制支持。通过使用这种机制Web应用防火墙的编写更为方便;
  • 支持设置proxy、memcached、fastcgi、scgi、uwsgi在后端失败时的重试次数
  • 动态脚本语言Lua支持。扩展功能非常高效简单;
  • 支持按指定关键字(域名,url等)收集Tengine运行状态
  • 组合多个CSS、JavaScript文件的访问请求变成一个请求
  • 自动去除空白字符和注释从而减小页面的体积
  • 自动根据CPU数目设置进程个数和绑定CPU亲缘性;
  • 监控系统的负载和资源占用从而对系统进行保护
  • 显示对运维人员更友好的出错信息,便于定位出错机器;
  • 更强大的防攻击(访问速度限制)模块
  • 更方便的命令行参数,如列出编译的模块列表、支持的指令等
  • 可以根据访问文件类型设置过期时间;
  • ……

安装

  1. 安装Tengine

    • 安装安装依赖pcre
    • wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
    • ./configure –prefix=/usr/local/pcre && make && make install
  2. 指定pcre源码目录安装tengine

    • wget https://tengine.taobao.org/download/tengine-2.3.2.tar.gz
    • tar zxvf tengine-2.3.2.tar.gz && cd /data/tengine-2.3.0
    • ./configure --prefix=/data/tengine/ --with-http_realip_module --with-http_gzip_static_module --with-pcre=/data/pcre-8.44
    • make && make install

最简单的配置:路由转发请求到 Gunicorn/uWSGI 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name recruit.mycompany.com;

location / {
# 转发请求到gunicorn进程处理
proxy_pass http://127.0.0.1:8000;

proxy_set_header Host $http_host;
proxy_set_header x-Real-IP $remote_addr;

# 包含了客户端地址,以及各级代理IP的完整IP链
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

使用Tengine/Nginx负载均衡

Tengine

  • 请求路由到两台后端服务器
  • 两台后端服务器 Upstream
    • 服务器运行 Gunicorn/uWSGI
    • 单台服务器运行有两个实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#vim /data/tengine/conf.d/recruitment.conf

upstream django-server {
# max_fails = 3为允许失败的次数,默认值为1。对后端节点做健康检查。
# 20s内,当max_fails次失败后,暂停将请求分发到该服务器
server 192.168.1.2:8001 max_fails=3 fail_timeout=20s;
server 192.168.1.2:8002 max_fails=3 fail_timeout=20s;
server 192.168.1.3:8001 max_fails=3 fail_timeout=20s;
server 192.168.1.3:8002 max_fails=3 fail_timeout=20s;
}
server {
listen 80;
server_name www.mycompany.com;

access_log /data/tengine/logs/recruitment-access.log main;
error_log /data/tengine/logs/recruitment-error.log;

location / {
proxy_pass http://django-server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Tengine 的分流策略

负载分流策略

  • round-robin — 平均分配流量:轮询模式
  • least-connected — 最少连接优先,下一个请求分到活跃连接最少的服务器
  • ip-hash — 按照客户端 IP 哈希来分配服务器 IP
  • 带权重流量分配
  • 一致性哈希 (Tengine)
  • 会话保持 (Tengine 特性)

最少连接优先

  • 前面配置的为平均分配流量;
  • 按照最少连接优先/ip hash 的配置:
    1
    2
    3
    4
    5
    6
    7
    upstream django-upstream {
    least_conn; # for ip hash: ip_hash;
    server 192.168.1.2:8001;
    server 192.168.1.2:8002;
    server 192.168.1.3:8001;
    server 192.168.1.3:8002;
    }

按权重分配

  • 按照权重分配(适合机器配置不一样时)
  • 6个请求里面,3个走到第一台,其它3台没台1个请求。
    1
    2
    3
    4
    5
    6
    upstream django-upstream {
    server 192.168.1.2:8001 weight=3;
    server 192.168.1.2:8002;
    server 192.168.1.3:8001;
    server 192.168.1.3:8002;
    }

会话保持

  • 尽可能保证同一个客户端访问的都是同一个后端服务器
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 默认配置:cookie=route mode=insert fallback=on
    upstream django-upstream {
    server 192.168.0.1;
    server 192.168.0.2;
    session_sticky;
    }

    server {
    location / {
    proxy_pass http://django-upstream;
    }
    }

健康检查自动容错

  • 被动健康检查

    ngx_http_upstream_module 实现了被动的健康检查功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 被动健康检查
    upstream backend {
    server 127.0.0.1:8000 max_fails=2 fail_timeout=20s;
    server 127.0.0.1:8001 max_fails=2 fail_timeout=20s;
    }

    server {
    listen 80;
    server_name recruit.mycompany.com;

    location / {
    proxy_pass http://backend;
    }
    }
  • 主动健康检查

    http_upstream_check_module,主动定时检查

    1
    2
    3
    4
    5
    6
    7
    8
    # 主动健康检查
    upstream django-upstream {
    server 192.168.1.2:8000;
    server 192.168.1.3:8000;
    check intervel=3000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "HEAD / HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
    }
    1
    2
    3
    4
    5
    6
    7
    指令后面的参数意义是:
    interval:向后端发送的健康检查包的间隔。
    fall(fall_count):如果连续失败次数达到fall_count,服务器就被认为是down。
    rise(rise_count):如果连续成功次数达到rise_count,服务器就被认为是up。
    timeout:后端健康请求的超时时间。

    上面配置的意思是,对django_upstream的所有节点,每个3秒(3000毫秒)检测一次,请求2次正常则标记realserver状态为up,如果检测3次都失败,则标记realserver的状态为down,超时时间为1秒。