网易容器云平台的微服务化实践

摘要:网易云容器平台期望能给实施了微服务架构的团队提供完整的解决方案和闭环的用户体验,为此从 2016 年开始,我们容器服务团队内部率先开始进行 dogfooding 实践,看看容器云平台能不能支撑得起容器服务本身的微服务架构,这是一次很有趣的尝试。

 

一旦决定做微服务架构,有很多现实问题摆在面前,比如技术选型、业务拆分问题、高可用、服务通信、服务发现和治理、集群容错、配置管理、数据一致性问题、康威定律、分布式调用跟踪、CI/CD、微服务测试,以及调度和部署等等,这并非一些简单招数能够化解。实践微服务架构的方式有千万种,我们探索并实践了其中的一种可能性,希望可以给大家一个参考。本文是《网易容器云平台的微服务化实践》系列文章的第一篇。


 

Docker 容器技术已经过了最早的喧嚣期,逐渐在各大公司和技术团队中应用。尽管以今天来看,大家从观念上已经逐渐认可 “将镜像定义为应用交付标准,将容器作为应用运行的标准环境” 的观点,但还是有相当一部分人在迷惑容器技术作为一个标准,应该怎么落地,怎样才能大规模线上应用,怎么玩才能真正解放生产力,促进软件交付效率和质量?答案其实在应用的架构当中。

 

微服务架构不是因 Docker 容器技术而生,但确实是因容器技术而火。容器技术提供了一致性的分发手段和运行环境,使得只有微服务化后的应用架构,才能配合容器发挥其最大价值。而微服务化架构引入了很大的复杂性,只有应用容器化以及规模化的容器编排与调度才能避免运维效率下降。容器技术和微服务化架构之间本是一种相辅相成的互补关系。

 

网易容器云平台的前身是网易应用自动部署平台 (OMAD),它能够利用 IaaS 云提供的基础设施,实现包括构建和部署一体化在内的整个应用生命周期管理。2014 年,以 Docker 为代表的容器技术进入大众视野,我们惊喜地发现,容器技术是自动部署平台从工具型应用进化为平台型应用过程中最重要的一块拼图。原本用户需要初始化主机,然后借助自动部署平台完成应用的构建和部署。引入容器技术之后,用户从功能开发到测试到一键部署上线,整个应用交付过程中不用关心主机初始化、主机间通信、实例调度等一系列应用之外的问题。这简直是信仰 DevOps 的人的福音。

 

我们从 2015 年开始探索容器技术的最佳实践方式,从当初 “胖容器” 与容器集群的产品形态,到后来关于有状态和无状态服务的定义,以及如今的新计算与高性能计算,我们一直在思考并丰富着容器技术的应用场景。无论产品形态如何调整,容器云平台的核心概念一直是 “微服务”,通过微服务这一抽象提供高性能的容器集群管理方案,支持弹性伸缩、垂直扩容、灰度升级、服务发现、服务编排、错误恢复、性能监测等功能,满足用户提升应用交付效率和快速响应业务变化的需求。网易云容器平台期望能给实施了微服务架构的团队提供完整的解决方案和闭环的用户体验,为此从 2016 年开始,我们容器服务团队内部率先开始进行 dogfooding 实践,一方面检验容器云平台能不能支撑得起容器服务本身的微服务架构,另一方面通过微服务化实践经验反哺容器云平台产品设计,这是一次很有趣的尝试,也是我们分享容器云平台微服务化架构实践的初衷。

 

在谈容器服务的微服务架构实践之前,有必要先把网易云容器服务大致做个介绍。目前网易云容器服务团队以 DevOps 的方式管理着30+微服务,每周构建部署次数 400+。网易云容器服务架构从逻辑上看由 4 个层次组成,从下到上分别是基础设施层、Docker 容器引擎层、Kubernetes (以下简称 K8S)容器编排层、DevOps 和自动化工具层:

 

容器云平台整体业务架构如下:

(点击图片放大查看)

