42 | 如何应对突发流量:漏桶和令牌桶的概念
温铭
该思维导图由 AI 生成,仅供参考
你好,我是温铭。
在前面几节课中,我们学习了代码的优化和缓存的设计,这两者都和应用的整体性能息息相关,自然值得我们重视。不过,在真实的业务场景下,我们还需要考虑到突发流量对性能的影响。这里的突发流量,可能是正常的,比如突发新闻、促销活动等带来的流量;也可能是不正常的流量,比如 DDoS 攻击等。
OpenResty 现在主要被用于作为接入层的 Web 应用,比如 WAF 和 API 网关,这些都要应对刚刚提到的正常和不正常的突发流量。毕竟,如果不能处理好突发流量,后端的服务就很容易被打垮,业务也就无法正常响应了。所以今天,我们就专门来看下,应对突发流量的方法。
流量控制
流量控制是 WAF 和 API 网关都必备的功能之一,它通过一些算法对入口流量进行疏导和控制,来保证上游的服务能够正常运行,从而让系统整体保持健康。
因为后端的处理能力是有限的,我们需要从成本、用户体验、系统稳定性等多个方面来综合考虑。不管使用哪一种算法,都不可避免地会造成正常用户请求变慢甚至被拒绝,牺牲部分的用户体验。所以,流量控制是需要在业务稳定和用户体验之间做平衡的。
其实,在现实的生活中,也经常会有流量控制的情况。比如春运等高峰期的地铁站、火车站、机场等交通枢纽,这些交通工具的处理能力是有上限的,那么,为了保证交通安全运转,就需要乘客排队等候、分批次进站。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
突发流量对Web应用性能的影响不容忽视。本文介绍了漏桶和令牌桶算法作为应对突发流量的方法。漏桶算法通过控制请求速率,保证流量平滑,确保上游服务的稳定性;而令牌桶算法则允许突发流量传递到后端服务,具有更弹性的特点。文章通过实例代码和生活场景的类比,生动地解释了这两种算法的原理和应用。读者可以根据自身情况选择合适的算法来应对突发流量,以保证系统的稳定性和高效运行。 此外,文章还介绍了Nginx中的限速模块,通过简单的配置实现了限速功能。然而,Nginx中设置限流限速的最大问题是无法动态修改,需要重启才能生效。最后,文章提出了一个思考题,探讨了如何识别正常用户请求和恶意请求的方法,以及如何在接入层直接拒绝恶意请求的问题。 总之,本文深入浅出地介绍了突发流量处理算法和Nginx的限速模块,同时引发了读者对于恶意请求识别和拒绝的思考。这些内容对于Web应用性能优化和安全防护具有重要意义。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《OpenResty 从入门到实战》,新⼈⾸单¥59
《OpenResty 从入门到实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(8)
- 最新
- 精选
- 许童童可以加黑名单,WAF最总要的就是模式匹配与数据过滤,找到一些恶意请求的特征并过滤掉,最好是使用ModSecurity这类比较成熟的解决方案。2019-08-304
- wusiration针对恶意流量,通常是通过一些特征识别来判断,然后进行一定时间的拒绝访问控制;若再次攻击,则直接封禁。感觉这种手段有点类似于反爬虫2019-08-303
- Geek_30e2481、黑白名单 2、错误指数间隔重试2020-12-162
- 杨丁增加ip黑名单机制,但难点在于ip黑名单的定义,比如单日总数或单日请求占比数2019-08-301
- forever温老师,您好,最近在开发过程中,使用lua-resty-rate来限速,但是无论是用imcomming还是用是用take_available方法,日志里面总是灰报dictionary not fount 代码: local token_lim_global, err = token_limit_rate.new("my_token_limit_store_new", interval_global, capacity_global, quantum_global, nil, { lock_enable = swith_flag_global, lock_dict_name = "my_lock", }) if not token_lim_global then ngx.log(ngx.ERR, "failed to instantiate a resty.limit.rate object: ", err) return ngx.exit(500) end local key = ngx.var.binary_remote_addr local delay, err = token_lim_global:incoming(key, true) if not delay then if err == "rejected" then return ngx.exit(503) end ngx.log(ngx.ERR, "failed to take token: ", err) -- 这里的err里面信息是 dictionary not fount return ngx.exit(500) end 我openresty http模块下面已经配置了: lua_shared_dict my_token_limit_store_new 100m; lua_shared_dict my_lock 100m; 报错信息就这样一个,一直找不到原因,希望老师有空帮忙知道一下,谢谢了2020-03-11
- slarkwaf砍一刀,网关砍一刀,这二者在云架构里是不是可以合并最好2020-02-29
- Sirexcess = max(tonumber(rec.excess) - rate * abs(elapsed) / 1000 + 1000,0) 这个公式,后面的 +1000没有看明白2019-09-181
- krugle想请教个问题,实在是找不到资料,我们需要绑定几千个域名,导致每个worker进程内存占用很大,想用lua动态加载证书,ssl_certificate_by_lua_file,我看了很多例子 也是按例子写的,但是偶尔出现某个域名出现不安全连接的提示,再次刷新就好了 if pemData == nil or keyData == nil then ngx.log(ngx.ERR, "faile to set ssl") return ngx.exit(ngx.ERROR) end local cert, err = ssl.parse_pem_cert(pemData) if not cert then ngx.log(ngx.ERR, "failed to parse PEM cert: ", err) return ngx.exit(ngx.ERROR) end local ok, err = ssl.set_cert(cert) if not ok then ngx.log(ngx.ERR, "failed to set cert: ", err) return ngx.exit(ngx.ERROR) end local key, err = ssl.parse_pem_priv_key(keyData) if not key then ngx.log(ngx.ERR, "failed to parse pem key: ", err) return ngx.exit(ngx.ERROR) end local ok, err = ssl.set_priv_key(key) if not ok then ngx.log(ngx.ERR, "failed to set private key: ", err) return ngx.exit(ngx.ERROR) end 代码主要是这样的,可能有什么原因,我自己查的话完全没有方向2019-08-312
收起评论