背景
随着容器化、云原生等的流行,DevOps团队也在不断鼓吹「以无状态为荣,以有状态为耻」。因为有状态的服务难以部署、难以扩展。下面我举几个自己工作中实际的例子。
实例1-依赖系统目录结构
刚转来基础架构的时候,接手了一个服务,原来是个应届生写的。所以可以理解,也就是基本能完成功能,反正也不是核心服务。
刚拿到的时候下载下来本地运行没成功,报错是说对某个目录下没有某个文件。读了一下代码发现是启动时需要加载一个本地认证的证书。从发布脚本目录下找到了那个证书文件,放到指定目录下后运行成功。
后来把这个证书的内容放到了公司的秘钥统一管理服务上,就实现了更加安全的无状态化了。
无状态是指服务内部变量值的存储,这里证书文件是存储在服务器上的,那就是这个变量值,是一个状态。
实例2-依赖服务器上脚本
之前在金融那边有个兄弟是从「去哪儿」过来的。当时我们聊起日志的定时归档。一般java日志组件都带有这个功能。但是在「去哪儿」的时候他们采用的cron脚本来实现。原因是更省资源更高效。
后来我自己想了想,在一般的项目中还是更建议用自带的日志组件。因为便于统一管理,可移植性好。
仔细分一下领域:日志和业务逻辑分开,没有问题。但是日志需要和服务分开吗?服务性质、打印日志的级别、服务的量级直接决定了日志文件的大小以及归档策略。如果需要调整时要找另一个地方就不太合适的。
如果这个东西真的和业务逻辑一点关系都没有。那就会有一个专门的服务比如在linux系统层自己去处理这件事情,我们就不需要感知了。
无状态是指服务内部变量值的存储,这里服务器上的脚本就是那个状态。
实例3-zookeeper和DB
zookeeper、分布式共识、分布式协调、leader选举、master-slave五个概念都不知道的可以跳过这个例子。不影响理解本文的核心。
zookeeper和目前经典数据库部署既然有master和非master之分。那么就是有状态的,是否为master就是一个状态。
这个状态会引起什么问题呢?
不容易水平扩展:经典的线上mysql部署方式是1主2从或者1主3从。只有主节点负责写。压力扛不住了,可以纵向升级,就是提高机器配置。或者垂直拆分,业务自己去拆库拆表。
节点多反而引起性能下降:zookeeper也好、mysql也好,之间要通信,节点越多开销越大。zookeeper用Paxos来解决拜占庭将军问题的时候,节点越多,可用性是越差的。这个不解释了。知道有状态不好就OK啦。着实,像数据库、图片存储服务这样的,本质就是磁盘存储的,是做不到无状态的。这会增加一些部署上的困难,但是是可以接受的。但是对于外侧业务来说,如果是有状态的,就需要问自己一下:是否可以通过引入中间件等策略来消除状态?
内推
最近陆续收到一些朋友让帮忙美团内推的的消息,非常欢迎!内推请自助。填写完材料我会收到消息,然后我会帮忙一起物色合适的职位。
校招
社招
相关阅读