这个话题是从我对 Amazon 云平台的工作流框架 AWS Flow Framework 的使用研究中想到的,对于一个工作流引擎来说,一个完整工作流的某个阶段完成后,当前阶段的状态必须要被存储下来。
Workflow(Decider) 来决定任务的执行流程,Activity 来执行实际的任务,二者都封装在相应的 Worker 中执行,但不直接交互,而是通过 SWF 管理起来。不过,除了 SWF 的日志,它们都不记录任何当前任务执行状态的信息,即所有的任务执行情况只能从 SWF 的日志中找到。譬如一个 Workflow 由 Activity1 和 Activity2 组成,在执行完 Activity1 之后、要执行 Activity2 之前,Workflow 并不知道 Activity1 已经执行,而是询问 SWF,SWF 从日志中查询并告知。
这整个看似把流程变复杂的办法(被称作 Replay),带来了一个好处,避免了在 Workflow 中记录某个工作流当前执行的状态,而且,当某一步执行遇到了问题,很容易进行某一 Activity 的重执行和整个 Workflow 的失败操作。
这以后,我觉得最容易联想到的是 EJB 中的 stateless bean,它们不包含用户相关的数据,资源需求少,执行速度快,还很容易被池化。当服务提供变成无状态的时候,横向扩展能力就很容易做到,因为不会有状态存储方面带来的瓶颈。
关于无状态方法:我不知道这样的叫法合不合理,当方法不受到方法外的状态变量影响,输出只取决于输入参数,结果仅通过返回值返回,这样的编程就成了函数式编程。函数式编程带来了很多好处,例如没有外部变量和副作用,支持闭包和高阶函数、支持懒惰优化,和容易使用递归控制流程等等。
HTTP 是无状态协议,这就是说,HTTP 报文不会记录任何前面报文中所携带的当前客户端或者服务端的状态信息,报文简单而且不承载任何业务信息,但是互联网世界是有状态的,于是客户端有了 Cookie,服务端有了 Session。相较而言,其它有些协议是有状态的,例如 DNS,它的报文将承载及其上的一些资源服务器的分布信息等数据,因为这样的协议将要传递的信息的语义规则定义在协议里了。
另外,关于网站优化方面的一些例子。相较于那些新闻类网站(它们的网站信息展示由少数编辑完成,大部分的东西在不同用户的浏览器上呈现是一致的,这些页面的访问可以获得很高的性能),Web2.0 的应用(如各类 SNS 网站),情况的复杂性显然不可同日而语,当一个页面用户相关时,或者说包含大量用户相关数据时,这样的页面是有状态的,随着用户不同而动态变化的,那么它们的性能优化就会复杂一些。这里容易想到一个思路是抽象出那些变化的数据或者页面片段来,让那些无状态的页面成为片段缓存的主要承载体。
最后,再回到这个 AWS Flow Framework 上来,“ 无状态” 给它带来的仅仅是本文开头提到的好处吗?似乎不止,“ 状态” 的存在就意味着状态的同步问题,即状态在 Workflow、SWF 和 Activity 之间的一致性问题,而一致性问题往往是伴随着瓶颈产生的。分布式系统中,如果引入了状态的保持、分发和传递,很可能会带来单点业务而产生的问题,例如难以做到去中心化,难以做到节点平等和业务平均分布等等。
一个完整的对象,是既需要改变状态的操作,又需要保持状态的属性的,世界亦如此;而做软件,正是改变世界状态这样一件充满意义的事。
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》