创业公司的容器化之路

作者简介: 章烨明,杏仁医生CTO。中年程序员,关注各种技术和团队管理。本文首发杏仁医生技术站

1. 创业公司的技术挑战

托尔斯泰说:“幸福的家庭都是相同的,不幸的家庭各有各的不幸。”互联网创业公司也一样。大部分互联网创业公司,都会碰到以下几个技术挑战。

  • 如何快速、低成本的搭建系统,同时确保安全稳定?
  • 如何快速的构建和发布应用,满足业务需求?
  • 如何提高团队开发效率,确保开发质量?

这个列表肯定不完整,但这三个应该是创业公司技术团队都会面临的共通的问题。当然杏仁不能说完全解决了这几个问题,但还是取得了一些进展。我们接下来简单介绍下,我们杏仁是怎么应对这些挑战的,以及容器又可以带来什么?

该系列文章会分为三篇。第一篇介绍容器化之前,杏仁技术架构的发展历史。第二篇介绍容器以及杏仁的容器化方案。第三篇最后总结为什么我们认为创业公司应该用容器,以及为什么容器可以帮助我们应对这三个挑战。

2. 杏仁早期

在 2012 年以前,大部分互联网公司包括创业公司,都是直接购买服务器,租用 IDC 机房的机架部署的。应用是直接运行在物理机上的,要扩展必须购买新服务器。IDC 经常出各种故障,如果碰到 IDC 迁移的话,就更痛苦,必须半夜搬机器,天亮前上线。总之对创业公司的成本、服务稳定性、工作效率都是有很大的消耗。

不过杏仁医生很幸运,正好赶上了公有云的成熟,所以一开始就是基于公有云搭建的。杏仁医生最早期的架构如下:

图片描述

这个架构非常简单,其中负载平衡、数据库都是基于腾讯云的。然后腾讯云也提供了一些基础的监控、告警和安全服务。然后就是两个应用,一个移动后端 API,一个运营平台,都是基于 Play 的 Scala 应用。

很多人可能会好奇为什么选择 Scala/Play 进行开发,毕竟 Scala 在国内应该用的不多。这里一方面因为杏仁医生是继承了看处方的架构,当初看处方就是基于 Scala/Play 开发的, 团队对这一套方案比较熟悉。我们需要快速的构建杏仁医生,自然就会选择最熟悉的语言和框架。而且对于中小规模的应用,Scala/Play 的开发效率的确非常高。Scala 本身的表达能力非常强,是一门很有意思的语言。很多好学的工程师,也会对新的语言也会比较感兴趣。

3. 应用拆分和CI/CD

经过一年多快速演进,整个应用越来越庞杂。所以我们对应用进行了拆分,并且随着业务扩张,应用也越来越多,例如 HIS、CRM 等。所以我们的架构变成了这个样子。

图片描述

这时 Scala 最大的问题开始体现出来了,那就是编译速度的问题。那时候我们的应用部署方式也很原始,必须登陆服务器运行一个 Shell 脚本,它会拉取代码,然后编译、打包、运行,整个过程需要耗费5~10分钟。而我们 API 应用的节点后来增加到 5、6 台,即使两台同时发布,也需要 20 分钟才能全部发布完成。如果发布后出了问题,那就吐血了,因为回滚也是一样的流程,又需要 20 分钟。

有一次我们做了一个送 Apple Watch 的活动,半夜 12 点开始。我们出了个很低级的 BUG,活动一开始就蹭蹭蹭的一分钟送好几个 Apple Watch。我们创业公司也没多少钱,每一个都是白花花的银子,心痛啊。修复很简单,但发布或者回滚都得先编译,太慢了,于是我们一狠心把服务器给停了,几分钟后才部署上了新的代码。

这是我们觉得必须要有一个自动化的发布系统了。其实在几年以前,发布都是需要运维执行的,研发提交给运维,运维手动部署。那自然发布不可能很频繁,并且对开发和运维都是很大的负担。但渐渐的敏捷和 Devops 的文化成为主流,持续集成和发布(CI/CD)成为一项基础设施。

我们第一版 CI/CD 很简单,是基于 Jenkins 的,通过脚本进行编译、打包,然后拷贝到服务器上发布。因为只要打包一次即可,缓解了部署慢的问题。但还是存在几个问题。

  • 首先,没有应用仓库。打包是一次性的,部署的时候会备份当前应用目录,用于回滚,所以只能回滚到上一个版本。
  • 其次,健康检比较简单,只能检测应用是否启动。我们遇到过应用启动了,测活也没问题,但服务还是有严重问题、基本不可用的情况。
  • 最后,不支持灰度发布,出问题只能回滚。

