本文更新中,待完成
目的
- 当后端应用故障不可用时,从容灾系统中获取数据并返回给用户,能正常提供最基本数据浏览功能
- 需要能够正常返回HTML页面、非用户态接口数据等等
ps: 研发菜鸡,不相信研发的降级服务能力,作为运维又不想背服务全崩的这个锅,那就开始实施吧。
需要重点思考的问题
- 容灾系统应针对接口级进行判断和缓存,并采用不侵入业务式的设计
- 只有当后端接口不可用时,才获取缓存数据,并做到接口级判断;例:A/B接口相互独立,当后端只有A接口不可用时,A接口从容灾系统获取数据并返回给用户,B接口正常从后端获取数据并返回给用户,当A接口恢复时,立刻从后端获取数据返回给用户
- 用户态接口必须梳理出来,用户态接口不能被缓存!!
由于用户态接口梳理不够完善,在这方面踩了不少大坑
技术选型
Openresty: OpenResty®是一个基于Nginx与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。可以轻松应对超高并发(公司入口网关层一直采用了Openresty,所以就在Openresty上下文章)
流量异步写入缓存: srcache模块将接口数据存入Memcache
流量随机取样: Lua脚本随机取样10%数据进行缓存,这样能降低缓存的内存使用率,也能缓存到热点数据
缓存系统:Memcache,由于我们的静态容灾系统,会直接缓存比如HTML整个页面、一些返回内容较大的接口数据,而redis6以下都是单线程,在使用大key时会阻塞,这会极度影响性能。而memcache在这方面略有一点优势,所以采用memcache
实现原理
- 1、正常情况下在openresty上通过srcache和lua随机取样10%的请求 并将请求返回体写入到memcache中
- 2、当后端异常时从缓存获取数据。实现方法:判断Nginx的upstream response status,将5xx状态码重定向到缓存获取数据
架构图
配置
域名配置文件中增加配置
set srcache_v 0;
access_by_lua_file 'conf/conf.d/luascripts/srcache_random.lua';
if (uri ~ (/tk_zs/|/pmc/|/pay/|/cloud/|/set/|/ucenters/|/kfpt/)) {
set srcache_v 2;
}
if (request_uri ~ "_=[0-9]{10,13}") {
setsrcache_v 2;
}
set_md5 mem_keyuriargs;
srcache_store PUT /memcmem_key;
srcache_store_skip srcache_v;
srcache_store_statuses 200 301 302;
srcache_response_cache_control off;
srcache_methods GET HEAD;
srcache_ignore_content_encoding on;
srcache_max_expire 10h;
error_page 500 = @down_cache;
error_page 502 = @down_cache;
error_page 503 = @down_cache;
error_page 504 = @down_cache;
location = /memc {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
memc_ignore_client_abort on;
setmemc_key query_string;
setmemc_exptime 36000;
memc_pass memcached;
}
location @down_cache {
more_set_headers "down-memcache: HIT";
access_log /var/log/nginx/downcache.www.dataoke.com.access.log json;
srcache_fetch GET /memc $mem_key;
}
添加upstream组
upstream memcached {
server m-2zec60b225.memcache.rds.aliyuncs.com:11211 weight=5 max_fails=0 fail_timeout=0s;
keepalive 100;
}
lua随机取样
ngx.var.srcache_v = math.random(0,9)
--ngx.log(ngx.ERR, "===============================")
--ngx.log(ngx.ERR, ngx.var.srcache_v)
文章评论