【翻訳】マイクロサービス-Martinファウラー(RPM)

著者:YYGCui

出典:のhttp://blog.cuicc.com/blog/2015/07/22/microservices/

 

過去数年間で、「マイクロサービスのアーキテクチャ」という用語が生まれて、それがサービスのセットとして設計された特定の方法でソフトウェアアプリケーションを独立して展開することができますについて説明します。分散制御・オートメーションの展開、エンドポイント・インテリジェンス、言語とデータ:この建築様式が明確に定義されていますが、いくつかの共通の特徴は、組織、運用能力にありますされていないが。

 

「マイクロ・サービス」 - 路上で混雑ソフトウェアアーキテクチャ新しい用語があります。一方で私たちの自然な傾斜が通過する際に、それに軽蔑一目ですが、私たちは、この用語は、ソフトウェアシステムより魅力的なスタイルを記述していることが分かりました。私たちが見てきた、このスタイルを使用して多くのプロジェクトは、過去数年の間に存在し、エンタープライズアプリケーションのデフォルト・スタイルのアーキテクチャを構築するとき、それは私たちの同僚が使用になってきたように、これまでの結果は、かなり良いです。しかし、残念ながら、マイクロサービスのスタイルとどのようにこのスタイルを使用することです何まとめてあまりにも多くの情報ではありません。

短い、マイクロサービス・アーキテクチャ・スタイルにおける小さなサービスアプローチのグループのための単一のアプリケーションを開発する方法である[1]に、各サービスは、独自のプロセスで実行され、サービス間の通信軽量通信機構を使用して(通常HTTPリソースAPI)。これらのサービスは、ビジネス機能を中心に構築し、自動展開機構によって独立して展開することができます。これらのサービスは、さまざまなデータ・ストレージ・テクノロジーを使用して、利用可能な異なる言語で開発された最も一般的な小型の集中管理サービスです。

スタイルは、単量体を比較したマイクロサービススタイルの開始を説明するのに役立ちます:モノマーアプリケーションは、単一のユニットとして構成されています。エンタープライズアプリケーションは通常、3つの部分から構成:データテーブルの数、共通のリレーショナルデータベース管理システムコンポーネントに挿入することで、データベース((HTMLページとJavascriptの組成の開発マシン上で実行されているブラウザで)クライアント側のユーザーインターフェイスを)、サーバアプリケーション。サーバアプリケーション処理HTTPリクエストは、HTTPブラウザビューを充填するために送信されるように、選択し、データを更新し、データベースから取得した論理フィールドを行います。アプリケーションサーバは、単一の論理的実行可能性モノマーである[2]。システム内のすべての変更は、再構築に関与し、サーバーの新しいバージョンを展開します。

このようなモノマーは、サーバが最も自然な方法であるようなシステムを構築します。すべてのロジックの処理要求は、アプリケーションのプログラミング言語ゾーニング分類、機能、および名前空間の基本的な機能を使用することができ、単一のプロセスで実行されています。あなたは真剣に開発マシン上でテストアプリケーションを実行し、展開の変更が適切にテストされ、本番環境に配備されていることを確認するためにパイプラインを使用します。モノマーの水平方向の拡張は、ロードバランサの背後に複数のインスタンスを実行することによって達成することができます。

より多くのアプリケーションがクラウドに配備されている、特にとして、モノリシックアプリケーションは成功することができますが、彼らのために成長している不満があります。でも、アプリケーションの変更の一部だけならば、だけでなく、再構築する必要があり、全体のモノマーを展開 - チェンジサイクルが一緒にバンドルされています。時間が経つにつれて、通常は困難なだけモジュールで発生を変化させることができる優れたモジュラー型アーキテクチャを維持することは困難だろう変更する必要があります。プログラムの拡張要件は、アプリケーション全体ではなく、追加のリソースセクションのアプリケーションを拡張する必要性のために拡張すること。

 

図1:モノマーとmicroService

