访问式的web服务(一)

100 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

web服务的特点都是快速服务的,一个操作要在短时间完成,并响应用户。

但是这样有一些耗时的操作就没法做了,只能使用其他方式了。

还有一些问题,也是传统web服务:“访问一下就操作,再返回,没人访问就是死的”,这种模式所达不到的效果。

RabbitMQ - RabbitMQ tutorial - Work Queues

This concept is especially useful in web applications where it's impossible to handle a complex task during a short HTTP request window.(这个概念是特别有用的,web应用程序是不可能在一个短的HTTP请求窗口中处理复杂的任务。

要改变当前这种情况,就需要使用新的开发模式和技术了,目前来看主要有三种:

  1. 定时任务(例子:定时器)
比如每隔几秒钟执行一次什么任务,特点是高频,定时器模式,强调的是每隔多长时间执行一次。例子:每隔三秒钟做一次日志整理备份;每隔一秒钟做一次缓存检查;每隔一秒钟扫描一次所有下线用户,并作下线处理。
  1. 计划任务(例子:闹钟)
比如每天的闹钟,每个星期几做什么事,特点是重复,比如每天的闹钟,每天都会响(如果我要设置一个十五天后提醒我的闹钟就不行了,这时就得用代办提醒的程序了)
  1. 延时任务(例子:代办提醒)
比如三天后提醒我做什么,一个月之后自动执行什么事情,特点是单次,执行后就完成了,如果你需要3天后做什么,还需要9天后在做一次,那么你就添加两个这样的任务就行了
  1. 队列(例子:餐厅排队)
队列的意义其实是缓冲,如果某个操作费时,并且业务不依赖它马上返回执行结果的操作就可以放到队列去,要求的是越快做完越好,

注意这里面很重要的一点要考虑,那就是阻塞。被调用方执行过程中是否会阻塞当前调用方。比如定时器是否会被阻塞,如果被阻塞了,那么就不能按照理想的状态一秒钟执行一次了(目前定时使用无限循环和延时睡眠的方式实现的,不知道还有没有其它方式实现),另外多任务的执行,是不是要开启多进程,不然太耗时了。要弄懂这里面的细节,就必须彻底理解程序/进程底层有哪些调用方式。(TODO 待测试:可以拿swoole的定时器做下试验)

有时候需要这几种方式配合起来应用,比如我网站有一亿会员,我是管理员,我现在需要给每个发送会员通知,这么多人,我不可能直接执行发送的程序。

所以我可以把发送会员消息当成一个任务,任务里面有我要发的内容,以及是否为全部成员(也可以是几个会员的id),我写好内容后点击发送就创建这样一个任务可以了,然后另一个程序在后台执行这个任务就可以了(得到任务数据,给每一个给用户发消息),让它在后台慢慢发就可以了,这样我就不用守着程序执行了,其实这就是队列(这个群发的队列跟普通的还有点 差别呢,那就是它在执行的过程中还会更新任务的数据,比如更新已发送了多少,当然可以用其他方式)。

如果情况变成我需要三天后执行这样的任务,那么此时就可以使用2,3两种配合了。创建一个2的任务,任务要做的事就是三天后在创建3的任务/队列。甚至这个给一亿会员发消息做一个队列不好,还可以拆分为每个用户一个队列,总之任务自己还可以创建任务。任务之间是灵活的。

这样不光解决了大任务(复杂耗时任务)不适合 **“传统的基于访问式的web服务”**来做的问题,更重要的意义其实是系统的解耦,这样将复杂的系统模块化了,降低了系统的耦合程度,系统的稳定性,可用性将大大提高,而这是大型系统所必须的面对和考虑的。

定时取决于你对时间精度的要求,最小时间是xx,你不会有这样的要求吧,就算你要求的时间精度很高,要知道cpu的时钟频率是xx,当然每个进程不可能完全独占cpu的时间片,而是每个进程占用一小部分cpu的时间片,cpu每次执行每个进程的一小段,不断地在各个进程中来回切换的。不过它还是很快。对于你的时间精度要求足够了。

时间要求精确的用延时队列(精确程度还是取决于工人数量),比如,半个小时后通知我,15分钟未支付订单自动关闭/三天后自动确认收货等等。要求不精确的用计划任务,比如每天晚上统计一些信息,给超过三十天未登录的用户发送邮件等等这样的任务可以使用计划任务做。

计划任务和队列;计划任务,按时间计划,做某事。而计划,展开那就多种多样了,有一次的,有每个月的,多次的,等等,总之是围绕时间的计划。

队列类型:1. 即时队列;2. 延时队列。

(RPC本质其实也是访问时模型的)

这三类又带来了一个问题,那就是:处理程序在什么时候执行?或者说被触发:

  1. 在死循环中执行
  2. 用系统的定时任务触发
  3. 其他程序的触发

(有些情况可以让用户访问时触发,有些则需要单独用后台进程去触发,比如DZ的定时任务就是访问触发的,文章的按时发布,还有的针对用户的业务功能,也可以让用户访问时触发,当然也可以其他进程触发,如果其他进程不及时/实时的话,那么访问时触发就弥补了这个问题。)

image.png