从多租户隔离到高可用,谈DaoShip微服务架构演进

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:

本文根据DCOS联盟第3期线上分享整理而成

 

讲师介绍 20161212111105534.jpg

姜冲

DaoCloud高级软件工程师

 

  • Docker Contributor,负责公有云构建服务、DaoShip的设计与研发。

  • 对微服务架构设计与实现有着丰富的理论与实践经验。

 

 

大纲:

 
  1. 正确构建镜像的目标和所需资源,以及如何规划和构建服务;

  2. 基于优良的微服务架构设计及网络层优化,为数十万用户的服务使用提供稳定高速的构建能力;

  3. 不同运营需求下的技术架构演进;

  4. 微服务带给客户的价值。

 

DaoShip 作为 DaoCloud Service 的一个基础组件,提供了利用 Docker 技术实现的代码构建、代码测试和持续集成功能,是基于云端的的 DevOps 工具,因为多租户安全隔离和高可用性的需要,从早期就采取了今天看来成为潮流的微服务设计。

 

这里应该很多人用过 jenkins 或者 travis ci 等持续集成服务。

 

无论何种构建服务或者集成服务,源代码是必不可少的,都会对接各种源码托管服务。针对国内用户,我们需要支持国外的 GitHub、Bitbucket、国内的 Coding 和企业内部自建的 GitLab 的源代码托管服务。我们会在这些代码仓库上设置 webhook,这样用户一推送代码,我们就能立刻开始自动化构建。

 

另外,对于每一次构建,用户最关心的莫过于结果,是成功还是失败,以及如果失败原因是什么。所以我们还得提供清晰的构建日志,方便用户查错。

 

内部实现上,由于我们面对的是众多不同的用户,还必须能多租户隔离,让不同用户的任务不会相互影响。容器技术出现前,我们需要起一个个虚拟机,来跑不同的任务,隔离程度最好。但是这样做,消耗资源大,而且启动时间长,在主机资源少的情况下,任务会排期长队,每个任务都需要等待很长时间。

 

Docker 的出现,使得我们可以秒级启动,同时资源消耗大幅下降,一台主机可以同时启动多个构建任务,所有任务全部容器化。

 

针对以上 3 点,我们总结下构建服务的基本目标:

  1. 集成代码托管服务;

  2. 提供清晰的构建日志;

  3. 隔离构建任务。

 

在初期我们的构建服务就是这样的:

 

20161212111120481.jpg

 

有如下 3 个特点:

  1. 单机部署模式,单体应用。

    应用太复杂,降低开发速度。因为所有模块都运行在一个进程中,任何一个模块中的一个 bug,比如空指针引用,将会弄垮整个进程,有单点故障。并且无法扩展,只有有限的服务能力。DaoShip API 中使用 docker daemon 做构建的模块(builder)更新频繁,但是每次更新,必须把 DaoShip API 整个更新。

  2. 调用本地 Docker Daemon。

    这不是一件好事,构建全在本地,用户进程会影响 API 的性能。比如用户构建一个 node 应用,npm install 会分分钟把内存和 CPU 吃满。

    Docker 的每次更新,都会带来很多新功能,解决大量 bug。通常我们会评估下,然后将新版本 Docker 引入到我们的构建服务里,为用户带来新的 Docker 功能。然而 DaoShip 内部与 docker daemon 的深度耦合,我们需要引用新的 docker api,修改这部分代码,然后再经历完整而漫长的测试,最后才能提心吊胆地上线。整个过程复杂而冗长,还无法保证质量。

  3. 日志存本地文件,可能因为主机故障而丢失,或者磁盘爆满,导致服务中断。

 

20161212111139884.jpg

 

针对上面 3 点,我们做了两件事。

 

首先日志使用单独的分布式文件存储。其次分离处理构建的模块 builder,每个 builder 都部署在不同的主机上,直接接受 API 下发的任务。

 

20161212111153739.jpg

 

