背景
天翼云CDN现有的架构是Nginx通过一致性哈希的方式去后端ATS请求,节资点中同一个资源都会哈希到相同的ATS服务器,当某个源访问过热时会造成后端ATS服务器负载过高。
解决方案
为了解决这一问题,需要识别到热点资源,并把热点资源的请求通过轮询方式转发到其他机器的ATS上去,以减轻当前节点的访问压力。
热点轮询新方案是以分频道域名粒度实现的。请求访问进入网关以后,对该请求的请求频次加以统计,并将统计结果记录到共享内存中,然后新进入请求会根据判断访问频次是否已经超过阈值,如果超过,就开启了轮询(round robin)方式,将请求分散到其他ATS节点,否则就保持现有的一致性hash方式,请求固定访问到集群中某一台机器。
在NGINX上实现
- 分配一块专门用作热点请求统计的共享内存,请求开始统计请求次数,并判断当前请求是否是热点请求,若为热点请求则使用轮询方式回源,否则使用一致性哈希方式回源。
- 示例配置:
# 共享内存
lua_shared_dict hoturi_shm 100m;
# 一致性哈希方式
upstream cache_server {
hash $http_ctl_store_url consistent;
server 192.169.159.167:8080;
server 192.169.159.168:8080;
server 192.169.159.169:8080;
keepalive 1000;
}
# 轮询方式
upstream roundrobin_server {
server 192.169.159.167:8080;
server 192.169.159.168:8080;
server 192.169.159.169:8080;
keepalive 1000;
}
server {
listen 80;
server_name test.com;
access_log logs/core_access.log core_main;
error_log logs/error.log error;
set $cache_server "cache_server";
location / {
access_by_lua_block {
local hoturi_shm = ngx.shared.hoturi_shm
local threshold = 100
local key = ngx.var.http_ctl_store_url
local request_times = hoturi_shm:get("key")
if request_times >= threshold then
ngx.var.cache_server = "roundrobin_server"
end
}
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_pass $scheme://$cache_server;
}
}