去状态化
所谓的去状态化,就是应用程序一开始会有很多的数据,比如有些数据是保存在内存里,像会话的数据,有的是保存在本地文件系统、本地库里,像照片。去状态化做的事情没有那么难,把这些数据外置化就可以了,可以把会话放在缓存里,可以把用户数据放在数据库里,可以把照片保存在远程的分布式存储里面。仅仅包括商务逻辑、算法的应用扩展起来就非常方便,一变三、三变五,可以比较好地分担整个应用。其他有状态的事情就交给外面的缓存、数据库和分布式存储来做。开源软件和互联网软件发展到今天,外部的缓存、数据库和分布式存储都已经有了自己的集群模式,所以把它外置出来并不担心丢失。
容器化
无状态化以后,就可以进行容器化。有人说容器化就是微服务,微服务就是容器化,其实不完全。这里我们用Kubernetes进行管理,把一个服务拆成了四个服务,服务A、B、C、D,它们之间互相关联、互相调动。容器化并用Kubernetes管理以后,它的服务可以自发现、自修复。如果这时候中间的机器挂了,中间的B、C服务会自动迁移到另外两台机器上,重启以后IP地址可能会是改变的,那么服务A、D怎么找到服务B、C呢?Kubernetes会自动管理,Kubernetes中每个服务都有一个服务名,A调用B,B就是一个服务名。A不用关心B的IP是什么,也不用把IP配在配置文件里面,只需要把服务名配在配置文件。无论B迁移到哪个机器,A要访问B,Kubernetes会自动把服务名映射为B的IP地址访问过去。这样就会优雅地实现自修复以及负载均衡。如果发现B是瓶颈,原来B只有一个实体,现在B有三个实体,这三个实体还叫B,那么A访问时还是访问B,但是A访问时不用关心访问的是这三个B里面的哪一个,Kubernetes会帮我们选一个进行访问,这样就实现了负载均衡。
DevOps、可迭代
用这种方式,开发的整个流程会非常的顺畅。因为容器的镜像是不可变的,所以镜像把OS、业务代码、运行环境、程序库、目录结构都包含在内,好处是镜像无论放在测试、联调、生产环境里面,都能保证环境的一致性。其次,比如从1.0版本升级到1.1版本,发现1.1版本有点不对,要回滚到1.0版本时,也可以确认它就是当时的1.0版本。如果是自己手工调整的话,需要特别小心,过了一段时间可能会忘了自己做了哪些微调整从1.0版本升级到1.1版本。当然其中会有不一样的地方,比如说环境的配置可能需要通过环境变量或者更稳健的方式来注入测试环境、联调环境、生产环境。中间一个优雅的事情是,比如原来做一个程序往往会有三份配置文件,打包时也会把不同的配置文件放进去。如果以Kubernetes自发现的方式,把B的名字放到配置文件里就可以了。本地起一个开发环境,只要把B的名字设为127.0.0.1,在本地就可以相互访问。到测试环境,A访问B,配置文件是不用变的,访问的B就是测试环境里面的B。到生产环境里面一样,配置文件也不用变更,不用每次保存多份配置文件,开发流程也会非常顺畅。
微服务架构
这是最初电商的架构,本来是单体的架构,后来拆分成很多很多的子服务,包括前端的、业务系统、基础服务系统的,它们之间相互引用,利用Kubernetes相互发现。如果没有自发现的系统,维护起来还是比较麻烦的。这其实是考拉海购抽象化的模型,整个架构比这个要复杂。巨大的优点是,比如“双十一”来了,进行压测可以发现里面的瓶颈点,对瓶颈点可以进行弹性伸缩,对于非瓶颈点伸缩就相对小一点。大家不会在“双十一”那天疯狂的进行用户注册,但是下订单压力就比较大了。
从私有云到公有云
接下来,我们从私有云开始迈向公有云,开始对外进行服务。这还是有一些挑战的:
第一,容器的安全问题。如果我们允许用户共享主机,大家进容器是能看到这个机器上所有的CPU和MEMORY的,而不是仅仅只能看到两盒。如果是一个黑客,完全可以把旁边的容器黑掉,所以安全问题是一个非常关键的问题,安全问题一个解决思路就是KVM。