これらの挫折サービス指向マイクロアーキテクチャスタイル:サービスパック用のアプリケーションを構築します。独立したサービスが展開されていることに加えて、独立して、外部固定境界を提供する各サービスモジュールを展開。でも、別のチームの管理によって開発された異なる言語で異なるサービスを可能にします。

我々はマイクロサービスのスタイルが戻って、少なくともUnixの設計思想にトレースすることができ、その性質上、小説、革新的であることを主張しません。しかし、我々は十分な人々が慎重にマイクロサービスアーキテクチャを考慮するとは思わない、とあなたはそれを使用する場合のソフトウェアの多くは良くなります。

サービスのマイクロアーキテクチャの機能

我々はマイクロサービスアーキテクチャスタイル正式な定義を与えることはできませんが、我々はアーキテクチャの共通の一部に沿って見るかを説明しようとすることができます。一般的な用語のいずれかの定義を概説し、すべてではないこれらの共通点はマイクロサービスアーキテクチャのスタイルですが、我々はほとんどの機能のマイクロサービスアーキテクチャスタイルの展示品のほとんどを期待しています。この作家はかなり緩いアクティブなユーザーコミュニティとなっていますが、私たちの目的は、私たちの仕事を記述しようとすることであり、我々はチームの同様の努力の一部が見て、聞いて知っています。特に、我々は定義に準拠して制定することはできません。

のサービス・コンポーネントを通じ

限り、我々は、ソフトウェア業界では、現実世界の構造のように、私たちは物事同じを見る方法を、システムを構築するために一緒に部品を通って挿入された欲求を従事されているよう。過去20年間で、我々は大きな進歩を遂げた公共図書館の多数のコンパイルの言語のほとんどの部分のためのプラットフォームとして見てきました。

どのようなコンポーネントはい:それはアセンブリに来るとき、私たちは、定義の困難に遭遇します。私たちの定義は次のとおりです。コンポーネントは独立して独立したユニット交換とソフトウェアのアップグレードです。

マイクロサービスアーキテクチャは、ライブラリを使用しますが、コンポーネントベースのソフトウェアの主な方法は、サービスに分割されます。我々のライブラリは、多くのオブジェクト指向プログラムがである(番組へのリンクとして定義され、コンポーネントを呼び出すためにメモリ関数呼び出しを使用し、サービスはWebサービス要求またはRPC通信メカニズムを介して(リモートプロシージャコール)する処理の外部コンポーネントでありますサービスオブジェクトの概念が異なっている[3]。)

アセンブリとしてサービスを使用しての代わりに、図書館サービスを使用する主な理由は、スタンドアロンの展開のために利用可能です。アプリケーションを持っている場合、[4]、アプリケーション全体を再デプロイすることになりつの成分の変更から成る単一のプロセスで複数のライブラリで構成されています。アプリケーションが複数のサービスに分解することができた場合でも、その後、単一のサービスの変更は、サービスが可能に再配備する必要があります。もちろん、これは絶対的なものではなく、いくつかの変更が変更されたサービス・インターフェースは、いくつかのコラボレーションが発生するが、良いマイクロサービスアーキテクチャの目的は、凝集国境通過であるとの合意にこれらのコラボレーションを最小限にするためのメカニズムを進化しました。

より明示的なコンポーネント・インターフェースの構成要素としてサービスを使用する別の結果。ほとんどの言語は、明確なパブリッシングインターフェースを定義するための良いメカニズムを持っていません。コンポーネント間のきつすぎるのカップリングにつながるパッケージアセンブリを、破るためにクライアントを防ぐために、通常の文書のみとルール。リモート呼び出しのための明確な機構を介してサービスが簡単にこれらを回避することができます。

リモートAPIは、粒度の粗いように設計されていて、呼び出し元のプロセス内の長距離通話よりも高価ないくつかの欠点を持っていないサービスを使用するように、多くの場合、使用する方が不便です。あなたが到達するような行動のアクションがより困難に、あなたは、プロセスの境界を越えたときにコンポーネント間の責任の割り当てを変更する必要がある場合。