图上展示的各个模块都支持独立横向扩展,似乎不会有单点故障。但是由于 API 是使用 Golang Channel 管理构建任务的,没有健壮的调度器,存在盲目调度的问题,一个 builder 很空闲,而另一个 builder 接受了很多任务可能很忙,导致宕机无响应。而 builder 一停机上面的任务会全失败,任务不会被重新调度,这问题严重影响用户体验。另外我们无法方便有效的更新 builder,由于 builder 几乎时刻都有任务在跑,我们必须等到夜深人静的时候,才能去更新,这样做非常麻烦。

 

20161212111210567.jpg

 

所以为了解决盲调度和错误率高的问题,我们加了一个单独的调度器,做任务的调度。

 

20161212111227622.jpg

 

调度器会把任务扔到任务队列里,builder 则根据自身的任务压力,去从任务队列中取任务。如果压力大,会隔很久才会取一个任务,保证发挥机器最大的性能。builder 还会发送心跳,如果某台 builder 失联或者宕机,其上的任务会被标识为需要重新调度,调度器识别出就会将任务重新扔入任务队列,等待新的 builder 来取。这样我们可以频繁更新,不用担心 builder 失联,同时构建错误率大幅下降,用户体验大幅提升。

 

随着产品迭代和体验提升,用户量急剧上升。用户量上来后,我们发现构建集中某几个时间段,比如下午1点到晚上 8点,都是构建的高峰期,而其它时间段构建很少。如果我们按高峰期来分配 builder 的数量,到低峰期时,资源会过剩,浪费严重。相反按低峰期分配 builder 数量,到高峰期,我们的任务会大量阻塞。所以这里我们还实现了根据 builder 的平均压力来自动扩展弹性伸缩,按需创建 builder。

 

另外根据收费计划,不同的用户有不同的套餐,比如专业版使用更好的构建机。同时我们的构建也分区为北京 BGP 和国外执行环境。所以我们还得能够根据用户的套餐和配置,把任务分配到不同的集群中。我们在调度器上建了一个任务派发器,把不同类型的任务派发到不同的构建集群。

 

20161212111246339.jpg

 

加入健壮的任务派发器和弹性伸缩构建集群后,随着更快的功能迭代,逐渐形成了今天的架构,如上图所示。在运营增长和功能迭代的要求下,我们始终坚持微服务化,不断迭代升级 DaoShip,各个服务之间有明确的界限,职责也非常清晰。在整个架构演进中,微服务化给我们带来如下 4 点显而易见的益处:

 

  1. 通过分解巨大单体式应用为多个服务方法解决了复杂性问题,服务边界清晰,组件之间通过 rest api 和消息队列进行通信。

  2. 这种架构使得我们的每个服务都可以有专门开发团队或者人员来开发。即使某个服务的同事离职,也不会影响其他服务的开发,同时由于服务足够简单,新的同事可以快速上手掌握。

  3. 微服务架构模式下每个服务可以独立部署,每个组件都能单独快速测试发布。小步迭代,敏捷开发下,现在我们可以做到时刻无感知上线,一个小 bug 修复可以在 10 分钟内做到从编码到测试到上线。

  4. 微服务架构模式使得每个服务可以独立扩展。在偶尔的构建压力暴增情况下,我们可以快速扩展 builder,以符合服务需求。

 

今天我主要分享了 DaoShip的微服务架构是如何演进的,其中的技术细节下次我们再深入探讨。

 

Q&A

 

Q1:你们微服务分解有什么经验吗?或是有什么方法吗?你们是怎么分解的?

A1:这个问题非常好,相信很多工程师都非常关心。说实话,我们公有云构建服务这一块,您已经看到了,由于我们没有很多的历史包袱,所以涉及到的服务拆分比较少,属于服务演进的范畴,少量的服务拆分也是在一开始的架构设计松耦合的方式下,成功演进。

 

Q2:宿主的Docker更新你们有做吗,如果做,要怎么在不停机的状况下做呢?