抛开容器服务具体业务不谈,仅从业务特征来说,可以分成以下多种类型(括号内为举例的微服务):


  • 面向终端用户 (OpenAPI 服务网关)、面向服务(裸机服务)

  • 同步通信(用户中心)、异步通信(构建服务)

  • 数据强一致需求(etcd 同步服务)、最终一致需求(资源回收服务)

  • 吞吐量敏感型(日志服务)、延时敏感型(实时服务)

  • CPU 计算密集型(签名认证中心)、网络 IO 密集型(镜像仓库)

  • 在线业务(Web 服务)、离线业务(镜像检查)

  • 批处理任务(计费日志推送)、定时任务(分布式定时任务)

  • 长连接(WebSocket 服务网关)、短连接(Hook 服务)

  • ……

 

一旦决定做微服务架构,有很多现实问题摆在面前,比如技术选型、业务拆分问题、高可用、服务通信、服务发现和治理、集群容错、配置管理、数据一致性问题、康威定律、分布式调用跟踪、CI/CD、微服务测试,以及调度和部署等等......这并非一些简单招数能够化解。

 

作为主要编程语言是 Java 的容器服务来说,选择 Spring Cloud 去搭配 K8S 是一个很自然的事情。Spring Cloud 和 K8S 都是很好的微服务开发和运行框架。从应用的生命周期角度来看,K8S 覆盖了更广的范围,特别像资源管理,应用编排、部署与调度等,Spring Cloud 则对此无能为力。从功能上看,两者存在一定程度的重叠,比如服务发现、负载均衡、配置管理、集群容错等方面,但两者解决问题的思路完全不同,Spring Cloud 面向的纯粹是开发者,开发者需要从代码级别考虑微服务架构的方方面面,而 K8S 面向的是 DevOps 人员,提供的是通用解决方案,它试图将微服务相关的问题都在平台层解决,对开发者屏蔽复杂性。举个简单的例子,关于服务发现,Spring Cloud 给出的是传统的带注册中心 Eureka 的解决方案,需要开发者维护 Eureka 服务器的同时,改造服务调用方与服务提供方代码以接入服务注册中心,开发者需关心基于 Eureka 实现服务发现的所有细节。而 K8S 提供的是一种去中心化方案,抽象了服务 (Service),通过 DNS+ClusterIP+iptables 解决服务暴露和发现问题,对服务提供方和服务调用方而言完全没有侵入。

 

对于技术选型,我们有自己的考量,优先选择更稳定的方案,毕竟稳定性是云计算的生命线。我们并不是 “K8S 原教旨主义者”,对于前面提到的微服务架构的各要点,我们有选择基于 K8S 实现,比如服务发现、负载均衡、高可用、集群容错、调度与部署等。有选择使用 Spring Cloud 提供的方案,比如同步的服务间通信;也有结合两者的优势共同实现,比如服务的故障隔离和熔断;当然,也有基于一些成熟的第三方方案和自研系统实现,比如配置管理、日志采集、分布式调用跟踪、流控系统等。

 

我们利用 K8S 管理微服务带来的最大改善体现在调度和部署效率上。以我们当前的情况来看,不同的服务要求部署在不同的机房和集群(联调环境、测试环境、预发布环境、生产环境等),有着不同需求的软硬件配置(内存、SSD、安全、海外访问加速等),这些需求已经较难通过传统的自动化工具实现。K8S 通过对 Node 主机进行 Label 化管理,我们只要指定服务属性 (Pod label),K8S 调度器根据 Pod 和 Node Label 的匹配关系,自动将服务部署到满足需求的 Node 主机上,简单而高效。内置滚动升级策略,配合健康检查 (liveness 和 readiness 探针)和 lifecycle hook 可以完成服务的不停服更新和回滚。此外,通过配置相关参数还可以实现服务的蓝绿部署和金丝雀部署。集群容错方面,K8S 通过副本控制器维持服务副本数 (replica),无论是服务实例故障(进程异常退出、oom-killed 等)还是 Node 主机故障(系统故障、硬件故障、网络故障等),服务副本数能够始终保持在固定数量。