直感的な推定値は、我々が観察されたプロセスが1つのマッピングサービスが、唯一の視覚的な評価を実行している場合にのみ。そのようなデータベースアプリケーション・プロセスなどのサービスマルチプロセス組成物によって提供されて、これらのプロセスは常に開発され、一緒に展開され、そしてのみこのサービスを使用しています。

組織の運用能力アラウンド

アプリケーションが大きなメンバーに分割したい場合には、通常、UIチーム、サーバーサイドのロジック・チーム、チームのデータベース部門につながる、技術的なレベルの管理に焦点を当てました。チームはこれらの技術の線で分割された場合でも簡単な変更は、クロスチームの時間と予算の承認につながることができます。スマートチームはあまり悪、これらの最適化に焦点を当てます-彼らはアクセスを強制するアプリケーションでのみビジネスロジックを。言い換えれば、どこにでもロジック。このルールは、コンウェイである一例では、[5]機能します。

(広義の)任意の設計システムは、設計組織を生成する、彼の通信構造は、組織の構造です。

-メルヴィンコンウェイ 1967

 

図2:職場でのコンウェイの法則

異なる方法を用いたマイクロ・セグメンテーションサービスは、組織の運用能力の周りのサービスに分割されます。これらのサービスは、ユーザー・インターフェース、永続ストレージ、および任意の外部のコラボレーションなどのビジネスソフトウェア実装のスタックの幅を、取ります。ユーザーエクスペリエンス、データベース、プロジェクト管理:そのため、チームはオールラウンドの能力開発ニーズを含め、クロスファンクショナルです。

 

図3:チームの境界が強化され、サービスの境界

www.comparethemarket.comは、この方法で編成会社です。製品の作成と運用を担当するクロスファンクショナルチームが、製品には、メッセージ・バスを介して通信する個々のサービスの数に分割されています。

これはよくあるケースではありませんが、大規模なモノリシックアプリケーションは常に、モジュール式の運用能力に前後になることができます。もちろん、我々は、それ自体がビジネスラインによって分割チームになり、大きなモノリシックなアプリケーションチームの作成を促すだろう。私たちは、このような状況の主な問題は、彼らがコンテキストの多くを中心に組織される傾向があるということです参照してください。モジュールの境界を越えて複数のモノマー、個々のチームメンバーならば、彼らは短期記憶に入れることは困難です。また、当社は、モジュラーコースは強制するルールの多くを必要ご覧ください。それが簡単にチーム明確な境界を維持すること、必要なサービスコンポーネントをより明確に分離します。

サイドバー:どのくらいのマイクロサービス?

「マイクロ・サービス」は、その代わりに、この建築様式となっていますが、名前がサービス上の不幸な焦点の大きさ、および議論構成するもの「マイクロ」を与えていません。マイクロサービスの専門家との対話では、我々はサービスの様々なサイズがあることがわかりました。Amazonの最大のサービスレポートは、チームが12人を超えていないことを意味2つのピザチーム(つまり、チーム全体が送ら2枚のピザを食べてしまう)という概念を、従ってください。小さいサイズで、我々はこのような構成を参照して、6人のチームは、6つのサービスをサポートします。

これは、彼らが同じマイクロラベルサービスに集中することができないように異なる十分な遊びがあるかどうか、12人の個人やサービスのサイズを一食当たり個体あたり1の範囲で、疑問につながります。現在、我々はそれらを一緒に入れて、それが最善と思いました。しかし、このスタイルの詳細な探査で、我々は我々の見解を変更することが可能でなければなりません。

製品は、プロジェクトではありません

目標が完了するまでにいくつかのソフトウェアを提供することです:私たちは、パターンを使用して、ほとんどのアプリケーション開発プロジェクトを参照してください。ソフトウェアの完了が保守団体に配信された後、それは解散チームを構築します。

