基于动态路由的方案设计
当业务量激增时,增减服务器是很频繁的事,每次手动修改配置文件的 upstream 并不是让人满意的做法,每次增加了服务器 nginx 可以自动刷新就好了,这时候需要使用到 upsync 模块。
基于 upsync 方式,开发了模块 nginx-upsync-module,它的功能是拉取 consul 的后端 server 的列表,并更新 Nginx 的路由信息。此模块不依赖于任何第三方模块。
路由表更新方式
consul 作为 Nginx 的 db,利用 consul 的 KV 服务,每个 Nginx work 进程独立的去拉取各个 upstream 的配置,并更新各自的路由。
Consul集群
环境准备
- Centos7 3节点
- 端口
- 8300 – TCP
- 8301 – TCP & UDP
- 8302 – TCP & UDP
- 8400 – TCP
- 8500 – TCP
- 8600 – TCP & UDP
- 目录规划
- /data/consul/bin 二进制命令目录
- /data/consul/config 配置文件目录
- /data/consul/data 数据目录
主程序包
- Consul 1.5.0
consul_1.5.0_linux_amd64.zip
安装部署
在3个节点上运行
- 下载Linux Consul二进制文件
sudo mkdir /data/install
cd /data/install
sudo wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
sudo unzip consul_1.5.0_linux_amd64.zip
sudo rm -f consul_1.5.0_linux_amd64.zip
- 创建用户、创建目录
sudo mkdir /data/consul/{bin,data,config} -p
sudo useradd --system --home /data/consul --shell /bin/false consul
sudo chown consul.consul -R /data/consul
- 拷贝命令到执行目录
sudo cp /data/install/consul /data/consul/bin/consul
sudo chown consul.consul /data/consul/bin/consul
- 在其中一台服务器上创建consul secret 将密钥复制到文本文件.
/data/consul/bin/consul keygen
- 在其中一台服务器上创建consul secret 将密钥复制到文本文件.
vim /data/consul/config/server.json
将以下配置复制到该文件
- 将encrypt值替换为步骤4中创建的密码
- 将advertise_addr替换为服务器IP-
- start_joinIP替换为集群的IP
- dc替换为数据中心名称
{
"bootstrap_expect": 3,
"client_addr": "0.0.0.0",
"bind_addr": "0.0.0.0",
"advertise_addr" : "192.168.103.12",
"data_dir": "/data/consul/data",
"domain": "consul",
"enable_script_checks": true,
"dns_config": {
"enable_truncate": true,
"only_passing": true
},
"enable_syslog": true,
"encrypt": "iOP+NHGTVsrOEzrngTe4XA==",
"leave_on_terminate": true,
"log_level": "INFO",
"rejoin_after_leave": true,
"server": true,
"datacenter": "jiajiantest",
"start_join": [
"192.168.103.11",
"192.168.103.12",
"192.168.103.13"
],
"ui": true
}
- 创建systemd文件
vim /etc/systemd/system/consul.service
将以下内容复制到该文件.
[Unit]
Description="HashiCorp Consul - A service mesh solution"
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/data/consul/config/consul_server.json
[Service]
User=consul
Group=consul
ExecStart=/data/consul/bin/consul agent -config-dir=/data/consul/config/
ExecReload=/data/consul/bin/consul reload
KillMode=process
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 引导并启动集群
# 最后调整目录权限
sudo chown consul.consul /data/consul/ -R
# 在三节点分别启动服务
sudo systemctl start consul
- 执行命令检查集群状态
/data/consul/bin/consul members
你应该得到如下的输出. 这意味着您的consul集群已启动并正在运行.
[jan@node-1 ~]$ /data/consul/bin/consul members
Node Address Status Type Build Protocol DC Segment
node-1 192.168.103.11:8301 alive server 1.4.4 2 us-central <all>
node-2 192.168.103.12:8301 alive server 1.4.4 2 us-central <all>
node-3 192.168.103.13:8301 alive server 1.4.4 2 us-central <all>
选项说明
Parameter | Comments |
---|---|
-server | 指定节点为server,每个数据中心(DC)的server数推荐3-5个 |
-bootstrap-expect | 参数表明该服务运行时最低开始进行选举的节点数,当设 |
-ui | 启动WEB UI |
-node | 指定节点在集群中的名称,该名称在集群中必须是唯一的 |
-config-dir | 指定service的配置文件和检查定义所在的位置。目录必需为 |
-data-dir | 指定agent储存状态的数据目录,这是所有agent都必须的,对 |
-bind | 指明节点的IP地址,Consul侦听的地址,它必须可以被集群中的所有其他 |
-client | 指定可访问这个服务结点的ip |
-join | 将该节点加入集群中 |
-datacenter | 指定该 agent 加入到哪一个数据中心,默认为 dc1 |
OpenResty
OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。
主程序包
- OpenResty
openresty-1.15.8.3.tar.gz
Nginx扩展模块
prce 正则匹配模块
pcre-8.44.tar.gzopenssl https协议模块
openssl-1.1.1g.tar.gzzlib 压缩模块
zlib-1.2.11.tar.gzngx_cache_purge 缓存清理模块
ngx_cache_purge-2.3.tar.gznginx-module-vts Vhost监控模块
nginx-module-vts-0.1.18.tar.gz
这个模块可以详细地输出Nginx的运行情况,通过json格式的输出,还可以纳入Zabbix监控中,来监控不同的vhost以及不同的upstream的运行状态,便于详细掌握Nginx的运行情况,达到自动化运维
参考链接nginx-upsync-module 动态Upstream模块
nginx-upsync-module-2.1.0.tar.gz 动态修改虚拟主机配置,上/下架应用服务器,鉴于操作起来比较复杂,先将此模块搁置。同时NginX reload并不影响业务
具体原理nginx_upstream_check_module 主动检查模块
nginx_upstream_check_module-master.zip
支持http及tcp协议检测后端服务健康模块
注意: nginx-upsync-module 与 nginx_upstream_check_module 同时编译会报错
yaoweibin原作者的模块代码不兼容nginx-upsync-module
fix bug: https://github.com/weibocom/nginx-upsync-module/issues/182
这里使用xiaokai-wang修复过的版本
ngx_brotli Brotli 压缩算法
ngx_brotli
启用 Brotli 压缩算法,对比 Gzip 压缩 CDN 流量再减少 20%
Google 认为互联网用户的时间是宝贵的,他们的时间不应该消耗在漫长的网页加载中,因此在 2015 年 9 月 Google 推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率。- 根据 Google 发布的研究报告,Brotli 压缩算法具有多个特点,最典型的是以下 3 个:
- 针对常见的 Web 资源内容,Brotli 的性能相比 Gzip 提高了 17-25%;
- 当 Brotli 压缩级别为 1 时,压缩率比 Gzip 压缩等级为 9(最高)时还要高;
- 在处理不同 HTML 文档时,Brotli 依然能够提供非常高的压缩率。
Jemalloc 内存管理
jemalloc-5.2.1.tar.bz2
JeMalloc 是一款内存分配器,与其它内存分配器相比,它最大的优势在于多线程情况下的高性能以及内存碎片的减少。
动态模块Upsync
介绍
nginx-upsync-module是由王晓开用C开发的nginx模块,用于从consul或其它同步upstream模块配置,动态修改后端服务属性(weight、max_fails等等)。修改这些信息后,不像未使用该模块的nginx一样需要reload下nginx。
nginx在作为负载均衡角色时,对于单台nginx,增加、删除后端服务,对于进行单台的nginx,修改nginx配置文件后,要想配置文件生效,必须reload下nginx,这是很方便的。但是对于一个十几台或者几十台的nginx集群,要实现这是一个很大的一个工作量。并且reload nginx会增加系统负载也会暂时降低性能。
nginx-upsync-module可以很容易解决上面所提到的问题,并且也不会影响性能。
该模块现在仍处于开发,不过已经准备用于生产环境。建议和后端健康检测模块nginx_upstream_check_module配合使用。兼容性
master分支兼容1.9版本及以上的nginx。nginx-upsync-1.8.x兼容1.8版本的nginx。优势
该模块提供了发现后端的方法。支持通过consul动态添加和删除后端服务和调整后端服务的weight、fail_timeout、max_fails等属性。也会从consul获取新的后端服务并同步到nginx的IP路由表。该模块具有以下优势:及时性
会发送给consul带有索引的key,consul会将该索引和consul的索引进行对比,如果索引没有改变,链接会挂起5分钟,在这期间,对该key-value的任何操作,都会立马得到反馈。几乎无性能损失
从consul获取后端服务器列表,对于nginx来说就相当于一个请求。更新nginx的IP路由表,需要reload nginx,因此只会对nginx的性能有一点影响。稳定
如果这次获取服务器失败,在下一个同步间隔仍会获取服务器列表。这样就保证了后端服务提供服务的稳定性。同时,支持将最近的配置文件备份到本地,即使consul故障宕机了,nginx仍可以随时可以reload配置。健康检测
该模块支持对后端服务的健康检测,不过需要nginx_upstream_check_module。因此建议nginx-upsync-module和nginx_upstream_check_module配合使用。
upsync
- 语法:upsync $consul.api.com:$port/v1/kv/upstreams/pstream_name [upsync_type=consul] [upsync_interval=seconds/nutes] [upsync_timeout=seconds/minutes] [strong_dependency=off/];
- 默认:upsync_interval=5s upsync_timeout=6m rong_dependency=off
- 位置:upstream
- 功能:从consul或etcd获取服务列表
- 参数解析
- upsync_interval: 从consul获取服务列表的间隔时间
- upsync_timeout: 从consul获取服务列表的请求超时时间
- upsync_type: 指定从什么类型的服务(consul或etcd)获取服务列表。
- strong_dependency: nginx启动是否强制依赖upsync_type指定的服务关。如果upsync_type指定的是consul,在nginx启动是,consul并未,那么nginx启动会失败。
upsync_dump_path
- 语法: upsync_dump_path $path;
- 默认:/tem/servers_$host.conf
- 位置:upstream
- 功能:备份upstream配置的后端服务器到指定的路径下
upsync_lb
- 语法:upsync_lb round_robin/ip_hash/hash
- 默认:round_robin
- 位置:upstream
- 功能:指定使用的调度方法
upstream_show
- 语法:upstream_show;
- 默认:None
- 位置:location
- 功能:列出指定的upstream配置的所有后端服务器
编译安装Jemalloc
# 进入默认的软件目录
cd /usr/local/src/
# 下载安装包
wget -c https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2
tar xjf jemalloc-5.2.1.tar.bz2
cd jemalloc-5.2.1
# 安装配置
./configure --prefix=/usr/local/jemalloc-5.2.1
make && make install
echo '/usr/local/jemalloc-5.2.1/lib' >> /etc/ld.so.conf.d/local.conf
ldconfig
编译安装OpenResty
- nginx源码包打补丁
nginx源码包不打upstream_check_module补丁,模块加载失效
cd openresty-1.15.8.3/bundle/nginx-1.15.8
patch -p1 < ../../../nginx_upstream_check_module-master/check_1.12.1+.patch
# 得到如下 secceeded 返回则为成功
patching file src/http/modules/ngx_http_upstream_hash_module.c
Hunk #2 succeeded at 241 (offset 3 lines).
Hunk #3 succeeded at 571 (offset 22 lines).
patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
Hunk #2 succeeded at 211 (offset 3 lines).
patching file src/http/modules/ngx_http_upstream_least_conn_module.c
patching file src/http/ngx_http_upstream_round_robin.c
patching file src/http/ngx_http_upstream_round_robin.h
- 去除gcc的debug参数(可以减少二进制包的大小)
vim openresty-1.15.8.3/bundle/nginx-1.15.8/auto/cc/gcc
#注释掉这一行
# debug
#CFLAGS="$CFLAGS -g"
- 处理报错”./configure: error: Brotli library is missing from the /usr directory.”
cd ../ngx_brotli && git submodule update --init && cd -
- 处理报错”./configure: error: Brotli library is missing from the /usr directory.”
- 编译参数
./configure --prefix=/data/sa/openresty-1.15.8.3-build-`date +%Y%m%d` \
--without-http_memc_module \
--without-lua_resty_memcached \
--without-lua_resty_mysql \
--with-threads \
--with-file-aio \
--with-http_v2_module \
--with-http_realip_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--with-http_sub_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_ssl_preread_module \
--with-pcre=../pcre-8.44 \
--with-pcre-jit \
--http-proxy-temp-path=/data/sadata/openresty/temp/proxy_temp \
--http-fastcgi-temp-path=/data/sadata/openresty/temp/fastcgi_temp \
--http-uwsgi-temp-path=/data/sadata/openresty/temp/uwsgi_temp \
--http-scgi-temp-path=/data/sadata/openresty/temp/scgi_temp \
--with-zlib=../zlib-1.2.11 \
--with-openssl=../openssl-1.1.1g \
--with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers' \
--add-module=../nginx-module-vts-0.1.18 \
--add-module=../nginx-upsync-module-2.1.2 \
--add-module=../nginx_upstream_check_module-master \
--add-module=../ngx_brotli \
--add-module=../ngx_cache_purge-2.3 \
--add-module=../ngx_http_substitutions_filter_module-0.6.4 \
--with-ld-opt="-ljemalloc"
- 编译
# 如果编译失败 可以试试 make -j1单进程
make
make install
- 查看版本信息
./bin/openresty -V
nginx version: openresty/1.15.8.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.1.1g 21 Apr 2020
TLS SNI support enabled
configure arguments: --prefix=/data/sa/openresty-1.15.8.3-build-20200424/nginx --with-cc-opt=-O2 --add-module=../ngx_devel_kit-0.3.1rc1 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.15 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.15 --add-module=../rds-csv-nginx-module-0.09 --add-module=../ngx_stream_lua-0.0.7 --with-ld-opt='-Wl,-rpath,/data/sa/openresty-1.15.8.3-build-20200424/luajit/lib -ljemalloc' --with-threads --with-file-aio --with-http_v2_module --with-http_realip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_secure_link_module --with-http_stub_status_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_sub_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module --with-pcre=/usr/local/src/openresty/openresty-1.15.8.3/../pcre-8.44 --with-pcre-jit --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --http-uwsgi-temp-path=temp/uwsgi_temp --http-scgi-temp-path=temp/scgi_temp --with-zlib=/usr/local/src/openresty/openresty-1.15.8.3/../zlib-1.2.11 --with-openssl=/usr/local/src/openresty/openresty-1.15.8.3/../openssl-1.1.1g --with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers' --add-module=/usr/local/src/openresty/openresty-1.15.8.3/../nginx-module-vts-0.1.18 --add-module=/usr/local/src/openresty/openresty-1.15.8.3/../nginx-upsync-module-2.1.2 --add-module=/usr/local/src/openresty/openresty-1.15.8.3/../nginx_upstream_check_module-master --add-module=/usr/local/src/openresty/openresty-1.15.8.3/../ngx_brotli --add-module=/usr/local/src/openresty/openresty-1.15.8.3/../ngx_cache_purge-2.3 --add-module=/usr/local/src/openresty/openresty-1.15.8.3/../ngx_http_substitutions_filter_module-0.6.4 --with-stream --with-stream_ssl_preread_module --with-http_ssl_module
OpenResty配置Demo
- 在目标配置jemalloc
cd /usr/local/
# 拷贝编译好的jemalloc-5.2.1到目录
7z x jemalloc-5.2.1.7z
echo '/usr/local/jemalloc-5.2.1/lib' >> /etc/ld.so.conf.d/local.conf
ldconfig
- 准备运行目录
mkdir -p /data/sadata/openresty/{config,logs}
mkdir -p /data/sadata/openresty/logs/{access,error,pid}
mkdir -p /data/sadata/openresty/config/{auth,blackip,ca,geoip,vhosts,whiteip}
- 主配置文件 nginx.conf
user nobody;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 100000;
error_log /data/sadata/openresty/logs/error/error.log error;
pid /data/sadata/openresty/logs/pid/nginx.pid;
pcre_jit on;
events {
use epoll;
worker_connections 65535;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '{"@timestamp":"$time_iso8601",'
'"clientRealIp":"$clientRealIp",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"time_local":"$remote_user",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_response_time":"$upstream_response_time",'
'"request_time":"$request_time",'
'"server_name":"$host",'
'"request_method":"$request_method",'
'"uri":"$uri"'
'}';
log_format main_with_body '{"@timestamp":"$time_iso8601",'
'"clientRealIp":"$clientRealIp",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"time_local":"$remote_user",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_response_time":"$upstream_response_time",'
'"request_time":"$request_time",'
'"server_name":"$host",'
'"request_method":"$request_method",'
'"content_length":"$content_length",'
'"content_type":"$content_type",'
'"request_body":"$request_body",'
'"uri":"$uri"'
'}';
map $http_x_forwarded_for $clientRealIp {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;
}
#access_log logs/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
send_timeout 15s;
#more_set_headers "Server: PP_Proxy";
server_tokens off;
# server name
server_names_hash_bucket_size 128;
server_name_in_redirect off;
# client
client_body_timeout 15;
client_header_buffer_size 16k;
client_max_body_size 32m;
client_body_buffer_size 512k;
large_client_header_buffers 4 32k;
# proxy
proxy_connect_timeout 15;
proxy_read_timeout 15;
proxy_send_timeout 15;
proxy_buffer_size 128k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_headers_hash_max_size 1024;
proxy_headers_hash_bucket_size 128;
proxy_max_temp_file_size 128m;
#proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream error invalid_header http_502 http_503;
proxy_temp_path /dev/shm/proxy_temp;
proxy_redirect off;
proxy_ignore_client_abort on;
proxy_set_header Host $host;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
# check
check_shm_size 50M;
# check
check_shm_size 128M;
# gzip
gzip on;
gzip_min_length 20;
gzip_buffers 32 128k;
gzip_http_version 1.1;
gzip_comp_level 5;
#gzip_types application/javascript application/rss application/xml application/json application/x-javascript text/xml text/css text/plain image/jpeg image/gif image/png;
gzip_types *;
gzip_vary off;
gzip_disable "msie6";
# brotli
brotli on;
brotli_comp_level 6;
brotli_buffers 32 128k;
brotli_min_length 20;
brotli_types *;
brotli_static always;
## vts
#vhost_traffic_status_zone shared:vhost_traffic_status:32m;
#vhost_traffic_status_filter_by_set_key $uri uri::*;
## vhost_traffic_status_filter_by_set_key $geoip_country_code country::*;
## vhost_traffic_status_filter_by_set_key $geoip_city city::*;
#map $http_user_agent $filter_user_agent {
# default 'unknown';
# ~iPhone ios;
# ~Android android;
# ~(MSIE|Mozilla) windows;
# ~(Axis|Java) java;
#}
#vhost_traffic_status_filter_by_set_key $filter_user_agent agent::*;
server {
listen 80 default;
server_name _;
default_type text/html;
charset utf-8;
#return 200 '<center><h1>Hello Proxy</h1></center>';
access_log off;
location / {
content_by_lua_block {
ngx.say('<center><h1>域名设置有误! Ngx Proxy找不到域名对应的后端程序, 请与运维团队联系!</h1></center>')
}
}
}
include /data/sadata/openresty/config/vhosts/*.conf;
}
- 查看jemalloc是否运行正常
lsof -n | grep jemalloc openresty 30734 root mem REG 253,0 4397608 604226 /usr/local/jemalloc-5.2.1/lib/libjemalloc.so.2 openresty 30735 nobody mem REG 253,0 4397608 604226 /usr/local/jemalloc-5.2.1/lib/libjemalloc.so.2 openresty 30736 nobody mem REG 253,0 4397608 604226 /usr/local/jemalloc-5.2.1/lib/libjemalloc.so.2
- 监控配置 slb-status.example.com.conf
server {
# SLB集群中只需设置一个用来查看的域名即可, 无需所有域名都开
listen 9913;
server_name slb-status.example.com;
location /ups_status {
check_status;
}
location /ups_list {
upstream_show;
}
location /vts_status {
vhost_traffic_status_display;
vhost_traffic_status_display_format json;
# vhost_traffic_status_display_format prometheus;
#统计国家流量
# vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;
#统计地区流量
#vhost_traffic_status_filter_by_set_key $geoip_city city::$server_name;
#统计用户代理流量
vhost_traffic_status_filter_by_set_key $filter_user_agent agent::$server_name;
# uri
vhost_traffic_status_filter_by_set_key $uri uris::$server_name;
#统计状态页面以外的流量
vhost_traffic_status_bypass_limit on;
vhost_traffic_status_bypass_stats on;
}
access_log off;
}
- 动态Upstream配置
注意: 要先创建upsync目录, 并且touch一个空的配置文件
sudo mkdir -p /data/sadata/openresty/upsync_dump/
touch /data/sadata/openresty/upsync_dump/test.conf
- 一键生成upsync路径 以及空配置文件(在每个openresty节点执行)
sudo mkdir -p /data/sadata/openresty/upsync_dump/
curl -Ss localhost:9913/ups_list |grep Upstream |awk -F'[ ;]' '{print "touch /data/sadata/openresty/upsync_dump/"$3".conf"}' > upsync_dir.sh
sudo bash upsync_dir.sh
sudo chown nobody. -R /data/sadata/openresty/upsync_dump/
- 配置文件test.conf
upstream test {
# 首次生成upsync_dump数据时用到,后续可以注释掉
# 生产请用真实的server
server 127.0.0.1:11111;
upsync 127.0.0.1:8500/v1/kv/ngx-ups/inside/test upsync_timeout=1m upsync_interval=1s upsync_type=consul strong_dependency=off;
upsync_dump_path /data/sadata/openresty/upsync_dump/test.conf;
include /data/sadata/openresty/upsync_dump/test.conf;
check interval=1000 rise=3 fall=5 timeout=1000 type=http;# default_down=false;
check_keepalive_requests 100;
check_http_send "HEAD / HTTP/1.1\r\nConnection: keep-alive\r\nHost: ngx-http-check.info\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
server {
listen 80;
server_name test.example.com;
location / {
proxy_pass http://test;
}
access_log /data/sadata/openresty/logs/access/access_test.log main;
}
Consul操作
选项说明
curl -X ${Mothed} http://$consul_ip:$port/v1/kv/$dir/$upstream_name/$backend_ip:$backend_port
Parameter | Comments |
---|---|
Motheds | API方法 |
dir | upstreams路径 |
- 加入upstream节点
curl -X PUT ‘http://192.168.103.12:8500/v1/kv/ngx-ups/inside/test/192.168.102.200:80'
curl -X PUT ‘http://192.168.103.12:8500/v1/kv/ngx-ups/inside/test/192.168.102.69:80'
- 删除upstream节点
curl -X DELETE ‘http://192.168.103.12:8500/v1/kv/ngx-ups/inside/test/192.168.102.200:80'
- 下架upstream节点
curl -X PUT -d ‘{“weight”:1, “max_fails”:2, “fail_timeout”:10, “down”:1}’ http://192.168.103.12:8500/v1/kv/ngx-ups/inside/test/192.168.102.69:80
- 激活upstream节点
curl -X PUT -d ‘{“weight”:1, “max_fails”:2, “fail_timeout”:10, “down”:0}’ http://192.168.103.12:8500/v1/kv/ngx-ups/inside/test/192.168.102.69:80
- 查看指定upstream节点
curl http://192.168.103.12:8500/v1/kv/ngx-ups/inside/test?recurse
- upstream 首次生成
# 获取upstgream列表
ngx_ups_list_url="192.168.103.12:9913/ups_list"
curl http://$ngx_ups_list_url|grep -v "^$" |awk -F'[ ;]' '{if ($1=="Upstream") print $3; else print $10}'
# 插入consul
consul_addr="192.168.103.12:8500"
ng_type="inside"
upstream_name="test"
backend="
192.168.21.15:8091
192.168.21.15:82
192.168.21.15:81
192.168.21.15:8092
192.168.21.15:8093
192.168.21.15:8001
"
for i in $backend ; do
curl -X PUT -d '{"weight":1, "max_fails":3, "fail_timeout":10}' http://$consul_addr/v1/kv/ngx-ups/$ng_type/$upstream_name/$i
done
可以使用下述命令,自动生成生成拼接的shell
# 设定
ngx_ups_list_url="172.16.99.87:9913/ups_list"
consul_addr="172.16.99.56:8500"
ng_type="ngx-proxy"
echo "ngx_ups_list_url=\"${ngx_ups_list_url}\"" > mk_upstream.sh
echo "consul_addr=\"${consul_addr}\"" >> mk_upstream.sh
echo "ng_type=\"${ng_type}\"" >> mk_upstream.sh
curl -Ss http://$ngx_ups_list_url |awk -F'[ ;]' '{if ($1=="Upstream") print "upstream_name=\""$3"\"\nbackend=\""; else if ($10 =="") print "\"\nfor i in $backend ; do curl -X PUT -d \"{\\\"weight\\\":1,\\\"max_fails\\\":0}\" http://$consul_addr/v1/kv/ngx-ups/$ng_type/$upstream_name/$i; done \n"; else print $10}' >> mk_upstream.sh
bash mk_upstream.sh
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!