Docker 通过分层镜像创造性地解决了应用和运行环境的一致性问题,但是通常来讲,不同环境下的服务的配置是不一样的。配置的不同使得开发环境构建的镜像无法直接在测试环境使用,QA 在测试环境验证过的镜像无法直接部署到线上……导致每个环境的 Docker 镜像都要重新构建。解决这个问题的思路无非是将配置信息提取出来,以环境变量的方式在 Docker 容器启动时注入,K8S 也给出了 ConfigMap 这样的解决方案,但这种方式有一个问题,配置信息变更后无法实时生效。我们采用的是使用 Disconf 统一配置中心解决。配置统一托管后,从开发环境构建的容器镜像,可以直接提交到测试环境测试,QA 验证通过后,上到演练环境、预发布环境和生产环境。一方面避免了重复的应用打包和 Docker 镜像构建,另一方面真正实现了线上线下应用的一致性。

 

Spring Cloud Hystrix 在我们的微服务治理中扮演了重要角色,我们对它做了二次开发,提供更灵活的故障隔离、降级和熔断策略,满足 API 网关等服务的特殊业务需求。进程内的故障隔离仅是服务治理的一方面,另一方面,在一个应用混部的主机上,应用间应该互相隔离,避免进程间互抢资源,影响业务 SLA。比如绝对要避免一个离线应用失控占用了大量 CPU,使得同主机的在线应用受影响。我们通过 K8S 限制了容器运行时的资源配额(以 CPU 和内存限制为主),实现了进程间的故障和异常隔离。K8S 提供的集群容错、高可用、进程隔离,配合 Spring Cloud Hystrix 提供的故障隔离和熔断,能够很好地实践 “Design for Failure” 设计哲学。

 

服务拆分的好坏直接影响了实施微服务架构的收益大小。服务拆分的难点往往在于业务边界不清晰、历史遗留系统改造难、数据一致性问题、康威定律等。从我们经验来看,对于前两个问题解决思路是一样的:1)只拆有确定边界能独立的业务。2)服务拆分本质上是数据模型的拆分,上层应用经得起倒腾,底层数据模型经不起倒腾。对于边界模糊的业务,即使要拆,只拆应用不拆数据库。

 

以下是我们从主工程里平滑拆出用户服务的示例步骤:


  1. 将用户相关的 UserService、UserDAO 分离出主工程,加上 UserController、UserDTO 等,形成用户服务,对外暴露 HTTP RESTful API。

  2. 将主工程用户相关的 UserService 类替换成 UserFaçade 类,采用 Spring Cloud Feign 的注解,调用用户服务 API。

  3. 主工程所有依赖 UserServce 接口的地方,改为依赖 UserFaçade 接口,平滑过渡。


经过以上三个步骤, 用户服务独立成一个微服务,而整个系统代码的复杂性几乎没有增加。

 

数据一致性问题在分布式系统中普遍存在,微服务架构下会将问题放大,这也从另一个角度说明合理拆分业务的重要性。我们碰到的大部分数据一致性场景都是可以接受最终一致的。“定时任务重试+幂等” 是解决这类问题的一把瑞士军刀,为此我们开发了一套独立于具体业务的 “分布式定时任务+可靠事件” 处理框架,将任何需保证数据最终一致的操作定义为一种事件,比如用户初始化、实例重建、资源回收、日志索引等业务场景。以用户初始化为例,注册一个用户后,必须对其进行初始化,初始化过程是一个耗时的异步操作,包含租户初始化、网络初始化、配额初始化等等,这需要协调不同的系统来完成。我们将初始化定义为一种 initTenant 事件,将 initTenant 事件及上下文存入可靠事件表,由分布式定时任务触发事件执行,执行成功后,清除该事件记录;如果执行失败,则定时任务系统会再次触发执行。对于某些实时性要求较高的场景,则可以先触发一次事件处理,再将事件存入可靠事件表。对于每个事件处理器来说,要在实现上确保支持幂等执行,实现幂等执行有多种方式,我们有用到布尔型状态位,有用到 UUID 做去重处理,也有用到基于版本号做 CAS。这里不展开说了。