微服务支持者倾向于避免这种模式,而是认为一个团队应该负责产品的整个生命周期。对此一个共同的启示是亚马逊的理念 “you build, you run it” ,开发团队负责软件的整个产品周期。这使开发者经常接触他们的软件在生产环境如何工作,并增加与他们的用户联系,因为他们必须承担至少部分的支持工作。

产品思想与业务能力紧紧联系在一起。要持续关注软件如何帮助用户提升业务能力,而不是把软件看成是将要完成的一组功能。

没有理由说为什么同样的方法不能用在单体应用程序上,但服务的粒度更小,使得它更容易在服务开发者和用户之间建立个人关系。

智能端点和哑管道

当在不同进程间创建通信结构时,我们已经看到了很多的产品和方法,把显著的智慧强压进通信机制本身。一个很好的例子就是企业服务总线(ESB),在ESB产品中通常为消息路由、编排(choreography)、转化和应用业务规则引入先进的设施。

微服务社区主张另一种方法:智能端点和哑管道。基于微服务构建的应用程序的目标是尽可能的解耦和尽可能的内聚 - 他们拥有自己的领域逻辑,他们的行为更像经典UNIX理念中的过滤器 - 接收请求,应用适当的逻辑并产生响应。使用简单的REST风格的协议来编排他们,而不是使用像WS-Choreography或者BPEL或者通过中心工具编制(orchestration)等复杂的协议。

最常用的两种协议是使用资源API的HTTP请求-响应和轻量级消息传送[6]。对第一种协议最好的表述是

本身就是web,而不是隐藏在web的后面。

-- Ian Robinson

微服务团队使用的规则和协议,正是构建万维网的规则和协议(在更大程度上,是UNIX的)。从开发者和运营人员的角度讲,通常使用的资源可以很容易的缓存。

第二种常用方法是在轻量级消息总线上传递消息。选择的基础设施是典型的哑的(哑在这里只充当消息路由器) - 像RabbitMQ或ZeroMQ这样简单的实现仅仅提供一个可靠的异步交换结构 - 在服务里,智能仍旧存活于端点中,生产和消费消息。

单体应用中,组件都在同一进程内执行,它们之间通过方法调用或函数调用通信。把单体变成微服务最大的问题在于通信模式的改变。一种幼稚的转换是从内存方法调用转变成RPC,这导致频繁通信且性能不好。相反,你需要用粗粒度通信代替细粒度通信。

去中心化治理

集中治理的一个后果是单一技术平台的标准化发展趋势。经验表明,这种方法正在收缩 - 不是每个问题都是钉子,不是每个问题都是锤子。我们更喜欢使用正确的工具来完成工作,而单体应用程序在一定程度上可以利用语言的优势,这是不常见的。

把单体的组件分裂成服务,在构建这些服务时可以有自己的选择。你想使用Node.js开发一个简单的报告页面?去吧。用C++实现一个特别粗糙的近乎实时的组件?好极了。你想换用一个更适合组件读操作数据的不同风格的数据库?我们有技术来重建它。

当然,仅仅因为你可以做些什么,而不意味着你应该这样做 - 但用这种方式划分系统意味着你可以选择。

团队在构建微服务时也更喜欢用不同的方法来达标。他们更喜欢生产有用的工具这种想法,而不是写在纸上的标准,这样其他开发者可以用这些工具解决他们所面临的相似的问题。有时,这些工具通常在实施中收获并与更广泛的群体共享,但不完全使用一个内部开源模型。现在git和github已经成为事实上的版本控制系统的选择,在内部开放源代码的实践也正变得越来越常见。

侧边栏:微服务和SOA

当我们谈论微服务时,一个常见问题是它是否仅仅是十年前我们看到的面向服务的架构(SOA)。这一点是有可取之处的,因为微服务风格和SOA赞同的某些主张十分相似。然而,问题是SOA意味着很多不同的东西,而大多数时候,我们遇到的所谓的SOA和这里我们描述的风格明显不同,这种不同通常由于SOA专注于用于集成单体应用的ESB。

