mirror of
https://github.com/DocsHome/microservices.git
synced 2025-12-08 19:25:13 +00:00
Update 1-introduction-to-microservices.md
This commit is contained in:
parent
cfcb041615
commit
15b5548efb
@ -1,37 +1,37 @@
|
||||
# 1、微服务简介
|
||||
目前微服务受到很多关注:文章、博客、社交媒体上的讨论和会议演讲。他们正在迅速走向[加德纳技术成熟度曲线(Gartner Hype cycle)](http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp)的高峰。与此同时,也有持怀疑态度的软件社区人员认为微服务没什么新鲜可言。反对者声称它的思想只是面向服务架构(SOA)的重塑。然而,无论是炒作还是怀疑,不可否认微服务架构模式具有非常明显的优势——特别是在实施敏捷开发和复杂的企业应用交付方面。
|
||||
如今微服务倍受关注:文章、博客、社交媒体讨论和会议演讲。微服务的走向正在迅速朝向[加德纳技术成熟度曲线(Gartner Hype cycle)](http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp)的高峰。与此同时,也有持怀疑态度的软件社区人员认为微服务没什么新鲜可言。反对者声称它的思想只是面向服务架构(SOA)的重塑。然而,无论是炒作还是怀疑,不可否认微服务架构模式具有非常明显的优势——特别是在实施敏捷开发和复杂的企业应用交付方面。
|
||||
|
||||
本章节是七章之中介绍关于的设计、构建和部署微服务方面的内容。您将了解微服务的由来和与传统[单体应用模式](http://microservices.io/patterns/monolithic.html)的比较。这本电子书描述了许多关于微服务架构方面的内容。无论是对您的项目的意义,或者是如何去应用它,您都将了解到微服务架构模式的优点和缺点。
|
||||
本书的七个章主要介绍如何设计、构建和部署微服务,这是本书的第一章。在此章节中,您将了解微服务的由来和与传统[单体应用模式](http://microservices.io/patterns/monolithic.html)的对比。这本电子书描述了许多关于微服务架构方面的内容。无论是项目意义还是实施方面,您都将了解到微服务架构模式的优点和缺点。
|
||||
|
||||
我们先来看看为什么要考虑使用微服务。
|
||||
|
||||
## 1.1、构建单体应用
|
||||
我们想一下,您开始制作一个新的打车应用,打算与 Uber 和 Hailo 竞争。经过初步交流与需求收集,您将手动或者使用类似 Rails、Spring Boot、Play或者Maven等平台来生成一个新项目。
|
||||
我们想一下,您开始开发一个打车应用,打算与 Uber 和 Hailo 竞争。经过初步交流和需求收集,您将手动或者使用类似 Rails、Spring Boot、Play 或者 Maven 等平台来生成一个新项目。
|
||||
|
||||
这个新应用是一个模块化的六边形架构,如图 1-1 所示:
|
||||
该新应用是一个模块化的六边形架构,如图 1-1 所示:
|
||||
|
||||

|
||||
|
||||
应用程序的核心是由模块实现的业务逻辑,它定义了服务、领域对象和事件。围绕核心的是与外部世界接口对接的适配器。适配器示例包括了数据库访问组件、生产和消费消息的消息组件和 web 组件,它们暴露了 API 或者实现了一个 UI。
|
||||
该应用的核心是由模块实现的业务逻辑,它定义了服务、领域对象和事件。围绕核心的是与外部世界接口对接的适配器。适配器示例包括数据库访问组件、生产和消费消息的消息组件和暴露了 API 或实现了一个 UI 的 web 组件。
|
||||
|
||||
尽管有一个逻辑模块化的架构,但应用程序被作为一个整体进行打包和部署。实际格式取决于应用程序的语言和框架。例如,许多 Java 应用程序被打包成 WAR 文件并部署在如 Tomcat 或者 Jetty 之类的应用服务器上。其他 Java 应用程序是打包成自包含(self-contained)的可执行 JAR。类似地,Rails 和 Node.js 应用程序被打包为目录层次结构。
|
||||
尽管有一个逻辑模块化的架构,但应用程序被作为一个单体进行打包和部署。实际格式取决于应用程序的语言和框架。例如,许多 Java 应用程序被打包成 WAR 文件部署在如 Tomcat 或者 Jetty 之类的应用服务器上。其他 Java 应用程序被打包成自包含(self-contained)的可执行 JAR。类似地,Rails 和 Node.js 应用程序被打包为有目录层次的结构。
|
||||
|
||||
以这种风格编写的应用是很常见的。他们很容易开发,因为我们的 IDE 和其他工具专注于构建单个应用程序。这些应用程序也很容易测试。您可以通过简单地启动并使用如 Selenium 测试包来测试 UI 以轻松地实现端到端(end-to-end)测试。单体应用同样易于部署。你只需拷贝打包好的应用程序到服务器。您还可以通过运行多个副本和结合负载均衡器来扩展应用。在项目的早期阶段,它运作良好。
|
||||
以这种风格编写的应用是很常见的。他们很容易开发,因为我们的 IDE 和其他工具就是专注于构建单体应用。这些应用程序也很容易测试。您可以通过简单地启动并使用如 Selenium 测试包来测试 UI 以轻松地实现端到端(end-to-end)测试。单体应用同样易于部署。你只需拷贝打包好的应用程序到服务器。您还可以通过运行多个副本和结合负载均衡器来扩展应用。在项目的早期阶段,它可以良好运作。
|
||||
|
||||
## 1.2、走向单体地狱
|
||||
不幸的是,这种简单的方法有很大的局限性。成功的应用有一个趋势,随着时间推移而变得越来越臃肿。在每个冲刺时期,您的开发团队实现了更多的用户需求,这意味着添加了许多行代码。几年之后,您的小而简单的应用将会逐渐成长为[庞然大物似的单体](http://microservices.io/patterns/monolithic.html)。为了给出一个极端的示例,我最近和一位开发者做了交谈,他正在编写一个工具用于从他们的数百万行代码(lines of code,LOC)应用中分析数千个 JAR 之间的依赖。我相信这是大量开发者在多年齐心协力下创造了这样的野兽。
|
||||
不幸的是,这种简单的方法有很大的局限性。成功的应用有一个趋势,随着时间推移而变得越来越臃肿。您的开发团队在每个冲刺阶段都要实现了更多的用户需求,这意味着需要添加了许多行代码。几年之后,您的小而简单的应用将会逐渐成长为[庞然大物似的单体](http://microservices.io/patterns/monolithic.html)。为了给出一个极端的示例,我最近和一位开发者做了交谈,他正在编写一个工具用于从他们的数百万行代码(lines of code,LOC)应用中分析出数千个 JAR 之间的依赖。我相信这是大量开发者在多年齐心协力下创造了这样的野兽。
|
||||
|
||||
一旦您的应用程序成为了一个庞大、复杂的单体,您的开发组织可能陷入了一个令人痛苦的世界。敏捷开发和交付的任何一次尝试都将原地徘徊。一个主要问题是应用程序实在是非常复杂。对于任何一个开发人员来说,这是在太大了,这是可以理解的。最终,正确地修复 bug 和实现新功能变得非常困难且耗时。此外,这个趋势就像是往下的螺旋。如果基本代码难以理解,那么改变将不会变得正确。您最终得到的是一个巨大且不可思议的[大泥球](http://www.laputan.org/mud/)。
|
||||
一旦您的应用程序成为了一个庞大、复杂的单体,您的开发组织可能陷入了一个痛苦的世界。敏捷开发和交付的任何一次尝试都将原地徘徊。一个主要问题是应用程序实在是非常复杂。对于任何一个开发人员来说,这实在太大了,这是可以理解。最终,正确地修复 bug 和实现新功能变得非常困难而耗时。此外,这个趋势就像是往下的螺旋。如果基本代码都难以理解,那么改变也不会变得正确,您最终得到的将是一个巨大且不可思议的[大泥球](http://www.laputan.org/mud/)。
|
||||
|
||||
应用程序的规模也将减缓发展。应用程序越大,启动的时间越长。我[调查](https://plainoldobjects.com/2015/05/13/monstrous-monoliths-how-bad-can-it-get/)过开发者们的单体应用的大小和性能,一些报告的启动时间为 12 分钟。我也听说过应用程序启动需要 40 分钟以上的怪事。如果开发人员经常要重启应用服务器,那么很大一部分时间都是在等待中度过,他们的生产力将受到限制。
|
||||
|
||||
另一个大问题是,复杂的单体应用本身就是持续部署的障碍。如今,SaaS 应用发展到了每天可将变更推送到生产中多次。这对于复杂的单体非常困难,因为您必须重新部署整个应用程序才能更新其中任何一部分。这对我之前提到的漫长的启动时间也不会有什么帮助。此外,因为变化的影响通常不是很清楚,您很可能需要做大量的手工测试。因此,持续部署是不可能做到的。
|
||||
另一个大问题是,复杂的单体应用本身就是持续部署的障碍。如今,SaaS 应用发展到了每天可多次将变更推送到生产环境中。这对于复杂的单体非常困难,因为您需要重新部署整个应用程序才能更新其中任何一部分。对于我之前提到的漫长启动时间,这也不会是什么好事。此外,因为变化所产生的影响通常不是很明确,您很可能需要做大量的手工测试。因此,持续部署是不可能做到的。
|
||||
|
||||
当不同模块存在资源需求冲突时,单体应用也可能难以扩展。例如,一个模块可能会执行 CPU 密集型图像处理逻辑,理想情况下是部署在 [Amazon EC2 Compute Optimized 实例](http://aws.amazon.com/about-aws/whats-new/2013/11/14/announcing-new-amazon-ec2-compute-optimized-instances/)中。另一个模块可能是内存数据库,最适合 [EC2 Memory-optimized 实例](https://aws.amazon.com/cn/about-aws/whats-new/2014/04/10/r3-announcing-the-next-generation-of-amazon-ec2-memory-optimized-instances/)。然而,因为这些模块被部署在一起,您必须在硬件选择上做出妥协。
|
||||
当不同模块存在资源需求冲突时,单体应用可能难以扩展。例如,一个模块可能会执行 CPU 密集型图像处理逻辑,理想情况下是部署在 [Amazon EC2 Compute Optimized 实例](http://aws.amazon.com/about-aws/whats-new/2013/11/14/announcing-new-amazon-ec2-compute-optimized-instances/)中。另一个模块可能是内存数据库,最适合部署到 [EC2 Memory-optimized 实例](https://aws.amazon.com/cn/about-aws/whats-new/2014/04/10/r3-announcing-the-next-generation-of-amazon-ec2-memory-optimized-instances/)。然而,因为这些模块被部署在一起,您必须在硬件选择上做出妥协。
|
||||
|
||||
单体应用的另一个问题是可靠性。因为所有模块运行在同一进程。任何模块的一个 bug,比如内存泄漏,可能会拖垮整个进程。此外,由于应用程序的所有的实例都是相同的,该错误将影响到整个应用的可用性。
|
||||
单体应用的另一个问题是可靠性。因为所有模块运行在同一进程。任何模块的一个 bug,比如内存泄漏,可能会拖垮整个进程。此外,由于应用程序的所有实例都是相同的,该错误将影响到整个应用的可用性。
|
||||
|
||||
最后但并非是最不重要的,单体应用使得采用新的框架和语言变得非常困难。例如,我们假设您有 200 万行代码使用了 XYZ 框架编写。使用较新的 ABC 框架来重写整个应用,这将是非常昂贵的(在时间和成本方面),即使那个框架非常好。因此,这对于采用新技术是一个非常大的障碍。您在项目开始时无论选择何种新技术都将会感到困扰。
|
||||
最后但同样重要,单体应用使得采用新框架和语言变得非常困难。例如,我们假设您有 200 万行代码使用了 XYZ 框架编写。使用较新的 ABC 框架来重写整个应用,这将是非常昂贵的(在时间和成本方面),即使框架非常好。因此,这对于采用新技术是一个非常大的障碍。您在项目开始时无论选择何种新技术都将会感到困扰。
|
||||
|
||||
总结一下:您有一个成功的关键业务应用程序,它已经发展成为一个只有少数开发人员(如果有的话)能够理解的巨大单体。它使用了过时、非生产性技术编写的,这使得招聘优秀开发人员变得困难。应用程序难以扩展,不可靠。因此敏捷开发和应用交付是不可能的。
|
||||
|
||||
@ -109,7 +109,7 @@
|
||||
|
||||
By Floyd Smith
|
||||
|
||||
[10000 个网站中有超过 50%](http://w3techs.com/technologies/cross/web_server/ranking) 使用 NGINX,这主要是因为它具有作为反向代理服务器的能力。您可以 NGINX 放在当前应用程序前面甚至是数据库服务器以获取各种功能 —— 更高的性能、更高的安全性、可扩展性、灵活性等。你现有的应用程序只需要配置代码和作出很少或无需改变。对于存在性能压力的站点,或者预计未来存在高负荷,效果看起来似乎没那么神奇。
|
||||
[10000 个网站中有超过 50%](http://w3techs.com/technologies/cross/web_server/ranking) 使用 NGINX,这主要是因为它具有作为反向代理服务器的能力。您可以把 NGINX 放在当前应用程序甚至是数据库服务器之前以获取各种功能 —— 更高的性能、更高的安全性、可扩展性、灵活性等。你现有的应用程序只需要配置代码和作出很少或无需改变。对于存在性能压力的站点,或者预计未来存在高负荷,效果看起来似乎没那么神奇。
|
||||
|
||||
那么这与微服务有什么关系呢?实现一个反向代理服务器,并使用 NGINX 的其他功能来为您提供架构灵活性。反向代理服务器、静态和应用文件缓存、SSL/TLS 和 HTTP/2 都会从您的应用程序剔除。让应用程序只做它该做的事,NGINX 还可作为负载均衡器,微服务实施过程中的一个关键角色。先进的 NGINX Plus 的功能包含了复杂的负载均衡算法、多种方式的会话持久和管理监控,这些对微服务尤其有用(NGINX 最近还增加了使用 DNS SRV 记录的服务发现支持,这是一个顶尖的功能)。而且,如本章所述,NGINX 可以自动化部署微服务。
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user