当业务边界与组织架构冲突时,从我们的实践经验来看,宁愿选择更加符合组织架构的服务拆分边界。这也是一种符合康威定律的做法。康威定律说,系统架构等同于组织的沟通结构。组织架构会在潜移默化中约束软件系统架构的形态。违背康威定律,非常容易出现系统设计盲区,出现 “两不管” 互相推脱的局面,我们在团队间、团队内都碰到过这种情况。

 

本文是《网易容器云平台的微服务化实践》系列文章的第一篇,介绍了容器技术和微服务架构的关系,我们做容器云平台的目的,以及简单介绍了网易云容器服务基于 Kubernetes 和 Spring Cloud 的微服务化实践经验。限于篇幅,有些微服务架构要点并未展开,比如服务通信、服务发现和治理、配置管理等话题;有些未提及,比如分布式调用跟踪、CI/CD、微服务测试等话题,这些方面的实践经验会在后续的系列文章中再做分享。实践微服务架构的方式有千万种,我们探索并实践了其中的一种可能性,希望可以给大家一个参考。



PS:推荐一个容器技术线上直播,讲师来自腾讯、华为、思科、58同城、美丽联合、当当等6位一线专家,议题涵盖容器云、微服务、servicemesh等最新实践,具体直播时间为本周六(12月16日),欢迎扫描下方图片中二维码报名参加。





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

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

相关文章

逐鹿工具显示服务器错误连接不上怎么解决,win7系统安装逐鹿工具箱提示“error launching installer”错误的解决方法...

win7系统使用久了,好多网友反馈说win7系统安装逐鹿工具箱提示“error launching installer”错误的问题,非常不方便。有什么办法可以永久解决win7系统安装逐鹿工具箱提示“error launching installer”错误的问题,面对win7系统安装逐鹿工具箱…

唯品会2017年双11大促技术保障实践,全域提供25万QPS服务能力

作者简介:刘惊惊,唯品会业务架构部高级架构师,负责唯品会电商平台的用户系统,营销系统和库存系统的架构设计工作。2016年加入唯品会,参与了唯品会电商系统的大重构,负责多个核心系统的梳理和大促准备。 张…

iis7 mysql_windows 7 下搭建php开发环境(windows7+IIS7+php+mysql)

首先需要说明的是,基于IIS v6.0/v7.0(2008),可以支持的脚本相当完整,不仅支持Linux无法支持的asp/asp.net,还可以安装php、mysql、zend实现php环境。同时,利用Serv-U可以实现ftp管理。操作简单,无需键入任何…

从核心技术到高可用实践——解密数据库深度挖掘指南

SDCC系列峰会各站在技术圈遍地花开之余,主办方CSDN为了更好地服务技术开发者并拓展受众,同步启动SDCC 2017系列之线上峰会——线上线下双管齐下,一举打破地域限制,内容为基,便捷加成,带来更友好的听众体验。…

Unity中Shader观察空间推导

文章目录 前言一、本地空间怎么转化到观察空间二、怎么得到观察空间的基向量1、Z轴向量2、假设 观察空间的 Y~假设~ (0,1,0)3、X Y 与 Z 的叉积4、Y X 与 Z 的叉积 三、求 [V~world~]^T^1、求V~world~2、求[V~world~]^T^ 四、求出最后在Unity中使用的公式1、偏移坐标轴2、把…

portainer 启动mysql_docker 安装portainer容器后,启动/Portainer 安装MySQL并开启远程访问...

启动命令:docker run -d -p 9000:9000 --restartalways -v /var/run/docker.sock:/var/run/docker.sock --name portainer docker.io/portainer/portainer下载mysql镜像文件:docker search mysqldocker pull mysql:5.7.32创建mysql容器:docker run -d --…

追求极简:Docker镜像构建演化史

作者简介:白明,东软互联网运营平台技术负责人,毕业于哈尔滨工业大学,Go语言专家,GopherChina讲师,技术培训师和撰稿人,博客tonybai.com作者,拥有多年后端服务架构设计和开发经验。目…

特征选择算法在微博业务应用中的演进历程

