Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

后端服务与多核 CPU

  有些后端服务本身对多核 CPU 的支持并不好,比如 MySQL 就是单进程的,所以我们在多核服务器上部署 MySQL 服务时经常会使用多实例的方式部署。而像 nginx 那样的服务本身就是多核 CPU 友好的,甚至还自带配置项,所以从来没见过谁把 nginx 用多实例的方式来部署。
  我觉得,多实例部署本身就不是一个服务常规的部署方式。如果一个服务做得足够好,它应该自己提供友好的多核 CPU 支持。因为只有服务自己知道什么时候最该去使用多核 CPU 资源。
  有些服务可能大部分时候并不是运算密集型的,只有某些特殊操作才会触发大量运算。对于这样的服务,最好的实现方式应该是自带进程池,自己在最需要计算能力的时候把 CPU 利用起来。假如这个应用在开发的时候就没考虑多核 CPU 会怎么样?也许有人就会回答,开多实例跑咯。可是开多实例真的就能充分利用 CPU 了么?这并不正确!假如现在有一台 16 核的服务器,多实例就是开 16 个这个服务的进程,于是可能会得到 16 个端口。如此部署之后,为了让入口统一,我们可能需要再开一个进程来做负载均衡。姑且不考虑这个负载均衡进程的开销,16 个实例跑在 16 个 CPU 上造成结果就是每个实例只能使用一个 CPU 的资源。如果这个服务的 QPS 很高,每个进程都有计算密集型的任务在跑,CPU 资源稀缺,这时候确实没有问题。但如果这是个 QPS 很低的内部项目,同时可能就一个用户在执行一个计算密集型的任务,那么这个用户只能使用一个 CPU 的资源,因为这个用户的访问只被分配到了一个实例上,而一个实例都只跑在一个 CPU 上,其它剩余的资源完全都是浪费的。
  另一方面,多实例会造成极大的内存资源浪费。因为每个实例在启动时总是有一堆初始化的工作要做,而且很多数据是被初始化后放入内存里的。比如某个服务为了性能优化,会在启动时将一个几百 MB 的文件读入内存。如果这样的服务实例被启动了一堆,那么内存就白白被浪费掉了几个 G。如果内存资源不充裕的话甚至有可能造成内存申请失败而无法初始化实例。
  有人说,多实例比单实例稳定,因为挂掉一个另一个还能跑。但是想想看,多实例是需要额外做负载均衡的,如果负载均衡本身挂掉呢?那不是和单实例的情况一样么?也许还可以反驳我说,负载均衡没那么容易挂掉,业务实例才比较容易挂掉。好吧,首先,就算是单实例的业务服务我们通常也会为其开一个守护进程,就算挂掉了也能迅速重启。而且保障服务稳定不应该以实例为单位,应该以机器为单位,哪个傻逼会把关键业务单机部署?万一被雷劈了怎么办?至少得多机器吧?现在大家害怕挖掘机袭击还搞多机房呢!甚至有些土豪公司还搞异地多活呢。如果真是单机部署的非关键业务的话,挂就挂呗,大不了就是让用户看到一瞬间的「服务器未知错误」之类的东西,服务被守护进程重新拉起来后就恢复。而且这种服务奔溃的情况通常是遇到一些极端异常才会出现的,应该监控下来让开发赶紧修掉。
  总结一下吧。我想输出的思想就这么两个:
    1. 服务应该自己提供多核 CPU 的支持,然后单实例部署。
    2. 不要基于多实例的奔溃来确保稳定性。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^