期间我们有一次较大的故障,也是因为这几个因素,花了很长时间才恢复。痛定思痛,于是我们又开发了 Frigate 发布系统,它的架构大致如下图。

图片描述

  • Frigate 有一个应用仓库,即 App Repository。应用仓库会保存发布的应用版本,回滚的时候可以指定版本。

  • Watcher 组建实现了比较强大的应用检测功能。除了一般的 HTTP 检测,还可以从日志、监控里获取数据,可以根据异常数、错误率等进行进一步的健康检测。

  • Frigate 支持分组和分阶段发布。例如现发布2台机器,然后健康检查,或者中间可以有一些人工检查,然后再发布剩余的机器。

后来回头看,Frigate 虽然没有使用容器,但其实是实现了容器编排的很多功能。Frigate 发布的截图如下,这是基于 Jenkins Pipeline 的。

图片描述

4. 微服务化

系统多了,依赖复杂、数据没有隔离、逻辑重复,接下来一个必然的方向就是微服务。关于微服务,我们公众号有两篇文章(乐高式微服务化改造(上)、乐高式微服务化改造(下))对此有比较详细的分析说明,这里就简单介绍一下。

我们的服务注册和发现是基于 Consul 的,负载平衡是通过 Nginx 实现的。下图是整个服务注册和发现的过程:

图片描述

有几点是值得一提的。

首先,我们的微服务是基于 HTTP 和 Json 的,没有采用二进制的协议如 Protobuf、Thrift 等。其实 HTTP 和二进制协议的性能差别,并没有很多人想的那么大,一般也就2、3倍的差距(没有亲测)。对大部分企业,这个差别根本就不是瓶颈,特别是现在还有 HTTP2。如果真的有需要,还可以在 HTTP2 上跑二进制协议,通过框架在服务端和客户端加一层就可以实现。

其次,我们的微服务对应用是无侵入的。我们没有采用常见的 Dubbo、SpringCloud 框架。一方面我们服务调用方有 Java 应用也有 Scala 应用,要接入还是要花点功夫。另一方面,我们认为微服务框架发展的未来方向是非侵入性的独立的微服务基础设施层。其实这和容器编排的理念是一致的,并且最近提出的 Service Mesh 概念,就是进一步的延伸,我们认为这才是微服务的未来。

最后,我们每个微服务都会生成一个 SDK,便于调用方调用。SDK 集成了熔断、异步、分布式追逐(开发中)等功能。

搭建了微服务基础框架后,我们开发了好几个微服务,有业务的例如订单、预约等,有基础设施的例如推送、短信等。当然其实有些并不算“微”。

但是我们发现,整个体系依然存在不少问题

  • 基于云服务,成本低了,效率高了。但运维还是面向资源的,并且资源利用率不高。

  • 有了持续集成和部署的能力。但新增节点、新建服务等,依然需要大量人工运维,并且扩展并不方便。

  • 实践微服务,改进了应用架构。但依赖管理、监控等尚未完善,稳定性仍然不够。

5. 容器是什么?

上面我们简单说明了杏仁容器化之前的架构发展。下面我们就来谈谈容器。

2013 年 Docker 横空出世,到 2015 年已经渐渐进入大家的视野。容器当然不一定是 Docker,而且容器现在也是有标准的。但一说容器大家肯定会想到 Docker。所以我们这里说的容器,主要就是指 Docker。

容器到底是什么呢?顾名思义,容器就是用来装东西的。在这里它用来装的就是应用程序。容器的特点简单说就那么四点:

  • 容器是自包含的,它打包了应用程序及其所有依赖,可以直接运行。以前应用程序的依赖管理一直是个大问题,即使像 RPM 、Maven、Ansible 等都能解决一部分问题,但并没有一个所有应用程序通用的标准机制,直到容器出现。

  • 容器是可移植的,可以在几乎任何地方以相同的方式运行。这就可以确保应用在开发环境、测试环境、生产环境等都有完全一样的运行环境。

  • 容器是互相隔离的,同一主机上运行的多个容器,不会互相影响。即一个容器中运行的应用程序,是访问不到其他容器的资源的(进程、网络、文件、用户等),除非配置为共享的资源。

  • 容器是轻量级的,体现在容器的秒级启动,并且占用资源很少。

