在当前互联网场景下,消息队列作为业务解耦的中间件服务,已经越来越多的得到了应用;
但是,在实际的部署中,我发现有相当多的开发人员,把队列的消费代码,直接写到了Web站点的代码里,并且部署上线。
应该说,在小规模的应用场景下,这种作法没有太大的问题:
- 开发简单,一个项目完成所有业务场景;
- 部署简单,只需要部署一个站点就完事了,后续的更新维护和日志排查,也只需要看一个地方就ok。
但是,在规模较大,或一些相对复杂的应用场景下,这么部署会存在如下问题:
- 消息消费必然会占用线程,在并发高时,会导致线程不足,无法及时接收用户请求;尤其是消息处理慢的场景;
- 站点启动时会自动启动消费者,不受nginx或服务注册控制,
在有隐藏bug的代码发布预发环境时,无法进行验证就自动上线了,
只能添加额外的是否开启消费者开关,增加开发复杂性; - 消息突增造成消费者阻塞时,必然对站点服务造成影响,在考虑解决方案时也要评估对站点的影响面;
- 消费者业务逻辑修改和发布,也需要站点停服,在业务高峰时一般不允许站点停服。
基于这4个原因考虑,我一般都是要求:消费者作为独立进程,分开部署,不允许跟站点一起部署;
开发时,如果是DotNet Core或Java服务,可以在一个项目里开发,用同一套代码分别部署站点 和 消费者进程,
部署的消费者进程,不应对用户开放服务(不进行服务注册,也不加入nginx后端)。
公司的同事有一些异议,他的建议是:
- 消息处理本质上也是对业务请求的响应,只不过请求方是MQ而已,如果不存在性能问题,业务逻辑简单的,还是应该跟关联业务一起部署,降低部署和维护的复杂性;
- 性能低下的,耗时较长的,业务逻辑复杂的,或者依赖较多的消费者,可以考虑独立部署。
- 不应该一刀切,要根据业务实际情况考虑。