近年来,人工智能与机器学习的应用越来越广泛,尤其是在互联网领域。在微博,机器学习被广泛地应用于微博的各个业务,如Feed流、热门微博、消息推送、反垃圾、内容推荐等。值得注意的是,深度学习作为人工智能和机器学习的…

c winform mysql类_C#连接MySQL数据库操作类

首先需要安装MySQL Connector Net 6.8.3然后在项目中引用MySQL Connector,如下图所示C#连接MySQL的操作类代码如下:public class MySQLHelper{private string db_host "localhost"; //数据库服务器private string db_port "3306";…

病历智能处理引擎的架构设计、实现和应用

作者简介:吴大帅,新屿算法工程师,曾供职于宅米网、新达达,从事系统架构设计、算法设计等工作。 李智慧,《大型网站技术架构:核心原理与案例分析》作者,从事大型网站、分布式系统、大数据方面的研…

Heron:来自Twitter的新一代流处理引擎应用篇

作者 | 吴惠君,吕能,符茂松责编 | 郭芮【导语】 本文对比了Heron和常见的流处理项目,包括Storm、Flink、Spark Streaming和Kafka Streams,归纳了系统选型的要点。此外实践了Heron的一个案例,以及讨论了Heron在这一年开…

2017 JavaScript 调查报告概述

本文转载自极光日报知乎专栏,地址:https://zhuanlan.zhihu.com/p/32260460简评:最近一份超过 23,000 名开发者参与的关于 JavaScript 的调查报告 - the State of JavaScript 2017 出炉了。内容包含框架的流行趋势、薪资水平等等,感…

python动态_python --动态类型

动态类型(dynamic typing)是Python另一个重要的核心概念。我们之前说过,Python的变量(variable)不需要声明,而在赋值时,变量可以重新赋值为任意值。这些都与动态类型的概念相关。动态类型在我们接触的对象中,有一类特殊的对象&…

微博热点事件背后数据库运维的“功守道”

作者 | 张冬洪责编 | 仲培艺【导语】 微博拥有超过3.76亿月活用户,是当前社会热点事件传播的主要平台。而热点事件往往具有不可预测性和突发性,较短时间内可能带来流量的翻倍增长,甚至更大。如何快速应对突发流量的冲击,确保线上服…

sql devalop连接mysql_SQL-Mysql表结构操作

一 前言本篇内容是关于 基本的数据库操作,建表,表结构修改等内容;学习本篇的基础是知识追寻者以前发布的文章:公众号:知识追寻者知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;)二…

云计算平台2017年盘点——真正成为新技术新应用的基础架构

作者简介:吴凯,北京云途腾科技有限责任公司首席运营官,具有20年的IT和软件服务行业管理经验,历任多家著名外资及民营IT企业的核心高级管理职位,是中国云计算专家委员会专家委员,中国开源云联盟及云计算开源…

Spark SQL在100TB上的自适应执行实践

作者:汪愈舟 俞育才 郭晨钊 程浩(英特尔),李元健(百度)责编:钱曙光(qianshgcsdn.net)Spark SQL是Apache Spark最广泛使用的一个组件,它提供了非常友好的…

分包组包 北斗通信_蓝牙mesh底层传输层(分包和组包)

当传输大于15字节的上层传输层PDU时,底层传输层就需要对上层传输层PDU进行分包并重新组包为了减少底层传输层包的数量,这里使用块应答机制。问题:怎么通过块应答机制减少底层传输层包的数量?上层传输层需要分成两个底层传输层PDU的…

别人在忙挖矿,京东架构师却悄悄用区块链搞了件大事

作者介绍: 赵铭,京东商城区块链研发工程师, 主要从事区块链底层研究设计工作,主攻方向为分布式账本结构; 孙海波,目前担任京东Y事业部供应链研发负责人,负责的业务包括订单履约、库存优化、采购…

用sklearn mysql_Sklearn之Linear Regression

import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, linear_modelfrom sklearn.metrics import mean_squared_error, r2_score# 加载糖尿病数据集diabetes datasets.load_diabetes()# 只使用一个特征diabetes_X diabetes.data[:, np.newaxis, …