限流讨论
我来开个话题
小型分布式微服务系统
考虑点: 分布式事务处理、redis作分布式锁、消息队列限流
我想 考虑这三点是否已经足够了
分布式事务怎么处理?
消息队列怎么限流?假设客户端是浏览器,能限制浏览器的流量吗?
首先我们需要花一周进行技术调研和评估,大概需要花费 10000元,请先拨款。
牛逼啊,
我上次调研,公司给我三周时间,我三天就回来了
你们不出调研目标和调研内容吗?
浏览器流量 我想先用 网关拦截一下 一些同样重复性的操作接口
可以用代理服务器和网关限流吧。
消息队列就不是用来 干你说的这个事的
那我打开一个网页,还不知道什么时候返回吗?
你进消息的时候,客户端(浏览器)和服务端就失去链接了。
就是我打开一个网页,你把流量打到消息队列,让后返回我成功,我客户端相当于什么数据都没拿到。
你像双十一 高峰的时候 你下订单完 订单列表都不一定马上显示的
你这个场景限制太死了(下单),如果就是查询呢?
也就是 说 你想 调一次接口 就把该接口业务都处理完毕再返回
那就达不到限流效果了
限流原因是系统无法第一时间 处理所有进来的请求,超过处理最大能力,需要设置一个系统能接受的能力范围 慢慢处理请求
是啊,所以我说一但使用消息队列就异步了,很多场景都不适用。
如果只是查询,那没必要限流,天然的幂等性
如果是涉及数据变动,那就作延迟处理呗,请求进来扔消息队列,直接返回前端接收了,等待处理的状态
进消息队列,只是依次执行,不代表连接断开啊,不断开连接,就能返回消息
队列不在具体的应用中
不在具体的Controller
你打开网页,发送的请求,创建的socket连接,没有断开。 tomcat服务器把请求封装成请求对象和socket一起放入待处理队列,等待处理完,你的socket就可以向客户端发送数据了。 这种队列都不在应用层面。
你能保证接受socket的服务器和处理消息的服务器是一个服务器吗?
假如你的请求就是了为了查询一篇文章,肯定是要给你返回文章内容的啊。不可能说我们已经接收了你要文章的请求,并且把请求记录下来放入消息队列。你可以放心了………………
当然能保证了
都到tomcat了。
tomcat就是服务器
软件层面的服务器,不是硬件。
限流是分多个层级进行限流的。
从网关,到服务器,再到应用内部;三个层面都可以做,这三个层面,咱们都从软件层面进行讨论,比如分别是: nginx, tomcat, myOrderApI
队列也是三个,分别在nginx自己队列,tomcat的队列,myOrderAPI的队列。
只有myOrderAPI层面的队列咱们自己控制。
myOrderAPI中放一个队列,这个队列来干什么呢?
把什么东西放入队列呢?
可以移步处理的任务才能放进去吧,我感觉。 比如发邮件、短信、记日志,通知其他系统。
假如myOrderAPI中有个Action就是为了,返回订单详情,不明白把什么东西怎么放入队列……
所以,修改、新增、删除操作都可以放入消息队列,告诉客户ok,我已经记录了你的请求。你可以走了。客户走了,消息消费程序可以从队列中取出一个一个对象,该删就删,该改就改,该增就增了?
查询我觉得相对好处理点
第一面先缓冲抗,redis正面抗住
第二面 redis没了,再走es库查询,保证查询效率
至于新来的数据,就等kafka消费了,消费完了同步到es库
也是 网关、ng、tomcat都可以做限流
我是这么想的 网关、ng、tomcat就处理那些乱七八糟的请求
对了接口层面 就处理真正合理有效的请求了 是真实性高的真实用户请求了
查询的感觉不用放入队列
对的,消息队列天生异步,凡是人家等着返回的都不能用消息队列。
那我就反问了,电商系统订单处理,如果有很大的并发数据量的话,很明显在极短的时间是无法进行消费的,那么为什么下了订单之后,就立马提示成功了?根本没有延时感,并且在订单列表页存在该条订单?
还是 成功下单的状态
种应该是服务多,消费能力强,但是也有个上限的,并不是所有相同处理都能实时处理,或许就是刚好你排队是靠前,消息队列马上收到了 处理了
会不会是虽然不能在100毫秒内把请求处理了。但是1秒钟肯定能处理完?
对个人来说,从下单成功页面跑到订单列表页面怎么也得两三秒吧。
消息队列天生异步,凡是人家等着返回的都不能用消息队列。
这个成功只是到达消息队列成功了,和真正的成功是有区别的。实际上消息队列处理会失败,一直失败的还得人工介入处理。
是的 如果消费队列有问题 代码不健壮
那就是一个通宵加班的故事了
我们对定时任务 队列消费失败 作了短信、邮件提醒
大面积出现 就得随时加班