写点什么

单体应用与微服务优缺点辨析

  • 2015-04-08
  • 本文字数:1990 字

    阅读完需:约 7 分钟

近日,Java Code Geeks 发表了一篇文章,分析了单体应用与微服务的优缺点,并建议使用微服务重构现有的应用程序。

通俗地讲,“单体应用(monolith application)”就是将应用程序的所有功能都打包成一个独立的单元,可以是 JAR、WAR、EAR 或其它归档格式。单体应用有如下优点:

  • 为人所熟知:现有的大部分工具、应用服务器、框架和脚本都是这种应用程序;
  • IDE**** 友好:像 NetBeans、Eclipse、IntelliJ 这些开发环境都是针对开发、部署、调试这样的单个应用而设计的;
  • 便于共享:单个归档文件包含所有功能,便于在团队之间以及不同的部署阶段之间共享;
  • 易于测试:单体应用一旦部署,所有的服务或特性就都可以使用了,这简化了测试过程,因为没有额外的依赖,每项测试都可以在部署完成后立刻开始;
  • 容易部署:只需将单个归档文件复制到单个目录下。

目前为止,单体应用已经很好地服务了我们,未来无疑还会继续发挥重要作用。但是,不管如何模块化,单体应用最终都会因为团队壮大、成员变动、应用范围扩展等出现问题。下面是单体应用的一些不足:

  • 不够灵活:对应用程序做任何细微的修改都需要将整个应用程序重新构建、重新部署。开发人员需要等到整个应用程序部署完成后才能看到变化。如果多个开发人员共同开发一个应用程序,那么还要等待其他开发人员完成了各自的开发。这降低了团队的灵活性和功能交付频率;
  • 妨碍持续交付:单体应用可能会比较大,构建和部署时间也相应地比较长,不利于频繁部署,阻碍持续交付。在移动应用开发中,这个问题会显得尤为严重;
  • 受技术栈限制:对于这类应用,技术是在开发之前经过慎重评估后选定的,每个团队成员都必须使用相同的开发语言、持久化存储及消息系统,而且要使用类似的工具,无法根据具体的场景做出其它选择;
  • 技术债务:“不坏不修(Not broken,don’t fix)”,这在软件开发中非常常见,单体应用尤其如此。系统设计或写好的代码难以修改,因为应用程序的其它部分可能会以意料之外的方式使用它。随着时间推移、人员更迭,这必然会增加应用程序的技术债务。

而随着业务需求的快速发展变化,敏捷性、灵活性和可扩展性需求不断增长,迫切需要一种更加快速高效的软件交付方式。微服务就是一种可以满足这种需求的软件架构风格。单体应用被分解成多个更小的服务,每个服务有自己的归档文件,单独部署,然后共同组成一个应用程序。这里的“微”不是针对代码行数而言,而是说服务的范围限定到单个功能。微服务有如下特点:

  • 领域驱动设计:应用程序功能分解可以通过 Eric Evans 在《领域驱动设计》中明确定义的规则实现;每个团队负责与一个领域或业务功能相关的全部开发;团队拥有全系列的开发人员,具备用户界面、业务逻辑和持久化存储等方面的开发技能;
  • 单一职责原则:每个服务应该负责该功能的一个单独的部分,这是 SOLID 原则之一;
  • 明确发布接口:每个服务都会发布一个定义明确的接口,而且保持不变;服务消费者只关心接口,而对于被消费的服务没有任何运行依赖;
  • 独立部署、升级、扩展和替换:每个服务都可以单独部署及重新部署而不影响整个系统。这使得服务很容易升级,每个服务都可以沿着《Art of Scalability》一书定义的 X 轴和 Z 轴进行扩展;
  • 可以异构 / 采用多种语言:每个服务的实现细节都与其它服务无关,这使得服务之间能够解耦,团队可以针对每个服务选择最合适的开发语言、持久化存储、工具和方法;
  • 轻量级通信:服务通信使用轻量级的通信协议,例如,同步的 REST,异步的 AMQP、STOMP、MQTT 等。

相应地,微服务具有如下优点:

  • 易于开发、理解和维护;
  • 比单体应用启动快;
  • 局部修改很容易部署,有利于持续集成和持续交付;
  • 故障隔离,一个服务出现问题不会影响整个应用;
  • 不会受限于任何技术栈。

微服务看上去像一枚银弹,可以解决许多软件开发方面的问题。这看上去很美好,但并不易于实现。微服务会极大地增加运维工作量,InfoWorld 在一篇文章中明确指出:

使用微服务,一些技术债务势必从开发转到运维,因此,你最好有一个一流的开发运维团队。

因此,微服务对基础设施提出了一些额外的需求。通常,我们将它们总称为 NoOps ,本质上讲,就是一组服务,提供一个更好的应用程序部署流程并确保其运行,包括服务复制、服务发现、服务恢复和服务监控。

不过,即使具备了上述条件,也并不是说就要抛弃现有的应用程序,在大多数情况下,我们无法做到。因此,我们要构建一种方法,依据它使用微服务重构现有的应用程序。虽然重构过程并不简单,但长远来看,重构一个单体应用可以一次性偿还所有的技术债务。

Netflix 是使用微服务的一个典型代表,它发表了数篇文章( 1 2 3 4 5 6 )分享采用微服务的一些经验,感兴趣的读者可以进一步阅读。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流。

2015-04-08 03:0821076
用户头像

发布了 1008 篇内容, 共 389.4 次阅读, 收获喜欢 344 次。

关注

评论

发布
暂无评论
发现更多内容

工赋开发者社区 | 定了!就在7月30日!

工赋开发者社区

技术分享 工业 峰会

人工智能助力复工复产,模版 OCR 轻松搞定健康码识别

亚马逊云科技 (Amazon Web Services)

人工智能 Lambda

【刷题记录】22. 括号生成

WangNing

7月月更

ES6 类聊 JavaScript 设计模式之行为型(一)

devpoint

JavaScript 设计模式 ECMAScript 6 7月月更

基础+框架+数据库+系统设计+算法,2022阿里最新Java面试突击手册我粉了

Java永远的神

Java 数据库 spring 面试 JVM

知识管理系统是什么?你需要知道这些

Geek_da0866

发评测赢好礼 | Serverless 函数计算征集令

阿里巴巴云原生

阿里云 Serverless 云原生

SpringBoot应用使用Docker实现远程部署(保姆教程)

技术小生

Docker 7月月更

参数解析与跳石板

未见花闻

7月月更

中天钢铁在 GPS、 AIS 调度中使用 TDengine

TDengine

数据库 tdengine 时序数据库

RocketMQ—(总结)一篇就搞懂RocketMQ

IT巅峰技术

客户案例 | 聚焦流程体验,助银行企业APP迭代

易观分析

银行 客户 银行app

企业内部信息碎片化该怎么办?不妨试试这样做

Baklib

聊聊css中文字的换行问题

南极一块修炼千年的大冰块

7月月更

低代码工具有哪些特色?明眼人都能看出来的低代码两大发展轨迹!

优秀

低代码 低代码平台

Docker 安装 Minio 搭建属于自己的文件服务器

宁在春

Docker Minio 7月月更

深度解析Java静态代理与动态代理模式的实现

了不起的程序猿

Java java程序员 java编程

模块八作业 - 消息数据 MySQL 表设计

Elvis FAN

3分钟创建Serverless Job 定时获取新闻热搜

云端explorer

Serverless Job 新闻热搜 场景搭建

OPPO 自研大规模知识图谱及其在数智工程中的应用

NebulaGraph

知识图谱 NebulaGraph

MPLS基础知识概述

穿过生命散发芬芳

MPLS 7月月更

如何在github的pages部署hexo实现代码提交到仓库自动部署

娃娃菜

GitHub Pages 签约计划第三季

客户案例|生学教育依托观测云打造可观测智慧教育新生态

观测云

Web3.0 时代,基于P2PDB实现一款Dapp的技术理论

Rock-李益

dapp 去中心化 去中心化数据库 p2pdb

阿里云消息队列 Kafka-消息检索实践

阿里巴巴云原生

kafka 阿里云 云原生 检索 消息

唠唠python的作用域,看看每个变量都为自己打下了多少江山

迷彩

Python 函数 作用域 7月月更

《TiDB 6.x in Action》发布,凝聚社区集体智慧的 6.x 实践汇总!

TiDB 社区干货传送门

数据库 分布式数据库 TiDB

车联网的数据安全该怎么保护

Geek_99967b

小程序 物联网

洋葱集团携手OceanBase实现分布式升级,全球数据首次实现跨云融合

OceanBase 数据库

B站713事故后的多活容灾建设|TakinTalks大咖分享

TakinTalks稳定性社区

故障 稳定性保障

企业数字化转型成大趋势,选对在线协作工具很重要

Baklib

单体应用与微服务优缺点辨析_架构_谢丽_InfoQ精选文章