降级

降级其实当网站出现高并发时,丢车保帅的一个策略。
降级分为:内容降级,限流降级,限速降级

内容降级

1.不重要的功能->平时从mysql获取的数据,

如果突然来了很多请求,系统负载不过来 请求开关 用redis(分配到2,3,4,5)

2.从缓存中获取数据,

3.静态文件。

4.nginx直接返回空数据(关停某个功能)

5.兜底文件

在这里插入图片描述
降级的种类:

1.根据开关的位置:可以分为代码降级和前置降级

2.读写,可以分读降级,写降级

在这里插入图片描述
写降级,有一定延迟,对实时性要求比较低的项目,可以用,防止系统崩掉。
功能重要性排序,功能重要性越低,越有可能成为我们降级的对象。

秒杀都是直接降级,然后秒杀结束处理(消息队列,或者redis)

限流降级
在这里插入图片描述
安装模块,nginx限流模块:
ngx_http_limit_req_moudule 里面有配置
ngx_http_limit_conn_moudule 里面有配置

修改nginx配置文件 nginx.conf 处理请求数

优化后(只能修改配置文件,控制流量和请求数,不智能)
在这里插入图片描述

--判断错误的响应,并进行计算   
--1.如果nginx响应不等于200
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  记到redis里
	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		
close_redis(redis_instance)		

降级的维护方式,分为手动降级和自动降级

手动降级,后台配置,开关

自动降级
在这里插入图片描述

nginx+lua+redis进行自动降级,限流降级(比nginx自带的那个模块要灵活)

nginx.conf 文件

http{
#下载redis模块  安装lua语言(没有也不能获取数据)  nginx配置redis模块
	lua_package_path "";
	lua_package_cpath "";
}

server {
#进行匹配那个地址需要被降级	
#根据test.lua实现逻辑
  location /test{
	default_type 'application/x-javascript;charset=ust-8';
	content_by_lua_file /etc/nginx/lua/test.lua;
	}
	#从服务层+mysql读取数据
	location /good_data{
		default_type 'application/x-javascript;charset=utf-8';
		proxy_pass http://127.0.0.1/:8080/getlist;
	}
}

如果需要返回json文件 需要引入json

---获取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 then
	ngx.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 = "读取开关key"
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_BY_MYSQL"  --默认值	
end 

--当开关是要从服务中获取数据时
if "FROM_DATA_BY_MYSQL" == switch then
	ngx.exec('/goods_data');
--当开关是要从缓存中获取数据时
elseif "FROM_CACHE" == switch then
	local resp,err = redis_instance:get("redis_goods")
	ngx.say(resp)
--当开关是要从静态资源中获取数据时
elseif "FROM_STATIC" == switch then
	ngx.header.content_type = "application/x-javascript;charset=utf-8"
	local file = "/etc/nginx/html/good_static.json"
	local f = io.open(file,"rb")
	local content = f:read("*all")
	f:close()
	ngx.print(content)
-- 当开关是要停掉数据获取时
elseif "SHUT_DOWN" == switch then
	ngx.say('no data')
end

--close_redis(redis_instance)
			
--判断错误的响应,并进行计算   
--1.如果nginx响应不等于200
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  记到redis里
	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		
close_redis(redis_instance)				

redis-cli -h 127.0.0.1

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mr.杰瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值