容器能做的很多事情,虚拟机也能做,那它们有什么区别呢?下面这张图是 Docker 官网的截图,很好的说明了两者的区别。

图片描述

但最根本的差别,其实就是最后一点:轻量。很多人可能觉得这只是一个简单的差别,但其实不是。因为就是这一点使得容器可以成为一种 标准化的应用发布方式。

上个世纪 5、60 年代集装箱刚出现,看上去也只是简单的差别,也没有什么技术含量。但集装箱提供了一个标准化的物流方式,全球的海陆空运输、码头装卸等围绕集装箱形成了整个一个高效的物流体系。最终改变了世界贸易,促成了全球化。

所以容器这个标准化的应用发布方式,最终会影响上层的整个应用架构。最终围绕容器,会建立一套完整应用架构体系,带来革命性的改变。现在其实已经可以看到一点端倪了,Kubernetes 基本已经成为标准,不久前 Google 还发布了 Istio 这个 Service Mesh 工具,进一步把微服务的基础架构也抽象了出来。

6. 容器编排是什么?

光有能装应用的容器还不够,如果还是人工管理那么多容器,那也发挥不出容器的优势。所以我们需要一个容器编排系统。容器编排能提供以下功能:

  • 应用调度:应用部署、无缝升级、弹性扩展、自愈等。
  • 资源管理:内存、CPU、存储空间、网络等。
  • 服务管理:命名空间、负载均衡、健康检查等。
  • 以及很多其他功能,如日志、监控、认证、授权等。

容器编排领域最主要的三个系统是 Docker Swarm、Kubernetes 以及 Marathon/Mesos。

Swarm 是 Docker 官方的方案,优点就是简单,缺点是太简单了。

然后是 Google 的 Kubernetes,也叫 K8s。Kubernetes 最近一年大放光彩,几乎统治了容器编排领域,就连 Docker 官方不久前也宣布了支持 Kubernetes 。它的优势就是有大厂支持,而且 Google 是把它作为战略来布局的,你可以把它想象成当年的 Android;它的社区也非常火爆。

技术上,Kubernetes 是一个集成的方案,设计非常优秀,可以说是分布式系统的设计典范,Google 在这方面毕竟有很深入的经验。缺点就是有点复杂,而且在今年之前它还是存在不少问题,包括性能问题、大版本的兼容性、部署复杂等,当然现在已经基本解决了。

Mesos 在 Docker 之前就有了,本身做的是分布式系统的资源管理,Mesos 很灵活,上面可以支持各种系统,包括 Spark 等。Marathon 则是基于 Mesos 实现了编排的功能。

我们是去年年中考虑容器化的,我们最后选择的方案是 Marathon/Mesos。原因一方面是之前 Jenkins 容器化已经用到了 Marathon/Mesos,有些经验。另一方面是该方案便于和当前的架构整合。Kubernetes 太过复杂,迁移的话,对架构改动太大。

7. 杏仁的容器化

我们容器化之后的架构是这样的:

图片描述

所有的应用都以容器的方式运行在 Mesos Slave 上,Mesos Master 统一管理 Mesos Slave 服务器。Marathon 通过 Mesos 调度容器,进行发布、升级、扩容等。Calico 是 Docker 的网络解决方案,实现了一个容器一个 IP 以及容器之间的互联。而右上角部分,我们基本保留了我们之前的微服务架构,只是用于服务发现和注册的 Consul Agent 替换成了 Registrator。

同时我们的 CI/CD 也相应的做了调整。

图片描述
Jenkins 自身现在也是基于容器的,会在 Mesos Slave 的容器里进行编译和打包。应用会被打包成的 Docker 镜像,上传到我们的镜像仓库 Harbor 里。部署时,Jenkins 调用 Marathon 的接口进行部署,Marathon 则从 Mesos 申请资源。部署时 Mesos 会从 Harbor 下载相应的应用镜像并根据配置运行。

有了这套系统,我们创建应用、扩展应用就很简单了。创建应用时首先通过 Dockerfile 和 Jenkins 创建镜像,然后在 Marathon 界面上,只需要准备一个 Json 配置(也可以通过 Form 配置),指定资源、实例数、镜像、网络、健康检查、环境变量等,就可以很快上线一个新应用。

