微服务 to 变 or not to 变?

本文涉及的产品
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 本文讲的是微服务 to 变 or not to 变?,今天,在创建和部署应用的时候,最常用的方式就是可变服务器。

巨兽型可变服务器

本文讲的是微服务 to 变 or not to 变?,今天,在创建和部署应用的时候,最常用的方式就是可变服务器。我们会创建一个web服务器,该服务器上具有完整的应用,每次有新的版本发布时我们就会对服务器进行更新。服务器中具体的改动包括配置改动(属性文件、XML文件、数据库表等)、代码工件(JAR、WAR、DLL、静态文件等)、数据库模式和数据。因为每当有新版本时我们就会对服务器进行相应的改动,因此这种服务器叫做可变服务器。
对于可变服务器来说,我们不清楚开发、测试和生产环境是否相同,甚至是生产中的不同节点也可能会产生不利的差异问题。代码、配置文件或静态文件在某些实例中是否全部完成升级更新也未可知。

可变服务器是一种巨兽服务器,它包含了我们需要的所有东西,构成了一个简单的实例,后端、前端、API接口等等都包括在内。此外,这种服务器会不断成长。一段时间后可能没有人知道生产中某一部分的配置详情,而要想准确复制(新生产节点、测试环境等等)就只能复制整个虚拟机,然后开始进行配置(IP、主机文件、数据库连接等)。我们不断的在服务器中添加新东西,渐渐地就会失去对服务器的把控。过一段时间,当初设计完美惊艳的架构就会面目全非。

新添加的层次、新耦合的代码、还有源源不断的修补程序(补丁),最终你会迷失在迷宫一样的代码中。一开始还很美丽的小项目变成了一头丑陋的巨兽。你满怀希望的项目,到最后也成为了大家茶余饭后的笑话。对于这样的项目,人们可能会说最好的处理方式就是扔到一旁重新来过。但事已至此,巨兽一旦形成就难以重新开始了,已经投入了太多资源,重新开始将会耗费大量时间,而且会产生很多风险。所以巨石架构可能还会持续相当长的一段时间。

image

可变部署看起来简单,实则不然。它将所有东西都耦合在一起,试图把复杂性隐藏,但这也使各个实例之间更容易产生差异。
发布新版本应用时,何时重启这样的服务器很关键。因为在重启时,服务器通常都是不工作的,而这不仅会造成经济上的损失,还会丧失客户的信任。在今天的商业世界里,我们应当提供全天候运行的服务。此外,新版本发布时通常也意味着研发小组需要在夜间加班工作。面对这样的情况,持续部署看起来遥若星辰,可望而不可及。
测试同样也存在问题。不论我们在研发和测试环境中进行了多少次测试,只有我们将软件部署在生产环境中,让测试员和用户都能够使用,才开始真正意义上的第一次生产测试。
另外,这种服务器几乎无法实现快速回滚。因为服务器的可变性,所以不存在之前版本的“快照”。除非我们为整个虚拟机创建一个快照,但这又会产生很多新问题。
如果采用可变服务器,那么我们之前所描述到的需求是不可能全部满足的。由于服务器无法实现零宕机和快速回滚,我们也无法对其进行持续(频繁)部署。可变服务器的特性也决定了我们不可能实现全自动化(有风险),这样就延缓了我们的研发速度。
如果不能经常部署,那么我们只能不断的积累各种改变,而这些最终都会在发布的时候才暴露问题,很容易就会导致研发的失败。
为了解决这些问题,我们应该采用不可变部署方式,同时部署中应当包括小型、独立且自给自足性的应用。我们的目标很明确,零宕机时间、回滚能力、自动化以及快速功能。此外,我们还应当在用户接触软件前就在生产环境中对发布版本进行测试。

不可变服务器和反向代理

每一种“传统”的部署方式中,对系统的改动都会呈现在服务器上,从而增加了风险。而如果我们采用不可变部署方式,那么就可以立竿见影,获得成效。由于我们不需要考虑应用(应用是不可变的),因此环境的准备工作将变得极为简单。当我们在生产服务器上部署一个新的镜像文件或容器时,我们很清楚该文件或容器就是我们一直在开发和测试的东西。

不可变部署减少了未知的风险,我们知道每一个部署的实例和其他实例都是相同的。与可变部署不同,当程序包不可变而且包含了所有东西(应用服务器、配置文件和工件)的时候,我们就可以高枕无忧了。这些东西打包作为整体在部署流程中进行处理,我们只需要确保这些不可变的程序包顺利到达终端服务器就好。不可变部署消除了可变部署带来的不一致性,我们在其他环境中进行测试的程序包和最终到达服务器的程序包是完全相同的。

反向代理可用来实现零宕机。不可变服务器和反向代理可以通过下面这种简单的方式结合使用。

首先我们启动一个反向代理,指向已经完成的完全自给自足的不可变应用程序包。这个程序包可以是虚拟机,也可以是容器。这个不可变的镜像显而易见有别于可变应用。此外,还会有一个代理服务,服务器并不会直接暴露,代理服务会将所有访问(traffic)发送(route)到最终的目标位置。

image