特别是我们已看到太多的搞砸的服务导向的实现,从趋向于隐藏ESB中的复杂性[7],到花费数百万并不产生任何价值的失败的多年举措,到积极抑制变化的集中治理模型,这有时很难看到过去的这些问题。

当然,微服务社区用到的许多技术从开发者在大型组织机构整合服务的经验中成长。Tolerant Reader模式就是这样的一个例子。使用简单协议是衍生自这些经验的另一个方法,使用网络的努力已做出远离中央标准的反应,坦率地说,中心标准已达到令人叹为观止的复杂性。(任何时候,你需要一个本体来管理你的本体,你知道你深陷困境。)

SOA的这种常见表现使得一些微服务倡导者完全拒绝SOA标签,尽管其他人认为微服务时SOA的一种形式[8],也许服务导向做得对。无论哪种方式,事实上,SOA意味着如此不同的事情,这意味着有一个术语来更清晰地定义这种架构风格是有价值的。

Netflix是遵守这一理念的很好的例子。尤其是,以库的形式分享有用的且经过市场检验的代码,这激励其他开发者用类似的方式解决相似的问题,同时还为采用不同方法敞开了大门。共享库倾向于聚焦在数据存储、进程间通信和我们接下来要深入讨论的基础设施自动化的共性问题。

对为服务社区来说,开销特别缺乏吸引力。这并不是说社区不重视服务合约。恰恰相反,因为他们有更多的合约。只是他们正在寻找不同的方式来管理这些合约。像Tolerant Reader和消费者驱动的契约(Consumer-Driven Contracts)这样的模式通常被用于微服务。
这些援助服务合约在独立进化。执行消费者驱动的合约作为构建的一部分,增加了信心并对服务是否在运作提供了更快的反馈。事实上,我们知道澳大利亚的一个团队用消费者驱动的合约这种模式来驱动新业务的构建。他们使用简单的工具定义服务的合约。这已变成自动构建的一部分,即使新服务的代码还没写。服务仅在满足合约的时候才被创建出来 - 这是在构建新软件时避免"YAGNI"[9]困境的一个优雅的方法。围绕这些成长起来的技术和工具,通过减少服务间的临时耦合,限制了中心合约管理的需要。

侧边栏:许多语言,许多选项

JVM作为平台的成长就是在一个共同平台内混合语言的最新例子。几十年来,破壳到高级语言利用高层次抽象的优势已成为一种普遍的做法。如同下拉到机器硬件,用低层次语言写性能敏感的代码一样。然而,很多单体不需要这个级别的性能优化和常见的更高层次的抽象,也不是DSL的。相反,单体通常是单一语言的并趋向于限制使用的技术的数量[10]。

也许去中心化治理的最高境界就是亚马逊广为流传的build it/run it理念。团队要对他们构建的软件的各方面负责,包括7*24小时的运营。这一级别的责任下放绝对是不规范的,但我们看到越来越多的公司让开发团队负起更多责任。Netflix是采用这一理念的另一家公司[11]。每天凌晨3点被传呼机叫醒无疑是一个强有力的激励,使你在写代码时关注质量。这是关于尽可能远离传统的集中治理模式的一些想法。

去中心化数据管理

数据管理的去中心化有许多不同的呈现方式。在最抽象的层面上,这意味着使系统间存在差异的世界概念模型。在整合一个大型企业时,客户的销售视图将不同于支持视图,这是一个常见的问题。客户的销售视图中的一些事情可能不会出现在支持视图中。它们确实可能有不同的属性和(更坏的)共同属性,这些共同属性在语义上有微妙的不同。

这个问题常见于应用程序之间,但也可能发生在应用程序内部,尤其当应用程序被划分成分离的组件时。一个有用的思维方式是有界上下文(Bounded Context)内的领域驱动设计(Domain-Driven Design, DDD)理念。DDD把一个复杂域划分成多个有界的上下文,并且映射出它们之间的关系。这个过程对单体架构和微服务架构都是有用的,但在服务和上下文边界间有天然的相关性,边界有助于澄清和加强分离,就像业务能力部分描述的那样。