图片描述

有时候我们要准备一个秒杀活动或者推送几百万用户,需要增加应用实例,也只要在 Marathon 界面调整一个数字就可以了。

图片描述

除了容器编排和 CI/CD,还有两个很基础的东西,一个是基于 ELK 的统一日志平台、另一个是基于 Open-Falcon、StatsD、Graphite、Grafana 的 监控告警平台。大致结构如下,具体实现以后有机会再专门写文章介绍,这里就不详述了。

图片描述

最终,我们的整个平台的组成是这样的:

图片描述

8. 容器化总结

到这里为止,这些就是杏仁目前的基础平台的架构。通过这套系统,我们提升了资源利用率,刚刚迁移到容器化环境的时候,我们只用了原来大约 6、70% 的云服务器。并且我们大大加强了我们的自动化运维的能力,完善了服务监控。

但是这套系统也存在不少问题。

  • 新增服务器节点还是需要一些手工操作。
  • 容器、环境等的配置都是分散在各处,缺乏有效的管理。
  • 对有状态应用支持不好。
  • 系统存在一些冗余,例如有 Zookeeper、有 Etcd 还有 Consul。
  • 不支持自动扩容。
  • 部分基础设施没有容器化。

未来我们会继续进化,也许等时机成熟了,也不排除会迁移到公有云的容器服务,或者自建 Kubernetes 集群。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

周围剃光头顶留长发型_发型改变气质,这话放在石原里美身上也通用啊

上周,石原里美的新剧《天国餐馆》开播啦。你们有在追吗?她新剧里的发型争议还蛮大。她在剧里演一个法国餐厅老板黑须假名子,非常多这种大背头造型。很多网友觉得不适合她,有点老气。▼这个大背头发型也是角色需要啦,是…

ServiceComb中的数据最终一致性方案

本文由华为微服务引擎技术团队&&ServiceComb社区授权发布。 数据一致性是构建业务系统需要考虑的重要问题 , 以往我们是依靠数据库来保证数据的一致性。但是在微服务架构以及分布式环境下实现数据一致性是一个很有挑战的的问题。ServiceComb作为开源的微服务…

laydate点击输入框闪一下不见了_爱剪辑:如何制作抖音、苹果风格的快闪视频...

不知道大家有没有看过iPhone的宣传片,视频开头有几十秒的快闪字幕,当时视频一出来就有很多剪刀手求教程,因为这个效果不仅酷炫,用途还很广,可以用于:日常生活介绍、产品介绍、搞笑段子......今天就来教大家…

C++和Lua交互教程(基于LuaBridge)

作者:查志旺 ,向日葵远程控制软件前端开发工程师。 最近公司需要做向日葵远程控制软件跨平台项目,为了代码的可复用性,需嵌入跨平台脚本语言,我们选择了Lua,理由是Lua由标准C编写而成,几乎在所有…

与Serverless 的第一次亲密接触

Servrless概念 Serverless 是一个架构上的概念,从字面上理解就是无服务器架构。Serverless最初是用于描述依赖第三方服务实现对逻辑和状态进行管理的应用,典型的例子是单页 Web 和移动 App 这种富客户端应用,他们一般都使用基于云端的数据库…

eclipse把tomcant用到一个项目里_聊一个镜头工艺里容易被忽略,但很重要的项目...

在不改换门庭的情况下,一颗镜头一般都会伴随大家使用很长一段时间,也相信大多数人都遇到过剐蹭镜头前组的情况,这时候最容易引发的担忧就是“伤着镀膜了么?会不会影响成像效果?”其实换个角度来看,这个问题…

华为手机怎么看图片属性_华为手机怎么才能息屏显示时间?操作方法很简单,看完涨知识了...

现如今大家几乎都是手机不离身,甚至有些朋友机不离手。所以已经比较少人,会因为看时间而佩戴手表了,毕竟只要按下电源键就可以看时间了。其实现在的很多手机,不用亮屏也能看时间,下面我们就一起来看看是如何设置的吧。…

开源神器,无需一行代码就能搞定机器学习,不会数学也能上手

对于机器学习和数据科学的初学者来说,最大的挑战之一是需要同时学习太多知识,特别是如果你不知道如何编码。你需要快速地适应线性代数、统计以及其他数学概念,并学习如何编码它们,对于新用户来说,这可能会有点难以承受…

