需求比较简单,提供一个异步Web服务供使用者调用。好比说,某应用程序须要批量地给图片加lomo效果。因为加lomo效果这个操做很是消耗CPU资源,因此咱们须要把这个加lomo效果的程序逻辑放到一台单独的服务器上去运行,以避免影响应用自己所在服务器的性能。html
这篇先讲讲服务的接口部分,侧重于理清应用和服务之间的调用关系,有时间的话,后面再写一篇关于服务内部任务分派资源调度的随笔。服务器
根据这个需求,咱们能够很快设计出一套流程:微信
Application经过向service的addTask接口post任务相关的信息建立一个任务,同时,service将此任务的任务id,即taskId返回给Application,以便Application接下来能够用这个taskId经过getStatus接口查询此任务的进行状态。app
问题一:异步
Application做为一个独立的应用,他确定须要有本身的任务管理逻辑。也就是说,Application在向Service发出建立任务的请求前,确定须要先往本身的DB中写入一条对应这个任务的相关数据,以便后续跟踪每一个任务的状态和数据。那么application在收到response时,如何将这个response的taskId和本身以前写入DB的那条数据对应起来呢?post
若是是上面的那种接口设计,应该是没法实现这个要求的。因此咱们须要给addTask接口加一个用来标记任务惟一性的参数customId。以下图:性能
问题二:设计
根据上面的设计,Application在建立task以后,会不断调用Service的getStatus接口,来获取该任务的最新状态,好比任务是在等待中、进行时仍是已完成。可是,这显然不是一个很是高效的方式。若是任务进行的时间比较长,Application则会在这段时间内屡次调用getStatus接口以及时获取任务状态信息。这样作不但加剧了Application的负担,更加剧了Service的负担。因此,咱们能够把这个地方的依赖关系反过来,让Service主动将任务的状态信息通知给Application。相应的,Service和Application的接口也要作相应变化:htm
如上图,咱们将原来由Application调用Service的getStatus接口的过程,改成了Service调用Application的setStatus接口。这样就实现了,一旦task状态发生变化,Service都能实时通知Application,从而减小了两个服务间无用的请求。blog
问题三:
假如,Application调用Service的addTask接口后,服务器由于种种缘由没法响应外部请求了。那么接下来,当task结束之后,Service就无法将这个重要的状态信息反馈给Application了。并且,因为Service不可能永远不停地尝试去调用Application的setStatus接口,直到成功。那么,当Application从新启动之后如何获取以前那个任务的状态就成了一个问题。因此,基于这样的缘由,以前的getStatus接口其实仍是有存在的必要的。
有了getStatus这个接口之后,如若Application在调用addTask之后出现当机等现象而错过了Service推送的task完成的消息。那么Application在从新启动之后,还能够本身经过Service的getStatus接口获取这个任务的最新状态。
至此,API部分设计完毕。
关于接口的部分,目前我所能想到的问题大概就这么多,不知道有没有什么遗漏或不妥。但愿你们不吝赐教,在下感激万分。
下篇:《如何设计一个异步Web服务——任务调度》
如需转载,请注明转自:http://www.cnblogs.com/silenttiger/p/4076333.html
欢迎关注个人微信公众号:老虎的小窝