侧边栏:久经考验的标准和执行标准

这有一点分裂,微服务团队倾向于避开企业架构组规定的那种严格的执行标准,但又很乐意使用甚至传教开放标准,比如HTTP、ATOM和其他威格士。

关键的区别是如何定制标准和如何执行。由诸如IETF等组织管理的标准仅当在世界范围内有几个有用的实现时才变成标准,这往往会从成功的开源项目成长起来。

这些标准是远离企业世界的标准。往往被一个几乎没有近期编程经验的或受供应商过度影响的组织开发的。

和概念模型的去中心化决策一样,微服务也去中心化数据存储决策。虽然单体应用程序更喜欢单一的逻辑数据库做持久化存储,但企业往往倾向于一系列应用程序共用一个单一的数据库 - 这些决定是供应商授权许可的商业模式驱动的。微服务更倾向于让每个服务管理自己的数据库,或者同一数据库技术的不同实例,或完全不同的数据库系统 - 这就是所谓的混合持久化(Polyglot Persistence)。你可以在单体应用程序中使用混合持久化,但它更常出现在为服务里。

对跨微服务的数据来说,去中心化责任对管理升级有影响。处理更新的常用方法是在更新多个资源时使用事务来保证一致性。这个方法通常用在单体中。

像这样使用事务有助于一致性,但会产生显著地临时耦合,这在横跨多个服务时是有问题的。分布式事务是出了名的难以实现,因此微服务架构强调服务间的无事务协作,对一致性可能只是最后一致性和通过补偿操作处理问题有明确的认知。

对很多开发团队来说,选择用这样的方式管理不一致性是一个新的挑战,但这通常与业务实践相匹配。通常业务处理一定程度的不一致,以快速响应需求,同时有某些类型的逆转过程来处理错误。这种权衡是值得的,只要修复错误的代价小于更大一致性下损失业务的代价。

基础设施自动化

在过去的几年中,基础设施自动化已经发生了巨大的变化,特别是云和AWS的演化已经降低了构建、部署和运维微服务的操作复杂度。

许多用微服务构建的产品或系统是由在持续部署和它的前身持续集成有丰富经验的团队构建的。团队用这种方式构建软件,广泛使用了基础设施自动化。如下面的构建管线图所示:

图5: 基础构建管道

因为这不是一篇关于持续交付的文章,我们这里将之光住几个关键特性。我们希望有尽可能多的信心,我们的软件正在工作,所以我们运行大量的自动化测试。促进科工作软件沿管道线“向上”意味着我们自动化部署到每个新的环境中。

一个单体应用程序可以十分愉快地通过这些环境被构建、测试和推送。事实证明,一旦你为单体投入了自动化生产之路,那么部署更多的应用程序似乎也不会更可怕。请记住,持续部署的目标之一是使部署枯燥,所以无论是一个或三个应用程序,只要它的部署仍然枯燥就没关系[12]。

侧边栏:使它容易做正确的事情

我们发现,作为持续交付和持续部署的一个后果,增加自动化的一个副作用是创造有用的工具,以帮助开发人员和运营人员。用于创造人工制品、管理代码库、起立(standing up)简单服务或添加标准监控和日志记录的工具现在都是很常见的。web上最好的例子可能是Netflix的开源工具集,但也有其他我们广泛使用的工具,如Dropwizard。

我们看到团队使用大量的基础设施自动化的另一个领域是在生产环境中管理微服务时。与我们上面的断言(只要部署是枯燥的)相比,单体和微服务没有太大的差别,各运营场景可以明显不同。

图6: 模块部署常常不同

为失效设计

使用服务作为组件的一个结果是,应用程序需要被设计成能够容忍服务失效。任何服务调用都可能因为供应者不可用而失败,客户端必须尽可能优雅的应对这种失败。与单体应用设计相比这是一个劣势,因为它引入额外的复杂性来处理它。结果是,微服务团队不断反思服务失效如何影响用户体验。Netflix的Simian Army在工作日诱导服务甚至是数据中心故障来测试应用程序的弹性和监测。

