阿男的小窝

View the Project on GitHub

云部署的特点

云部署需要项目最好是一个文件,现在各种框架都是朝着这个方向走。比如go语言,编译出来的项目就是一个文件,里面自带平台和各种包依赖。然后是spring-boot项目,项目编译出来就是一个jar文件,里面自带服务器,项目代码,依赖等等。下面是thorntailthorntailjboss社区针对microprofile标准做的实现,可以类比为spring-boot)编译出来的项目:

可以看到一个jar128M,这个jar里面包含了整个项目,包括服务器。我们可以大概看下这个jar里面的内容:

可以看到这个jar就是完整项目,并且可以独立启动:

这样做有什么好处呢?在云端,我们一边是把项目部署在容器里,而容器的尺寸越小越好,所以我们把最终build的项目变成一个文件,就可以很好控制最终部署用的容器的尺寸。docker在build过程中,对这种场景有考虑,把build过程所需要的容器和最终交付的runtime容器拆分开,叫做multi-stage build。就像下面这样:

可以看到第一个容器用来build,第二个容器直接拷贝第一个容器的build结果(也就是单个文件的交付项目)。上面的这个Dockerfile.multi所产生的两个images的尺寸:

可以看到,最终交付的image只有11.7MB,而build过程所使用的容器有293MB。所以,拆分build与deploy的容器,是云部署的需求,而最终交付的项目只有一个文件,会使得拆分边界十分清晰。以上是云部署的特点之一。云部署还有一个特点,就是容器要设计成无状态。我们看docker-compose的启动过程:

从上面的启动过程中可以看到,容器被创建了:

此时查看容器的运行状态:

可以看到被创建的两个容器。如果我们停掉这两个容器:

可以看到容器在被停掉的同时也被销毁了:

此时查看容器的状态:

可以看到之前创建的两个容器已经被销毁了。所以,如果容器里面保存了业务数据(有状态),就会被销毁掉了。上面是使用docker-compose的场景,在kubernetes的场景下,容器甚至会被动态的创建与销毁的。所以数据要分离出容器,独立处理,而容器要设计成无状态的。