OpenStack不行了吗?悉尼峰会,OpenStack的白城反击战?

作者:李开,九州云99Cloud联合创始人&副总裁。 11月悉尼的春天忽然变得阴冷潮湿,和第一天抵达时候的风和日丽大相径庭,海风推动着飘忽的乌云,有点电影《魔戒》里黑暗军团压境的味道。 由于早上不小心睡过了头&…

档案盒正面标签制作_错题本科学制作方法、正确使用方式及窍门

错题本的作用不用多说,重点是如何制作错题本以及正确使用方法。小编整理了以下制作错图集的正确步骤,希望对大家有用。一、制作错题本的简单步骤步骤1:把所有的练习册和试卷找出来;分学科按学期顺序整理;以学年或学期为单位装订在一起&#x…

android触摸效果,Android UI实现单行文本水平触摸滑动效果

本文实例为大家分享了单行文本水平触摸滑动效果,通过EditText实现TextView单行长文本水平滑动效果。下一篇再为大家介绍 多行文本折叠展开效果,自定义布局View实现多行文本折叠和展开。1.初衷最近做应用的时候有用到TextView单行长文本,当文本…

机器人爱因斯坦、索菲亚对话人类:“人类必须自我修复”

人工智能的发展速度真的太快了,就在不久前机器人“索菲亚”获得沙特阿拉伯获得了公民身份之后,机器人版的爱因斯坦教授也登上了历史的舞台。 机器人版的爱因斯坦教授是由汉森机器人(Hanson Robotics)公司制造的,这家机器人制造商制造的另外一…

hook控制浏览器的方法_Java-Hook技术-入门实践+反射、动态代理、热修复再看看

延续之前的MonkeyLei:Android-模块化、组件化、插件化、热修复-插件化-起个头,我们复习下里面的关于反射和动态代理点的知识。然后尝试简单了解下Hook...看之前文章,记得多复习下反射代理,比如使用这些....:public cla…

vscode 头文件包含问题_使用clangd替代c/c++配置vscode c++项目

背景:最近从Clion切换到了vscode来进行代码开发,发现vscode自带的c/c插件除了能够使用debug功能,其余代码补全,跳转等功能都和基于clangd的clion有较大差距,经常出现匹配不上或者跳转不准确的问题,在这背景…

微服务拆分需要考虑的必要因素与坚持原则

前言:创业公司往往因为有限的时间和投入,把系统所有的功能都聚集在一起。随着业务的不断发展,技术人员开始不断地对架构进行解耦和拆分。微服务在最近几年大行其道,很多公司的研发人员都在考虑微服务架构,或者在做微服…

data后缀文件解码_Java语法进阶13-文件、IO流

FileFile是文件和目录路径名的抽象表示形式,即File类是文件或目录的路径,而不是文件本身,因此File类不能直接访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。File类的对象用来表示文件和文件夹的对…

中小型互联网公司微服务实践-经验和教训

上次写了一篇文章叫Spring Cloud在国内中小型公司能用起来吗?介绍了Spring Cloud是否能在中小公司使用起来,这篇文章是它的姊妹篇。其实我们在这条路上已经走了一年多,从16年初到现在。在使用Spring Cloud之前我们对微服务实践是没有太多的体会和经验的…

对于机器学习,到底该选择哪种编程语言

开发者到底应该学习哪种编程语言才能获得机器学习或数据科学这类工作呢?这是一个非常重要的问题。我们在许多论坛上都有讨论过。现在,我可以提供我自己的答案并解释原因,但我们先看一些数据。毕竟,这是机器学习者和数据科学家应该…

android如何适配平板,适用于平板电脑、大屏设备和可折叠设备的自适应布局

将应用支持扩展到更大屏幕的设备(例如平板电脑、可折叠设备和 Chrome 操作系统设备)是扩大您的覆盖面和互动度的绝佳方式。平板电脑的增长率比去年同期 (YOY) 大幅增长了 30%,Chrome 操作系统设备比去年同期增长了 92%。我们还发现,用户使用平板电脑的时…

对于机器学习,到底该选择哪种编程语言?

开发者到底应该学习哪种编程语言才能获得机器学习或数据科学这类工作呢?这是一个非常重要的问题。我们在许多论坛上都讨论过这个问题。今天,我将给出我自己的答案并解释其中原因,但我们首先看一些数据。毕竟,这是机器学习者和数据…