A2:Docker更新更是一个非常切实际的话题。我们目前的策略是:我们的 builder 是自动去取任务的,所以更新时,会让builder 停止取任务,然后上面的任务完成后,我们再更新Docker 。

 

Q3:你们的微服务主要存在哪个环节?

A3:关于微服务存在于哪些方面,这个问题。我们的认识是这样的。我们在镜像构建这边,尽管没有涉及到市面上的dubbo,zuul,APIgateway等内容,主要是因为本身不是一个复杂的系统,职责较为聚焦,但是整个构建的演进可以认为是具备微服务演进的基本特性,这里5个服务:API服务,日志服务,构建服务,调度服务,分发服务,它们的设计于演进都是结合场景,在需求之下,谋变,求突破,达到预期的效果。我个人的观点是:微服务与代码行数方面没有直接关系。

 

Q4:Python和node的镜像基本都要安装大量的包,IO的占用很大,你们在docker这边有什么优化吗?

A4:“Python和node的镜像基本都要安装大量的包,IO的占用很大,你们在docker这边有什么优化吗”。这又是一个实际过程中经常会遇到的问题。首先第一点,我们完完全全尊重用户编写的Dockerfile,其次在这基础上满足用户对构建高效,快速的需求。网络IO方面,我们采用两条线,一条国内,一条国外,一经发现用户构建涉及国外源,即分发至国外的构建机器。磁盘IO方面,我们全部采用的是SSD。因此,您可以发现,我们首先会从硬件基础设施层满足用户的需求。

 

Q5:目前这个架构中,还有没有可改进的地方?

A5:很好的话题。首先第一点,我们的架构肯定会跟着客户的需求来走,目前,我们这套可以服务20w用户的构建任务,日构建量达到15k,当前运行非常稳定。第二点,架构改进方面,我们后续计划在构建的自学习方面引进一类新的服务,即如何更好的帮助用户识别出Dockerfile的软件源,并实现更加高效快速构建。

原文发布时间为:2016-12-12

