数据库降级_浅谈服务降级(二)

1 实现降级

1.1 配置中心

    配置中心是一个后台,这个配置中心大家根据各自需求自己去实现,这里我们采用手工操作redis的方式,实际上是通过后台操作的redis。

1.2 nginx+lua+redis实现降级

nginx配置文件/etc/nginx/nginx.conf

user nobody; worker_processes 1; events {worker_connections 1024; }http {lua_package_path "/usr/share/lua/5.1/lua-resty-redis/lib/?.lua;;/usr/share/lua/5.1/lua- resty-redis-cluster/lib/resty‘7/?.lua;;"; lua_package_cpath "/usr/share/lua/5.1/lua-resty-redis-cluster/lib/libredis_slot.so;;"; include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name 127.0.0.1; server_name 192.168.232.100; #获取广告推荐数据 location /goods_list_advert { default_type 'application/x-javascript;charset=utf-8'; content_by_lua_file /etc/nginx/lua/goods_list_advert.lua; }#从服务层+mysql获取数据 location /goods_list_advert_from_data { default_type 'application/x-javascript;charset=utf-8'; content_by_lua ' ngx.say("从服务层+mysql获取数据") '; } } }

lua降级代码:/etc/nginx/lua/goods_list_advert.lua

--获取get或post参数-------------------- local request_method = ngx.var.request_method local args = nil local param = nil --获取参数的值 if "GET" == request_method then args = ngx.req.get_uri_args() elseif "POST" == request_method thenngx.req.read_body() args = ngx.req.get_post_args() end sku_id = args["sku_id"] --关闭redis的函数-------------------- local function close_redis(redis_instance) if not redis_instance then return end local ok,err = redis_instance:close(); if not ok then ngx.say("close redis error : ",err); end end --连接redis-------------------- local redis = require("resty.redis"); --local redis = require "redis" -- 创建一个redis对象实例。在失败,返回nil和描述错误的字符串的情况下 local redis_instance = redis:new(); --设置后续操作的超时(以毫秒为单位)保护,包括connect方法 redis_instance:set_timeout(1000) --建立连接 local ip = '127.0.0.1' local port = 6379 --尝试连接到redis服务器正在侦听的远程主机和端口 local ok,err = redis_instance:connect(ip,port) if not ok then ngx.say("connect redis error : ",err) return close_redis(redis_instance); end --从redis里面读取开关-------------------- local key = "level_goods_list_advert" local switch, err = redis_instance:get(key) if not switch then ngx.say("get msg error : ", err) return close_redis(redis_instance) end --得到的开关为空处理-------------------- if switch == ngx.null then switch = "FROM_DATA" --比如默认值 end

2 验证降级

验证1 设置为从服务和数据库读取

[root@101 redis-5.0.8]# redis-cli

127.0.0.1:6379> set level_goods_list_advert FROM_DATA 

OK

发送请求,发现广告推荐请求获取到了微服务提供的数据

fadd96463ac28d10e4832a923d84caf5.png

验证2 设置为从缓存读取

127.0.0.1:6379> set level_goods_list_advert FROM_CACHE 

OK

发送请求,发现获取到了缓存提供的数据

435dda553de78d62192c2ff7c48d4ce7.png

验证3 设置为从静态文件读取

127.0.0.1:6379> set level_goods_list_advert FROM_STATIC 

OK

发送请求,发现获取到了静态文件中的数据

367757709323c7b6565fae945511037d.png

127.0.0.1:6379> set level_goods_list_advert SHUT_DOWN 

OK

发送请求,发现获取不到数据了

3f4c785cb0b0af971d1f5ecbf345b8fe.png

3 自动降级

原理:

采用nginx+lua+redis对错误返回进行统计,当统计到的错误次数达到一定数值时,lua会判断这个数值, 然后会

在/etc/nginx/lua/goods_list_advert.lua中添加如下代码:

--判断错误的响应,并进行计数, 后续便可以参考这个数值进行降级 if tonumber(ngx.var.status) == 200 then ngx.say(ngx.var.status) ngx.log(ngx.ERR,"upstream reponse status is " .. ngx.var.status .. ",please notice it") local error_count, err = redis_instance:get("error_count_goods_list_advert") --得到的数据为空处理 if error_count == ngx.null then error_count = 0 end error_count = error_count + 1 --统计错误次数到error_count_goods_list_advert local resp,err = redis_instance:set("error_count_goods_list_advert",error_count) if not resp then ngx.say("set msg error : ",err) return close_redis(redis_instance) end end

当我们有意关掉一些服务让状态码不为200时,

可以看到redis中error_count_goods_list_advert的值在加1:

127.0.0.1:6379> get error_count_goods_list_advert 

"1"

接下来,你就可以在lua中添加判断, 比如设置一个阈值为100, 当error_count_goods_list_advert的值达到100时(也就是错误返回达到100时),你就可以降级为请求另外一个版本(老版本程序)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值