高可用框架目录
1、高可用概念
可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。这里的重点是"有限时间内"和"返回结果"。
2、集群主从
基本上大多数技术栈,如nosql、搜索引擎、数据库、等等都支持集群主从
3、降级、限流算法
降级的原理:就是降低次要功能的可用性实用性,增加核心功能的高可用性。
当我们的服务器压力剧增为了保证核心功能的可用性 ,而选择性的降低一些功能的可用性,实时性,或者把这些功能从不实时的缓存中获取,或者直接关闭该功能。这就是典型的丢车保帅了。 就比如贴吧类型的网站,当服务器吃不消的时候,可以选择把发帖功能关闭,注册功能关闭,改密码,改头像这些都关了,为了确保登录和浏览帖子这种核心的功能。
配置中心手动降级,基于nginx接入层的手动降级代码示例:
代码:
--获取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 = "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
--当开关是要从服务中获取数据时--------------------
if "FROM_DATA" == switch then
ngx.exec('/goods_list_advert_from_data');
--当开关是要从缓存中获取数据时--------------------
elseif "FROM_CACHE" == switch then
local resp, err = redis_instance:get("nihao")
ngx.say(resp)
--当开关是要从静态资源中获取数据时--------------------
elseif "FROM_STATIC" == switch then
ngx.header.content_type="application/x-javascript;charset=utf-8"
local file = "/etc/nginx/html/goods_list_advert.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
基于nginx的漏桶自动降级代码示例:
-- 加载nginx—lua限流模块 local limit_req = require "resty.limit.req" -- 这里设置rate=50个请求/每秒,漏桶桶容量设置为1000个请求 -- 因为模块中控制粒度为毫秒级别,所以可以做到毫秒级别的平滑处理 local lim, err = limit_req.new("my_limit_req_store", 50, 1000) if not lim then ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err) return ngx.exit(501) end local key = ngx.var.binary_remote_addr local delay, err = lim:incoming(key, true) ngx.say(delay) if ( delay <0 or delay==nil ) then return ngx.exit(502) end -- delay值就是当前这个请求的等待时长,这个时长是通过resty.limit.req模块计算出来的 -- 1000以外的就溢出 if not delay then if err == "rejected" then return ngx.say("1000以外的就溢出") -- return ngx.exit(502) end
ngx.log(ngx.ERR, "failed to limit req: ", err)
return ngx.exit(502)
end
-- 50-100的等待从微服务+mysql获取实时数据;(100-50)/50 =1
if ( delay >0 and delay <=1 ) then
ngx.sleep(delay)
-- 100-400的直接从redis获取实时性略差的数据;(400-50)/50 =7
elseif ( delay >1 and delay <=7 ) then
local resp, err = redis_instance:get("redis_goods_list_advert")
ngx.say(resp)
return
-- 400-1000的从静态文件获取实时性非常低的数据(1000-50)/50 =19
elseif ( delay >7) then
ngx.header.content_type="application/x-javascript;charset=utf-8"
local file = "/etc/nginx/html/goods_list_advert.json"
local f = io.open(file, "rb")
local content = f:read("*all")
f:close()
ngx.print(content)
return
end
ngx.say("进入查询微服务+mysql")
限流算法
令牌桶算法:
令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是足够,当令牌数减为零时,则拒绝新的请求。 漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数积到漏桶容量时,则新流入的请求被拒绝。 令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,又付一次拿3个令牌,或4个令牌),并允许一定程度的突发流量。 漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的率流
出,而不能一次是1,下次又是2),从而平滑突发流入速率。 令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率。
4、负载均衡故障切换
MHA 的切换过程,共包括以下的步骤:
1. 配置文件检查阶段,这个阶段会检查整个集群配置文件配置
2. 宕机的 master 处理,这个阶段包括虚拟 ip 摘除操作,主机关机操作(由于没有定义power_manager脚
本,不会关机)
3. 复制 dead maste 和最新 slave 相差的 relay log,并保存到 MHA Manger 具体的目录下
4. 识别含有最新更新的 slave
5. 应用从 master 保存的二进制日志事件(binlog events)(这点信息对于将故障master修复后加入集群很重
要)
6. 提升一个 slave 为新的 master 进行复制
7. 使其他的 slave 连接新的 master 进行复制
nginx故障切换
#服务器的集群 upstream xxx.com { #服务器集群名字 #server 192.168.218.129:8080 weight=1 max_fails=2 fail_timeout=600s; #server 192.168.218.131:8080 weight=1 max_fails=2 fail_timeout=600s; server 192.168.88.103:8080 weight=2 **max_fails=2**; #tomcat1 server 192.168.88.103:8082 weight=2 **max_fails=2**; #tomcat2 server 192.168.88.103:8084 backup ; #tomcat3 } location / { proxy_pass http://xxx.com; proxy_redirect default; proxy_connect_timeout 10; }
5、健康检测
5.1、consul注册服务
curl -X PUT -d '{"ID":"order_1","Name":"order","Tags":["xdp- \/core.order"],"Address":"192.168.232.201","Port":18307,"Check": {"name":"order_1.check","tcp":"192.168.232.201:18307","interval":"10s","timeout":"2s"}}' http://192.168.232.204:8550/v1/agent/service/register
5.2、nginx_upstream_check_module模块主动检查健康状态
模块配置
upstream cluster { # simple round-robin(默认是简单的轮徇,加weight就是加权轮徇) server 172.17.2.235:80; server 172.17.2.235:81; server 172.17.2.235:82; check interval=3000 rise=2 fall=5 timeout=1000 type=http; # 每隔三秒检查后端真实节点状态,成功2次为up状态,失败5次为down状态,超时时间为1秒,检查类型为http check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; # 返回2xx,3xx状态码为正常状态,其它状态码为down状态 } server { listen 80; server_name _; location / { proxy_pass http://cluster; } # 查看后端服务器实时的健康状态 location /status { check_status; access_log off; } }
6、多分组、多机房抗风险
7、隔离
爬虫隔离、热点隔离、查询隔离、数据隔离
8、cap理论
9、base理论

浙公网安备 33010602011771号