Web前端和worker服务通过一个消息队列进行通信。
这个架构中还包含其它一些组件:
- 一个/多个数据库
- KV Cache,用来降低数据库的负载
- CDN系统,提供静态资源的访问加速
- 远程服务,比如email或消息发送服务,通常是第三方的服务
- 身份认证服务,比如Google Oauth登录服务
Web前端和worker服务都是无状态的。作业的会话状态通常存储在分布式存储里(比如Redis集群)。worker通过异步的方式处理耗时的作业,我们通常使用消息队列来触发作业的创建和执行,或者通过一个定时任务调度批处理任务。worker并不是必须的,如果没有耗时的操作,就不需要它。
前端除了页面的部分,也可以提供web API(BFF层)。在client端,我们可以通过一个单页应用触发ajax请求,或者使用原生的APP去触发。
应用场景
Web-Queue-worker架构在云服务中很常见,比如函数计算服务(FAAS)。这类服务通常会提供 HTTP API 或 RPC API,同时支持消费Kafka来的流式消息。目前流行的低代码也是由此衍生出来的。
该架构适用于以下的场景:
- 应用的业务领域/场景比较简单
- 应用包含了一些耗时的工作流或批处理任务;
- 想要低成本地接入现有的服务,而不是从Infra开始搭建
架构优势
- 架构简单易懂;
- 部署和管理很简单;
- 服务职能边界清晰;
- 前端和worker是解耦的,消息队列使用现成的技术即可;
- 前端和worker可以独立进行扩容;
有哪些挑战
- 如果设计不合理,前端和worker都可能融入太多的逻辑,变得越来越重。后期演变成单体架构后,很难维护和升级;
- 如果前端和worker共享了一些数据结构或代码,可能会有隐藏的依赖;
最佳实践
- 暴露给client的API必须清晰明了,经过良好的设计;对于HTTP请求,可以遵循REST协议;
- 对于工作负载的变化,启动自动扩缩容;云平台和K8s都提供了监控实例CPU/内存自动扩缩容的能力;
- 对于半静态的数据,使用缓存进行加速访问;比如memcached/memory cache等;
- 使用CDN对静态资源进行缓存加速;
- 根据需求使用混合持久化方案。比如关系数据库和非关系型数据库混合使用,比如KV存储、文档数据库、搜索数据库、时序数据库、列式存储数据库、图数据库等。数据库之间,可以采用最终一致性方案进行数据同步;
- 对数据进行分区,分区可以更好地支持扩容,减少竞争读写问题,提升访问性能。