在生产环境中的这种自动化测试足够给大多数运营团队那种不寒而栗,通常在结束一周的工作之前。这不是说单体风格不能够进行完善的监测设置,只是在我们的经验中比较少见。

侧边栏:断路器和产品就绪代码

断路器(Circuit Breaker)与其他模式如Bulkhead和Timeout出现在《Release it!》中。这些模式是被一起实现的,在构建通信应用程序时,它们是至关重要的。这篇Netflix博文很好的解释了使用这些模式的应用程序。

既然服务随时都可能失败,那么能够快速检测故障,如果可能的话,能自动恢复服务是很重要的。微服务应用程序投入大量比重来进行应用程序的实时监测,既检查构形要素(每秒多少次数据请求),又检查业务相关指标(例如每分钟收到多少订单)。语义监测可以提供一套早期预警系统,触发开发团队跟进和调查。

这对微服务架构特别重要,因为微服务偏好编排和事件协作,这会带来突发行为。虽然很多专家称赞偶然涌现的价值,事实的真相是,突发行为有时可能是一件坏事请。监测对于快速发现不良突发行为是至关重要的,所以它可以被修复。

单体可以被构建成和微服务一样透明 - 事实上,它们应该是透明的。不同的是,你绝对需要知道在不同进程中运行的服务是否断开。对同一进程中的库来说,这种透明性是不大可能有用的。

侧边栏:同步调用被认为是有害的

任何时候,在服务间有大量的同步调用,你将遇到停机的乘法效应。简单地说,就是你的系统的停机时间编程各个组件停机时间的乘积。你面临一个选择,让你的调用变成异步或者管理停机时间。在www.guardian.co.uk,他们已在新平台实现了一个简单的规则 - 每个用户请求一个同步调用,而在Netflix,他们的平台API重设计成在API交换结构(fabric)建立异步性。

微服务团队希望看到为每个单独的服务设置的完善的监控和日志记录,比如控制面板上显示启动/关闭状态和各种各样的运营和业务相关指标。断路器状态、当前吞吐量和时延的详细信息是我们经常遇到的其他例子。

进化式设计

微服务从业者,通常有进化式设计背景并且把服务分解看做是进一步的工具,使应用程序开发者能够控制他们应用程序中的变更而不减缓变更。变更控制并不一定意味着变更的减少 - 用正确的态度和工具,你可以频繁、快速且控制良好的改变软件。

当你试图把软件系统组件化时,你就面临着如何划分成块的决策 - 我们决定分割我们的应用的原则是什么?组件的关键特性是独立的更换和升级的理念[13] - 这意味着我们要找到这样的点,我们可以想象重写组件而不影响其合作者。事实上很多微服务群组通过明确地预期许多服务将被废弃而不是长期演进来进一步找到这些点。

卫报网站是被设计和构建成单体应用程序的一个好例子,但它已向微服务方向演化。网站的核心仍是单体,但他们喜欢通过使用调用单体API构建的微服务添加新功能。这种方法对天然临时性的特性特别方便,比如处理体育赛事的专题页面。网站的这样一部分可以使用快速开发语言迅速的被放在一起,并且一旦赛事结束立即删除。在金融机构中,我们看到类似的方法,为一个市场机会添加新服务,并在几个月甚至几周后丢弃掉。

强调可替代性是模块设计更一般原则的一个特例,它是通过变更模式来驱动模块化的[14]。你想保持在同一模块中相同时间改变的事情。系统中很少变更的部分应该和正在经历大量扰动的部分放在不同的服务里。如果你发现你自己不断地一起改变两个服务,这是它们应该被合并的一个标志。