本文来自云栖社区合作伙伴DBAplus

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1天前
|
Kubernetes 监控 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【5月更文挑战第4天】在现代软件开发中,微服务架构已成为实现可扩展、灵活且独立部署服务的流行解决方案。本文将探讨如何利用Docker容器化技术和Kubernetes容器编排平台来构建一个高效的微服务系统。我们将分析Docker和Kubernetes的核心优势,并指导读者如何通过这些工具优化微服务部署、管理和扩展过程。文章还将涉及监控和日志管理策略,以确保系统的健壮性和可靠性。
|
1天前
|
监控 Java 持续交付
构建高效微服务架构:后端开发者的终极指南
【5月更文挑战第4天】在当今快速迭代和竞争激烈的软件市场中,微服务架构已成为企业追求敏捷性、可扩展性和技术多样性的关键策略。本文深入探讨了如何构建和维护高效的微服务系统,从基本概念到高级实践,为后端开发者提供一套综合指南,以支持他们在这一变革性架构风格中扮演关键角色。
|
1天前
|
负载均衡 API 数据库
构建高效微服务架构的五大关键技术
【5月更文挑战第4天】 随着云计算和容器化技术的成熟,微服务架构已成为软件开发的主流模式。本文将详细探讨实现高效微服务架构的五个关键技术点:服务拆分策略、API网关设计、服务发现与注册、熔断机制以及分布式事务管理。这些技术点是确保微服务系统可扩展性、灵活性及稳定性的基石,对于后端开发者而言,掌握它们至关重要。文章将提供具体的实施建议和最佳实践,帮助读者构建和维护高性能的微服务系统。
|
2天前
|
JavaScript Java 持续交付
构建高效微服务架构:后端开发的新范式
【5月更文挑战第3天】 在现代软件开发的浪潮中,微服务架构以其灵活性、可扩展性和技术多样性而受到重视。本文深入探讨了如何构建一个高效的微服务系统,包括关键的设计原则、技术选型、以及实现细节。我们将通过分析微服务的核心概念,提供一套实用的步骤和最佳实践,以指导开发者构建出既健壮又易于维护的分布式系统。文章将重点讨论如何在保证系统性能和稳定性的前提下,实现服务的解耦与独立部署,从而推动后端开发工作流的优化和创新。
|
2天前
|
安全 数据管理 持续交付
构建高效微服务架构的五大核心策略
【5月更文挑战第3天】在当前软件开发领域,微服务架构已成为一种流行的设计模式,它通过将应用程序拆分成一组小型、松耦合的服务来提高系统的可维护性和扩展性。本文将详细探讨构建高效微服务架构的五大核心策略,包括服务划分原则、通信机制设计、数据管理、安全性考虑以及持续集成与部署。这些策略不仅有助于确保系统的高可用性和灵活性,同时也支持快速迭代和部署,是实现现代云原生应用的基石。
|
3天前
|
Kubernetes API 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第2天】 随着现代软件开发的演进,传统的单体应用已难以满足快速变化的业务需求和敏捷开发的挑战。本文探讨了如何通过构建高效的微服务架构来提升后端开发的灵活性、可维护性和扩展性。我们将深入分析微服务的核心组件,包括服务拆分、容器化、API网关和持续集成/持续部署(CI/CD)等关键技术,并讨论它们如何共同作用以支持复杂的业务场景和云原生应用的需求。
12 1
|
3天前
|
负载均衡 Java API
构建高效微服务架构:API网关与服务熔断策略
【5月更文挑战第2天】 在微服务架构中,确保系统的高可用性与灵活性是至关重要的。本文将深入探讨如何通过实施有效的API网关和设计合理的服务熔断机制来提升分布式系统的鲁棒性。我们将分析API网关的核心职责,包括请求路由、负载均衡、认证授权以及限流控制,并讨论如何利用熔断器模式防止故障传播,维护系统的整体稳定性。文章还将介绍一些实用的技术和工具,如Netflix Zuul、Spring Cloud Gateway以及Hystrix,以帮助开发者构建一个可靠且高效的微服务环境。
|
4天前
|
监控 安全 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第30天】随着现代软件开发的复杂性日益增加,传统的单体应用架构已难以满足快速迭代与灵活部署的需求。微服务架构作为一种新兴的设计理念,它通过将一个大型应用程序拆分成一系列小而专注的服务来提供解决方案。本文旨在探讨如何构建一个高效且可靠的微服务架构系统,涵盖从设计原则、技术选型到部署实践的全方位知识,为后端开发者提供一种全新的开发思路和实践指导。
|
4天前
|
Java 调度 开发者
构建高效微服务架构:后端开发的新趋势深入理解操作系统之进程调度策略
【4月更文挑战第30天】 随着企业数字化转型的不断深入,传统的单体应用逐渐不能满足快速迭代和灵活部署的需求。微服务架构以其高度模块化、独立部署和易于扩展的特性,成为现代后端开发的重要趋势。本文将探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术选型以及可能面临的挑战。
|
4天前
|
Cloud Native Devops 持续交付
构建未来:云原生架构在企业数字化转型中的关键作用构建高效微服务架构:后端开发的新范式
【4月更文挑战第30天】 随着企业加速其数字化进程,云原生架构已成为支撑复杂、可伸缩和灵活应用的骨干。本文探讨了云原生技术的崛起,重点分析了其在促进业务敏捷性、提高运营效率及推动创新方面的核心价值。通过深入剖析云原生生态系统的关键技术组件,如容器化、微服务、持续集成/持续部署(CI/CD)和DevOps实践,揭示了企业如何利用这些技术来构建和维护高度可用且动态的IT环境。文章还提出了一个多维度的采纳框架,帮助企业评估和实施云原生解决方案,以实现真正的业务价值。 【4月更文挑战第30天】在现代软件开发的快速演变中,微服务架构已经成为一种领先的设计模式,用于构建可扩展、灵活且容错的应用程序。与传