一旦我们决定要部署一个新版本时,我们就会通过在另外一个独立的服务器上部署单独的镜像来完成。当然,有时候我们可以将这个镜像部署在相同的服务器上,但更多时候,由于巨石应用消耗大量资源,在不影响性能的前提下我们很难在同一节点进行多次部署。
此时,我们就会有两个实例(两台服务器)。一个是老版本,一个是新版本。所有的访问均通过代理服务由老的服务器处理,这样用户就不会察觉到任何改变。因为对于用户来说,我们仍旧在运行之前的服务器和软件。此时我们就可以放心的去做新软件应用的最后测试了,最好这些测试都是自动化的,而且属于部署过程的一部分,但仍需人工检测。
例如,如果我们在前端做了修改,那么就需要在最后做一次用户体验测试。不论我们进测试类型是什么,都需要绕过代理服务针对新发布软件进行测试。做这些测试的时候,我们很清楚自己在测试的软件将来会发布并应用于硬件上,而且我们是在没有影响用户体验(用户此时在使用旧版本软件)的情况下进行的测试。甚至我们可以通过A/B测试的形式选择对一部分用户开放新版本软件。

总的来说,这个时候我们就有了两个服务器实例,一个(旧版本)给用户使用,一个(新版本)用来进行测试。
image

第二个实例与第一个实例平行部署
不可变应用的新版本部署在独立的节点处

一旦我们完成测试,确保新版本万无一失,那么我们只需要修改代理服务,让访问指向新版本软件即可。旧版本可暂时保留一段时间,供可能的回滚使用。但对用户来说,旧版本已经不复存在了。用户的所有请求都会指向新发布的版本。而我们在此之前已经确保新image
版本可以投入使用,因此请求指向的改变并不会影响服务体验(而如果在可变部署模式中,这样做就需要重启服务器,导致服务中断,影响用户体验)。当请求路径改变时,我们需要重新加载反向代理。例如,在所有连接转变到新路径之前,nginx会维持所有旧的连接路径。

image

最后,当所有转变完成后,我们可以移除旧版本,我们甚至可以让新版本去做这件事。这样的话,当到了合适的时间,新版本就会自动移除旧版本并取而代之。
image

上述方法已经在业内使用了很长时间,我们称之为蓝绿部署。之后我们在讲到Docker打包和部署示例的时候还会提到它。

不可变微服务

我们还能做的更好。不可变部署使得我们可以轻易实现流程的自动化,反向代理实现了零宕机,新旧版本的使用也简化了回滚工作。但由于我们面对的应用仍然过于庞大,因此部署和测试工作可能会花费大量的时间。这可能就会使我们的速度降低,而且无法频繁的进行部署工作。此外,体量庞大的应用在开发、测试和部署时的复杂度也很高。如果可以的话,我们可能会将其分割成易于管理的小部分,这样不仅易于管理操作,还能简化拓展。这些小服务可以部署在同一台机器上,如果其中某个服务到达瓶颈(需要扩展),那么我们就可以在网络中对其进行拓展或复制,而这正是微服务!
在研发“巨兽”型应用时,我们往往会产生解耦的层次。前端代码和后端代码分离,业务层和数据接入层分离等等。而在微服务中,我们应当开始换个角度来看问题。我们要分离的不再是业务层和数据接入层,而是各个服务。例如,用户管理服务可以从销售服务中分离出来。另外有一点不同的是在物理表现(physical)上,传统的架构分离是在程序包和类的级别进行,但所有东西还是共同部署的;而在微服务中,各项服务是物理隔离的,可能正在开发的两个服务都不在同一台机器上。
微服务的部署方式与之前描述的方式相同。

我们部署微服务不可变镜像的方式和部署其他软件的方式相同。

image

所有请求都通过代理服务选择路径
微服务应用是不可变的,部署时作为容器进行部署

当我们准备发布某个微服务的新版本时,会将其与旧版本部署在一起。

image

当新版本微服务完成测试后,我们改变代理的路径(route)

image

最终,我们就可以移除旧版本微服务,开始使用新服务。

image

唯一明显的不同就是,由于微服务体量较小,我们不需要额外的服务器存放新版本。现在,我们终于可以实现持续的(频繁的)自动部署,提高研发速度,零宕机时间,并且可以在出现错误时进行回滚工作。

原文发布时间为:2016-11-08
本文作者:胡帅
本文来自云栖社区合作伙伴EAWorld,了解相关信息可以关注EAWorld。

相关文章
|
人工智能 测试技术 API
AI计算机视觉笔记二十 九:yolov10竹签模型,自动数竹签
本文介绍了如何在AutoDL平台上搭建YOLOv10环境并进行竹签检测与计数。首先从官网下载YOLOv10源码并创建虚拟环境,安装依赖库。接着通过官方模型测试环境是否正常工作。然后下载自定义数据集并配置`mycoco128.yaml`文件,使用`yolo detect train`命令或Python代码进行训练。最后,通过命令行或API调用测试训练结果,并展示竹签计数功能。如需转载,请注明原文出处。
免去授权设置,不用授权的方法有哪些?
2021年年初淘宝的一则公告开始的,淘宝年初发了一则公告,大意是说:“以后淘宝官方的服务平台里的复制宝贝类应用,客户在运用这类应用,复制淘宝店铺的宝贝到自己店铺的时候,必须先取得被复制店铺的授权。”,就这样,就有了复制淘宝宝贝授权的样的说法。
|
弹性计算 Ubuntu 安全
阿里云服务器ecs如何选择操作系统(Linux+Window) - 阿里云建站
如何选择适合网站的阿里云云服务器ECS操作系统,阿里云云服务器ECS的操作系统有什么区别,阿里云linux服务器和windows服务器有何不同呢?
749 0
|
9天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
8天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
372 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
8天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
363 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
20天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1342 8
|
2天前
|
存储 JSON 安全
加密和解密函数的具体实现代码
加密和解密函数的具体实现代码
193 136