把组件放在服务中,为更细粒度的发布计划增加了一个机会。对单体来说,任何变更都需要完整构建和部署整个应用程序。而对微服务来说,你只需要重新部署你修改的服务。这可以简化和加速发布过程。坏处是,你必须担心一个服务的变化会阻断其消费者。传统的集成方法试图使用版本管理解决这个问题,但是微服务世界的偏好是只把版本管理作为最后的手段。我们可以避免大量的版本管理,通过把服务设计成对他们的提供者的变化尽可能的宽容。

微服务是未来吗?

我们写这篇文章的主要目的是讲解微服务的主要思想和原则。通过花时间做这件事情,我们清楚地认为微服务架构风格是一个重要的思想 - 它值得为企业应用程序认真考虑。我们最近用这种风格构建了一些系统,也知道别人用这种风格并赞成这种风格。

那些我们知道的以某种方式开拓这种架构风格的包括亚马逊,Netflix,卫报,英国政府数字服务部门,realestate.com.au,前锋和comparethemarket.com。2013年的会议电路中全是正向微服务类别转移的公司 - 包括Travis CI。此外还有大量的组织长期以来一直在做可归为微服务类别的事情,但是还没有使用这个名字。(这通常被称为SOA - 虽然,正如我们说过的,SOA有许多矛盾的形式。[15])

尽管有这些积极的经验,但是,我们并不认为我们确信微服务是软件架构的未来发展方向。虽然到目前为止,与单体应用程序相比,我们的经验是正面的,但我们意识到这样的事实,并没有经过足够的时间使我们做出充分的判断。

通常,你的架构决策的真正后果是在你做出这些决定的几年后才显现的。我们已经看到对模块化有强烈愿望的一个好团队用单体架构构建的项目,已经衰败了多年。很多人相信微服务是不太可能出现这种衰败的,因为服务界限是明确的,并且很难围绕它打补丁。然而,知道我们看到经过足够岁月的足够的系统,我们不能真正评估微服务架构有多么成熟。

人们当然有理由希望微服务时多么不成熟。在组件化中做任何努力,成功取决于软件在多大程度上适用于组件化。很难弄清楚组件边界在哪里。进化式设计承认获取正确边界的困难性和使它们易于重构的重要性。但当你的组件是带有远程通信的服务时,那么重构它比重构带有进程内库的服务难很多。跨服务边界移动代码是很困难的,任何接口变更都需要在参与者之间进行协调,需要添加向后兼容层,并且测试也变得更加复杂。

侧边栏:《构建微服务》

我们的同事Sam Newman花费2014年的大部分时间写了一本书,捕捉了我们构建微服务的经验。如果你想深入到这个话题中,这应该是你的下一步。

另一个问题是,如果组件不组成的干净利索,那么所有你做的是将复杂度从组件内部转移到组件之间的连接。不仅仅是把复杂性移到周围,它将复杂性移动到一个不太明确、难以控制的地方。在没有服务间的凌乱连接的情况下,当你在看一个小的、简单的组件内部时,你可以很容易的认为事情是更好的。

最后,有团队技能的因素。更熟练的团队倾向于采用新技术。但是对更熟练的团队更有效的一种技术不一定适合于不太熟练的团队。我们已经看到大量的例子,不太熟练的团队构建了凌乱的单体架构,但这需要时间去看当微服务发生这种凌乱时会发生什么。一个差的团队总是创建一个差的系统 - 很难讲在这个例子中微服务会减少这种凌乱还是使它更糟糕。

我们听到的一个合理的说法是,你不应该从微服务架构开始。相反,从单体开始,使它保持模块化,一旦单体成为问题时把它分解成微服务。(虽然这个建议是不理想的,因为一个好的进程内接口通常不是一个好的服务接口。)

所以我们怀着谨慎乐观的态度写了这篇文章。到目前为止,我们已经看到关于微服务风格足以觉得这是一条值得探索的路。我们不能肯定地说,我们将在哪里结束,但软件开发的挑战之一是,你只能基于目前能拿到手的不完善的信息作出决定。

おすすめ

転載: www.cnblogs.com/NetPig/p/10948783.html