1. 程式人生 > >前阿里開發工程師的分享微服務之基於Docker的分散式企業級實踐

前阿里開發工程師的分享微服務之基於Docker的分散式企業級實踐

前言

基於 Docker 的容器技術是在2015年的時候開始接觸的,兩年多的時間,作為一名 Docker 的 DevOps,也見證了 Docker 的技術體系的快速發展。本文主要是結合在公司搭建的微服務架構的實踐過程,做一個簡單的總結。希望給在創業初期探索如何佈局服務架構體系的 DevOps,或者想初步瞭解企業級架構的同學們一些參考。

Microservice 和 Docker

對於創業公司的技術佈局,很多聲音基本上是,創業公司就是要快速上線快速試錯。用單應用或者前後臺應用分離的方式快速整合,快速開發,快速釋出。但其實這種結果造成的隱性成本會更高。當業務發展起來,開發人員多了之後,就會面臨龐大系統的部署效率,開發協同效率問題。然後通過服務的拆分,資料的讀寫分離、分庫分表等方式重新架構,而且這種方式如果要做的徹底,需要花費大量人力物力。

個人建議,DevOps 結合自己對於業務目前以及長期的發展判斷,能夠在專案初期使用微服務架構,多為後人謀福。

隨著 Docker 周圍開源社群的發展,讓微服務架構的概念能有更好的一個落地實施的方案。並且在每一個微服務應用內部,都可以使用 DDD(Domain-Drive Design)的六邊形架構來進行服務內的設計。關於 DDD 的一些概念也可以參考之前寫的幾篇文章:領域驅動設計整理——概念&架構、領域驅動設計整理——實體和值物件設計、領域服務、領域事件。

清晰的微服務的領域劃分,服務內部有架構層次的優雅的實現,服務間通過 RPC 或者事件驅動完成必要的 IPC,使用 API gateway 進行所有微服務的請求轉發,非阻塞的請求結果合併。本文下面會具體介紹,如何在分散式環境下,也可以快速搭建起來具有以上幾點特徵的,微服務架構 with Docker。

服務發現模式

如果使用 Docker 技術來架構微服務體系,服務發現就是一個必然的課題。目前主流的服務發現模式有兩種:客戶端發現模式,以及服務端發現模式。

客戶端發現模式

客戶端發現模式的架構圖如下:

客戶端發現模式的典型實現是Netflix體系技術。客戶端從一個服務註冊服務中心查詢所有可用服務例項。客戶端使用負載均衡演算法從多個可用的服務例項中選擇出一個,然後發出請求。比較典型的一個開源實現就是 Netflix 的 Eureka。

Netflix-Eureka

Eureka 的客戶端是採用自注冊的模式,客戶端需要負責處理服務例項的註冊和登出,傳送心跳。

在使用 SpringBoot 整合一個微服務時,結合 SpringCloud 專案可以很方便得實現自動註冊。在服務啟動類上新增@EnableEurekaClient即可在服務例項啟動時,向配置好的 Eureka 服務端註冊服務,並且定時傳送以心跳。客戶端的負載均衡由 Netflix Ribbon 實現。服務閘道器使用 Netflix Zuul,熔斷器使用 Netflix Hystrix。

除了服務發現的配套框架,SpringCloud 的 Netflix-Feign,提供了宣告式的介面來處理服務的 Rest 請求。當然,除了使用 FeignClient,也可以使用 Spring RestTemplate。專案中如果使用@FeignClient可以使程式碼的可閱讀性更好,Rest API 也一目瞭然。

服務例項的註冊管理、查詢,都是通過應用內呼叫 Eureka 提供的 REST API 介面(當然使用 SpringCloud-Eureka 不需要編寫這部分程式碼)。由於服務註冊、登出是通過客戶端自身發出請求的,所以這種模式的一個主要問題是對於不同的程式語言會註冊不同服務,需要為每種開發語言單獨開發服務發現邏輯。另外,使用 Eureka 時需要顯式配置健康檢查支援。

服務端發現模式

服務端發現模式的架構圖如下:

客戶端向負載均衡器發出請求,負載均衡器向服務登錄檔發出請求,將請求轉發到登錄檔中可用的服務例項。服務例項也是在登錄檔中註冊,登出的。負載均衡可以使用可以使用 Haproxy 或者 Nginx。服務端發現模式目前基於 Docker 的主流方案主要是 Consul、Etcd 以及 Zookeeper。

Consul

Consul 提供了一個 API 允許客戶端註冊和發現服務。其一致性上基於RAFT演算法。通過 WAN 的 Gossip 協議,管理成員和廣播訊息,以完成跨資料中心的同步,且支援 ACL 訪問控制。Consul 還提供了健康檢查機制,支援 kv 儲存服務(Eureka 不支援)。Consul 的一些更詳細的介紹可以參考之前寫的一篇:Docker 容器部署 Consul 叢集。

Etcd

Etcd 都是強一致的(滿足 CAP 的 CP),高可用的。Etcd 也是基於 RAFT 演算法實現強一致性的 KV 資料同步。Kubernetes 中使用 Etcd 的 KV 結構儲存所有物件的生命週期。

關於 Etcd 的一些內部原理可以看下etcd v3原理分析

Zookeeper

ZK 最早應用於 Hadoop,其體系已經非常成熟,常被用於大公司。如果已經有自己的 ZK 叢集,那麼可以考慮用 ZK 來做自己的服務註冊中心。

Zookeeper 同 Etcd 一樣,強一致性,高可用性。一致性演算法是基於 Paxos 的。對於微服務架構的初始階段,沒有必要用比較繁重的 ZK 來做服務發現。

服務註冊 服務登錄檔是服務發現中的一個重要元件。除了 Kubernetes、Marathon 其服務發現是內建的模組之外。服務都是需要註冊到登錄檔上。上文介紹的 Eureka、consul、etcd 以及 ZK 都是服務登錄檔的例子。

微服務如何註冊到登錄檔也是有兩種比較典型的註冊方式:自注冊模式,第三方註冊模式。

自注冊模式 Self-registration pattern

上文中的 Netflix-Eureka 客戶端就是一個典型的自注冊模式的例子。也即每個微服務的例項本身,需要負責註冊以及登出服務。Eureka 還提供了心跳機制,來保證註冊資訊的準確,具體的心跳的傳送間隔時間可以在微服務的 SpringBoot 中進行配置。

如下,就是使用 Eureka 做登錄檔時,在微服務(SpringBoot 應用)啟動時會有一條服務註冊的資訊:

com.netflix.discovery.DiscoveryClient : DiscoveryClientSERVICE-USER/{yourip}:service-user:{port}:cc9f93c54a0820c7a845422f9ecc73fb: registering service… 同樣,在應用停用時,服務例項需要主動登出本例項資訊:

2018-01-04 20:41:37.290 INFO 49244 --- [ Thread-8] c.n.e.EurekaDiscoveryClientConfiguration : Unregistering application service-user with eureka with status DOWN
2018-01-04 20:41:37.340 INFO 49244 --- [ Thread-8] com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...
2018-01-04 20:41:37.381 INFO 49244 --- [ Thread-8] com.netflix.discovery.DiscoveryClient : Unregistering ...
2018-01-04 20:41:37.559 INFO 49244 --- [ Thread-8] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-USER/{your_ip}:service-user:{port}:cc9f93c54a0820c7a845422f9ecc73fb - deregister status: 200

自注冊方式是比較簡單的服務註冊方式,不需要額外的設施或代理,由微服務例項本身來管理服務註冊。但是缺點也很明顯,比如 Eureka 目前只提供了 Java 客戶端,所以不方便多語言的微服務擴充套件。因為需要微服務自己去管理服務註冊邏輯,所以微服務實現也耦合了服務註冊和心跳機制。跨語言性比較差。

第三方註冊模式 Third party registration pattern

第三方註冊,也即服務註冊的管理(註冊、登出服務)通過一個專門的服務管理器(Registar)來負責。Registrator 就是一個開源的服務管理器的實現。Registrator 提供了對於 Etcd 以及 Consul 的登錄檔服務支援。 Registrator 作為一個代理服務,需要部署、執行在微服務所在的伺服器或者虛擬機器中。比較簡單的安裝方式就是通過 Docker,以容器的方式來執行。三方註冊模式的架構圖如下:

通過新增一個服務管理器,微服務例項不再直接向註冊中心註冊,登出。由服務管理器(Registar)通過訂閱服務,跟蹤心跳,來發現可用的服務例項,並向註冊中心(consul、etcd 等)註冊,登出例項,以及傳送心跳。這樣就可以實現服務發現元件和微服務架構的解耦。想學文中的技術可以加入我的群:375989619

Registrator 配合 Consul,以及 Consul Template 搭建服務發現中心,可以參考: Scalable Architecture DR CoN: Docker, Registrator, Consul, Consul Template and Nginx 。此文示例了 Nginx 來做負載均衡,在具體的實施過程中也可以用 Haproxy 或其他方案進行替代。想學文中的技術可以加入我的群:375989619

小結

除了以上幾種做服務發現的技術,Kubernetes 自帶了服務發現模組,負責處理服務例項的註冊和登出。Kubernetes 也在每個叢集節點上執行代理,來實現服務端發現路由器的功能。如果編排技術使用的 k8n,可以用 k8n 的一整套 Docker 微服務方案,對 k8n 感興趣的可以閱讀下Kubernetes 架構設計與核心原理。

在實際的技術選型中,最主要還是要結合業務、系統的未來發展的特徵進行合理判斷。

在 CAP 理論中。Eureka 滿足了 AP,Consul 是 CA,ZK 和 Etcd 是 CP。 在分散式場景下 Eureka 和 Consul 都能保證可用性。而搭建 Eureka 服務會相對更快速,因為不需要搭建額外的高可用服務註冊中心,在小規模伺服器例項時,使用 Eureka 可以節省一定成本。

Eureka、Consul 都提供了可以檢視服務註冊資料的 WebUI 元件。Consul 還提供了 KV 儲存,支援支援 http 和 dns 介面。對於創業公司最開始搭建微服務,比較推薦這兩者。

在多資料中心方面,Consul 自帶資料中心的 WAN 方案。ZK 和 Etcd 均不提供多資料中心功能的支援,需要額外的開發。

跨語言性上,Zookeeper 需要使用其提供的客戶端 api,跨語言支援較弱。Etcd、Eureka 都支援 http,Etcd 還支援 grpc。Consul 除了 http 之外還提供了 DNS 的支援。

安全方面,Consul,Zookeeper 支援 ACL,另外 Consul、Etcd 支援安全通道 Https。

SpringCloud 目前對於 Eureka、Consul、Etcd、ZK 都有相應的支援。

Consul 和 Docker 一樣,都是用 Go 語言實現,基於 Go 語言的微服務應用可以優先考慮用 Consul。

服務間的 IPC 機制

按照微服務的架構體系,解決了服務發現的問題之後。就需要選擇合適的服務間通訊的機制。如果是在 SpringBoot 應用中,使用基於 Http 協議的 REST API 是一種同步的解決方案。而且 Restful 風格的 API 可以使每個微服務應用更加趨於資源化,使用輕量級的協議也是微服務一直提倡的。

如果每個微服務是使用 DDD(Domain-Driven Design)思想的話,那麼需要每個微服務儘量不使用同步的 RPC 機制。非同步的基於訊息的方式比如 AMQP 或者 STOMP,來鬆耦合微服務間的依賴會是很好的選擇。目前基於訊息的點對點的 pub/sub 的框架選擇也比較多。下面具體介紹下兩種 IPC 的一些方案。

同步

對於同步的請求/響應模式的通訊方式。可以選擇基於 Restful 風格的 Http 協議進行服務間通訊,或者跨語言性很好的 Thrift 協議。如果是使用純 Java 語言的微服務,也可以使用 Dubbo。如果是 SpringBoot 整合的微服務架構體系,建議選擇跨語言性好、Spring 社群支援比較好的 RPC。

Dubbo

Dubbo是由阿里巴巴開發的開源的 Java 客戶端的 RPC 框架。Dubbo 基於 TCP 協議的長連線進行資料傳輸。傳輸格式是使用 Hessian 二進位制序列化。服務註冊中心可以通過 Zookeeper 實現。

Apache Thrift

ApacheThrift 是由 Facebook 開發的 RPC 框架。其程式碼生成引擎可以在多種語言中,如 C++、 Java、Python、PHP、Ruby、Erlang、Perl 等建立高效的服務。傳輸資料採用二進位制格式,其資料包要比使用 Json 或者 XML 格式的 HTTP 協議小。高併發,大資料場景下更有優勢。

Rest

Rest 基於 HTTP 協議,HTTP 協議本身具有語義的豐富性。隨著 Springboot 被廣泛使用,越來越多的基於 Restful 風格的 API 流行起來。REST 是基於 HTTP 協議的,並且大多數開發者也是熟知 HTTP 的。

這裡另外提一點,很多公司或者團隊也是使用Springboot的,也在說自己是基於 Restful 風格的。但是事實其實往往是實施得並不到位。對於你的 Restful 是否是真的 Restful,可以參考這篇文章,對於 Restful 風格 API 的成熟度進行了四個層次的分析: Richardson Maturity Model steps toward the glory of REST。

如果使用Springboot的話,無論使用什麼服務發現機制,都可以通過 Spring 的RestTemplate來做基礎的Http請求封裝。

如果使用的前文提到的Netflix-Eureka的話,可以使用Netflix-Feign。Feign是一個宣告式 Web Service 客戶端。客戶端的負載均衡使用 Netflix-Ribbon。

非同步

在微服務架構中,排除純粹的“事件驅動架構”,使用訊息佇列的場景一般是為了進行微服務之間的解耦。服務之間不需要了解是由哪個服務例項來消費或者釋出訊息。只要處理好自己領域範圍的邏輯,然後通過訊息通道來發布,或者訂閱自己關注的訊息就可以。目前開源的訊息佇列技術也很多。比如 Apache Kafka,RabbitMQ,Apache ActiveMQ 以及阿里巴巴的 RocketMQ 目前已經成為 Apache 專案之一。訊息佇列的模型中,主要的三個組成就是:

  • Producer:生產訊息,將訊息寫入 channel。

  • Message Broker:訊息代理,將寫入 channel 的訊息按佇列的結構進行管理。負責儲存/轉發訊息。Broker 一般是需要單獨搭建、配置的叢集,而且必須是高可用的。

  • Consumer:訊息的消費者。目前大多數的訊息佇列都是保證訊息至少被消費一次。所以根據使用的訊息佇列設施不同,消費者要做好冪等。

不同的訊息佇列的實現,訊息模型不同。各個框架的特性也不同:

RabbitMQ

RabbitMQ 是基於 AMQP 協議的開源實現,由以高效能、可伸縮性出名的 Erlang 寫成。目前客戶端支援 Java、.Net/C# 和 Erlang。在 AMQP(Advanced Message Queuing Protocol)的元件中,Broker 中可以包含多個Exchange(交換機)元件。Exchange 可以繫結多個 Queue 以及其他 Exchange。訊息會按照 Exchange 中設定的 Routing 規則,傳送到相應的 Message Queue。在 Consumer 消費了這個訊息之後,會跟 Broker 建立連線。傳送消費訊息的通知。則 Message Queue 才會將這個訊息移除。

Kafka

Kafka 是一個高效能的基於釋出/訂閱的跨語言分散式訊息系統。Kafka 的開發語言為 Scala。其比較重要的特性是:

  • 以時間複雜度為O(1)的方式快速訊息持久化;

  • 高吞吐率;

  • 支援服務間的訊息分割槽,及分散式消費,同時保證訊息順序傳輸;

  • 支援線上水平擴充套件,自帶負載均衡;

  • 支援只消費且僅消費一次(Exactly Once)模式等等。

說個缺點: 管理介面是個比較雞肋了點,可以使用開源的kafka-manager

其高吞吐的特性,除了可以作為微服務之間的訊息佇列,也可以用於日誌收集, 離線分析, 實時分析等。

Kafka 官方提供了 Java 版本的客戶端 API,Kafka 社群目前也支援多種語言,包括 PHP、Python、Go、C/C++、Ruby、NodeJS 等。

ActiveMQ

ActiveMQ 是基於 JMS(Java Messaging Service)實現的 JMSProvider。JMS主要提供了兩種型別的訊息:點對點(Point-to-Point)以及釋出/訂閱(Publish/Subscribe)。目前客戶端支援 Java、C、C++、 C#、Ruby、Perl、Python、PHP。而且 ActiveMQ 支援多種協議:Stomp、AMQP、MQTT 以及 OpenWire。

RocketMQ/ONS

RocketMQ 是由阿里巴巴研發開源的高可用分散式訊息佇列。ONS是提供商業版的高可用叢集。ONS 支援 pull/push。可支援主動推送,百億級別訊息堆積。ONS 支援全域性的順序訊息,以及有友好的管理頁面,可以很好的監控訊息佇列的消費情況,並且支援手動觸發訊息多次重發。

小結

通過上篇的微服務的服務發現機制,加上 Restful API,可以解決微服務間的同步方式的程序間通訊。當然,既然使用了微服務,就希望所有的微服務能有合理的限界上下文(系統邊界)。微服務之間的同步通訊應儘量避免,以防止服務間的領域模型互相侵入。為了避免這種情況,就可以在微服務的架構中使用一層API gateway(會在下文介紹)。所有的微服務通過API gateway進行統一的請求的轉發,合併。並且API gateway也需要支援同步請求,以及NIO的非同步的請求(可以提高請求合併的效率以及效能)。想學文中的技術可以加入我的群:375989619

訊息佇列可以用於微服務間的解耦。在基於Docker的微服務的服務叢集環境下,網路環境會比一般的分散式叢集複雜。選擇一種高可用的分散式訊息佇列實現即可。如果自己搭建諸如Kafka、RabbitMQ叢集環境的話,那對於Broker設施的高可用性會要求很高。基於Springboot的微服務的話,比較推薦使用Kafka 或者ONS。雖然ONS是商用的,但是易於管理以及穩定性高,尤其對於必要場景才依賴於訊息佇列進行通訊的微服務架構來說,會更適合。如果考慮到會存在日誌收集,實時分析等場景,也可以搭建Kafka叢集。目前阿里雲也有了基於Kafka的商用叢集設施。

使用 API Gateway 處理微服務請求轉發、合併

前面主要介紹瞭如何解決微服務的服務發現和通訊問題。在微服務的架構體系中,使用DDD思想劃分服務間的限界上下文的時候,會盡量減少微服務之間的呼叫。為了解耦微服務,便有了基於API Gateway方式的優化方案。

解耦微服務的呼叫

比如,下面一個常見的需求場景——“使用者訂單列表”的一個聚合頁面。需要請求”使用者服務“獲取基礎使用者資訊,以及”訂單服務“獲取訂單資訊,再通過請求“商品服務”獲取訂單列表中的商品圖片、標題等資訊。如下圖所示的場景 :

如果讓客戶端(比如H5、Android、iOS)發出多個請求來解決多個資訊聚合,則會增加客戶端的複雜度。比較合理的方式就是增加API Gateway層。API Gateway跟微服務一樣,也可以部署、執行在Docker容器中,也是一個Springboot應用。如下,通過Gateway API進行轉發後:

所有的請求的資訊,由Gateway進行聚合,Gateway也是進入系統的唯一節點。並且Gateway和所有微服務,以及提供給客戶端的也是Restful風格API。Gateway層的引入可以很好的解決資訊的聚合問題。而且可以更好得適配不同的客戶端的請求,比如H5的頁面不需要展示使用者資訊,而iOS客戶端需要展示使用者資訊,則只需要新增一個Gateway API請求資源即可,微服務層的資源不需要進行變更。

API Gateway 的特點

API gateway除了可以進行請求的合併、轉發。還需要有其他的特點,才能成為一個完整的Gateway。

響應式程式設計

Gateway是所有客戶端請求的入口。類似Facade模式。為了提高請求的效能,最好選擇一套非阻塞I/O的框架。在一些需要請求多個微服務的場景下,對於每個微服務的請求不一定需要同步。前文舉例的“使用者訂單列表”的例子中,獲取使用者資訊,以及獲取訂單列表,就是兩個獨立請求。只有獲取訂單的商品資訊,需要等訂單資訊返回之後,根據訂單的商品id列表再去請求商品微服務。為了減少整個請求的響應時間,需要Gateway能夠併發處理相互獨立的請求。一種解決方案就是採用響應式程式設計。

目前使用Java技術棧的響應式程式設計方式有,Java8的CompletableFuture,以及ReactiveX提供的基於JVM的實現-RxJava。

ReactiveX是一個使用可觀察資料流進行非同步程式設計的程式設計介面,ReactiveX結合了觀察者模式、迭代器模式和函數語言程式設計的精華。除了RxJava還有RxJS,RX.NET等多語言的實現。

對於Gateway來說,RxJava提供的Observable可以很好的解決並行的獨立I/O請求,並且如果微服務專案中使用Java8,團隊成員會對RxJava的函式學習吸收會更快。同樣基於Lambda風格的響應式程式設計,可以使程式碼更加簡潔。關於RxJava的詳細介紹可以可以閱讀RxJava文件和教程。

通過響應式程式設計的Observable模式,可以很簡潔、方便得建立事件流、資料流,以及用簡潔的函式進行資料的組合和轉換,同時可以訂閱任何可觀察的資料流並執行操作。

通過使用RxJava,“使用者訂單列表”的資源請求時序圖:

響應式程式設計可以更好的處理各種執行緒同步、併發請求,通過Observables和Schedulers提供了透明的資料流、事件流的執行緒處理。在敏捷開發模式下,響應式程式設計使程式碼更加簡潔,更好維護。

鑑權

Gateway作為系統的唯一入口,基於微服務的所有鑑權,都可以圍繞Gateway去做。在Springboot工程中,基礎的授權可以使用spring-boot-starter-security以及Spring Security(Spring Security也可以整合在Spring MVC專案中)。

Spring Security主要使用AOP,對資源請求進行攔截,內部維護了一個角色的Filter Chain。因為微服務都是通過Gateway請求的,所以微服務的@Secured可以根據Gateway中不同的資源的角色級別進行設定。

Spring Security提供了基礎的角色的校驗介面規範。但客戶端請求的Token資訊的加密、儲存以及驗證,需要應用自己完成。對於Token加密資訊的儲存可以使用Redis。這裡再多提一點,為了保證一些加密資訊的可變性,最好在一開始設計Token模組的時候就考慮到支援多個版本金鑰,以防止萬一內部金鑰被洩露(之前聽一個朋友說其公司的Token加密程式碼被員工公佈出去)。至於加密演算法,以及具體的實現在此就不再展開。 在Gateway鑑權通過之後,解析後的token資訊可以直接傳遞給需要繼續請求的微服務層。想學文中的技術可以加入我的群:375989619

如果應用需要授權(對資源請求需要管理不同的角色、許可權),也只要在Gateway的Rest API基礎上基於AOP思想來做即可。統一管理鑑權和授權,這也是使用類似Facade模式的Gateway API的好處之一。

負載均衡

API Gateway跟Microservice一樣,作為Springboot應用,提供Rest api。所以同樣執行在Docker容器中。Gateway和微服務之間的服務發現還是可以採用前文所述的客戶端發現模式,或者服務端發現模式。

在叢集環境下,API Gateway 可以暴露統一的埠,其例項會執行在不同IP的伺服器上。因為我們是使用阿里雲的ECS作為容器的基礎設施,所以在叢集環境的負載均衡也是使用阿里雲的負載均衡SLB,域名解析也使用AliyunDNS。下圖是一個簡單的網路請求的示意:

在實踐中,為了不暴露服務的埠和資源地址,也可以在服務叢集中再部署Nginx服務作為反向代理,外部的負載均衡設施比如SLB可以將請求轉發到Nginx伺服器,請求通過Nginx再轉發給Gateway埠。如果是自建機房的叢集,就需要搭建高可用的負載均衡中心。為了應對跨機器請求,最好使用Consul,Consul(Consul Template)+Registor+Haproxy來做服務發現和負載均衡中心。

快取

對於一些高QPS的請求,可以在API Gateway做多級快取。分散式的快取可以使用Redis,Memcached等。如果是一些對實時性要求不高的,變化頻率不高但是高QPS的頁面級請求,也可以在Gateway層做本地快取。而且Gateway可以讓快取方案更靈活和通用。

API Gateway的錯誤處理

在Gateway的具體實現過程中,錯誤處理也是一個很重要的事情。對於Gateway的錯誤處理,可以使用Hystrix來處理請求的熔斷。並且RxJava自帶的onErrorReturn回撥也可以方便得處理錯誤資訊的返回。對於熔斷機制,需要處理以下幾個方面:

服務請求的容錯處理

作為一個合理的Gateway,其應該只負責處理資料流、事件流,而不應該處理業務邏輯。在處理多個微服務的請求時,會出現微服務請求的超時、不可用的情況。在一些特定的場景下, 需要能夠合理得處理部分失敗。比如上例中的“使用者訂單列表”,當“User”微服務出現錯誤時,不應該影響“Order”資料的請求。最好的處理方式就是給當時錯誤的使用者資訊請求返回一個預設的資料,比如顯示一個預設頭像,預設使用者暱稱。然後對於請求正常的訂單,以及商品資訊給與正確的資料返回。如果是一個關鍵的微服務請求異常,比如當“Order”領域的微服務異常時,則應該給客戶端一個錯誤碼,以及合理的錯誤提示資訊。這樣的處理可以儘量在部分系統不可用時提升使用者體驗。使用RxJava時,具體的實現方式就是針對不同的客戶端請求的情況,寫好onErrorReturn,做好錯誤資料相容即可。

異常的捕捉和記錄

Gateway主要是做請求的轉發、合併。為了能清楚得排查問題,定位到具體哪個服務、甚至是哪個Docker容器的問題,需要Gateway能對不同型別的異常、業務錯誤進行捕捉和記錄。如果使用FeignClient來請求微服務資源,可以通過對ErrorDecoder介面的實現,來針對Response結果進行進一步的過濾處理,以及在日誌中記錄下所有請求資訊。如果是使用Spring Rest Template,則可以通過定義一個定製化的RestTempate,並對返回的ResponseEntity進行解析。在返回序列化之後的結果物件之前,對錯誤資訊進行日誌記錄。

超時機制

Gateway執行緒中大多是IO執行緒,為了防止因為某一微服務請求阻塞,導致Gateway過多的等待執行緒,耗盡執行緒池、佇列等系統資源。需要Gateway中提供超時機制,對超時介面能進行優雅的服務降級。

在SpringCloud的Feign專案中集成了Hystrix。Hystrix提供了比較全面的超時處理的熔斷機制。預設情況下,超時機制是開啟的。除了可以配置超時相關的引數,Netflix還提供了基於Hytrix的實時監控Netflix -Dashboard,並且叢集服務只需再附加部署Netflix-Turbine。通用的Hytrix的配置項可以參考Hystrix-Configuration。

如果是使用RxJava的Observable的響應式程式設計,想對不同的請求設定不同的超時時間,可以直接在Observable的timeout()方法的引數進行設定回撥的方法以及超時時間等。

重試機制

對於一些關鍵的業務,在請求超時時,為了保證正確的資料返回,需要Gateway能提供重試機制。如果使用SpringCloudFeign,則其內建的Ribbon,會提供的預設的重試配置,可以通過設定spring.cloud.loadbalancer.retry.enabled=false將其關閉。Ribbon提供的重試機制會在請求超時或者socket read timeout觸發,除了設定重試,也可以定製重試的時間閥值以及重試次數等。

對於除了使用Feign,也使用Spring RestTemplate的應用,可以通過自定義的RestTemplate,對於返回的ResponseEntity物件進行結果解析,如果請求需要重試(比如某個固定格式的error-code的方式識別重試策略),則通過Interceptor進行請求攔截,以及回撥的方式invoke多次請求。想學文中的技術可以加入我的群:375989619

小結

對於微服務的架構,通過一個獨立的API Gateway,可以進行統一的請求轉發、合併以及協議轉換。可以更靈活得適配不同客戶端的請求資料。而且對於不同客戶端(比如H5和iOS的展示資料不同)、不同版本相容的請求,可以很好地在Gateway進行遮蔽,讓微服務更加純粹。微服務只要關注內部的領域服務的設計,事件的處理。

API gateway還可以對微服務的請求進行一定的容錯、服務降級。使用響應式程式設計來實現API gateway可以使執行緒同步、併發的程式碼更簡潔,更易於維護。在對於微服務的請求可以統一通過FeignClint。程式碼也會很有層次。如下圖,是一個示例的請求的類層次。

Clint負責整合服務發現(對於使用Eureka自注冊方式)、負載均衡以及發出請求,並獲取ResponseEntity物件。

Translator將ResponseEntity轉換成Observable物件,以及對異常進行統一日誌採集,類似於DDD中防腐層的概念。

Adapter呼叫各個Translator,使用Observable函式,對請求的資料流進行合併。如果存在多個數據的組裝,可以增加一層Assembler專門處理DTO物件到Model的轉換。

Controller,提供Restful資源的管理,每個Controller只請求唯一的一個Adapter方法。

微服務的持續整合部署

前文主要介紹了微服務的服務發現、服務通訊以及API Gateway。整體的微服務架構的模型初見。在實際的開發、測試以及生產環境中。使用Docker實現微服務,叢集的網路環境會更加複雜。微服務架構本身就意味著需要對若干個容器服務進行治理,每個微服務都應可以獨立部署、擴容、監控。下面會繼續介紹如何進行Docker微服務的持續整合部署(CI/CD)。

映象倉庫

用Docker來部署微服務,需要將微服務打包成Docker映象,就如同部署在Web server打包成war檔案一樣。只不過Docker映象執行在Docker容器中。想學文中的技術可以加入我的群:375989619

如果是Springboot服務,則會直接將包含Apache Tomcat server的Springboot,以及包含Java執行庫的編譯後的Java應用打包成Docker映象。

為了能統一管理打包以及分發(pull/push)映象。企業一般需要建立自己的映象私庫。實現方式也很簡單。可以在伺服器上直接部署Docker hub的映象倉庫的容器版Registry2。目前最新的版本是V2。

程式碼倉庫

程式碼的提交、回滾等管理,也是專案持續整合的一環。一般也是需要建立企業的程式碼倉庫的私庫。可以使用SVN,GIT等程式碼版本管理工具。

目前公司使用的是Gitlab,通過Git的Docker映象安裝、部署操作也很便捷。具體步驟可以參考docker gitlab install。為了能快速構建、打包,也可將Git和Registry部署在同一臺伺服器上。

專案構建

在Springboot專案中,構建工具可以用Maven,或者Gradle。Gradle相比Maven更加靈活,而且Springboot應用本身去配置化的特點,用基於Groovy的Gradle會更加適合,DSL本身也比XML更加簡潔高效。

因為Gradle支援自定義task。所以微服務的Dockerfile寫好之後,就可以用Gradle的task指令碼來進行構建打包成Docker Image。

目前也有一些開源的Gradle構建Docker映象的工具,比如Transmode-Gradlew外掛。其除了可以對子專案(單個微服務)進行構建Docker映象,也可以支援同時上傳映象到遠端映象倉庫。在生產環境中的build機器上,可以通過一個命令直接執行專案的build,Docker Image的打包,以及映象的push。

容器編排技術

Docker映象構建之後,因為每個容器執行著不同的微服務例項,容器之間也是隔離部署服務的。通過編排技術,可以使DevOps輕量化管理容器的部署以及監控,以提高容器管理的效率。

目前一些通用的編排工具比如Ansible、Chef、Puppet,也可以做容器的編排。但他們都不是專門針對容器的編排工具,所以使用時需要自己編寫一些指令碼,結合Docker的命令。比如Ansible,確實可以實現很便利的叢集的容器的部署和管理。目前Ansible針對其團隊自己研發的容器技術提供了整合方案:Ansible Container。

叢集管理系統將主機作為資源池,根據每個容器對資源的需求,決定將容器排程到哪個主機上。

目前,圍繞Docker容器的排程、編排,比較成熟的技術有Google的Kubernetes(下文會簡寫k8s),Mesos結合Marathon管理Docker叢集,以及在Docker 1.12.0版本以上官方提供的Docker Swarm。編排技術是容器技術的重點之一。選擇一個適合自己團隊的容器編排技術也可以使運維更高效、更自動化。

Docker Compose

Docker Compose是一個簡單的Docker容器的編排工具,通過YAML檔案配置需要執行的應用,然後通過compose up命令啟動多個服務對應的容器例項。Docker中沒有整合Compose,需要另外安裝。

Compose可以用於微服務專案的持續整合,但其不適合大型叢集的容器管理,大叢集中,可以Compose結合Ansible做叢集資源管理,以及服務治理。

對於叢集中伺服器不多的情況,可以使用Compose,其使用步驟主要是:

結合微服務執行環境,定義好服務的Dockerfile

根據服務映象、埠、執行變數等編寫docker-compose.yml檔案,以使服務可以一起部署,執行

執行docker-compose up 命令啟動並且進入容器例項,如果需要使用後臺程序方式執行,使用docker-compose up -d即可。

Docker Swarm

在16年,Docker的1.12版本出來之後,使用新版本的Docker,就自帶Docker swarm mode了。不需要額外安裝任何外掛工具。可以看出去年開始Docker團隊也開始重視服務編排技術,通過內建Swarm mode,也要搶佔一部分服務編排市場。

如果團隊開始使用新版本的Docker,可以選擇Docker swarm mode來進行叢集化的容器排程和管理。Swarm還支援滾動更新、節點間傳輸層安全加密、負載均衡等。

DockerSwarm的使用示例可以參考之前寫的一篇:使用docker-swarm搭建持續整合叢集服務。

Kubernetes

Kubernetes是Google開源的容器叢集管理系統,使用Go語言實現,其提供應用部署、維護、 擴充套件機制等功能。目前可以在GCE、vShpere、CoreOS、OpenShift、Azure等平臺使用k8s。國內目前Aliyun也提供了基於k8s的服務治理平臺。如果是基於物理機、虛擬機器搭建的Docker叢集的話,也可以直接部署、執行k8s。在微服務的叢集環境下,Kubernetes可以很方便管理跨機器的微服務容器例項。

目前k8s基本是公認的最強大開源服務治理技術之一。其主要提供以下功能:

  • 自動化對基於Docker對服務例項進行部署和複製

  • 以叢集的方式執行,可以管理跨機器的容器,以及滾動升級、儲存編排。

  • 內建了基於Docker的服務發現和負載均衡模組

K8s提供了強大的自我修復機制,會對崩潰的容器進行替換(對使用者,甚至開發團隊都無感知),並可隨時擴容、縮容。讓容器管理更加彈性化。

k8s主要通過以下幾個重要的元件完成彈性容器叢集的管理的:

  • Pod是Kubernetes的最小的管理元素,一個或多個容器執行在pod中。pod的生命週期很短暫,會隨著排程失敗,節點崩潰,或者其他資源回收時消亡。

  • Label是key/value儲存結構的,可以關聯pod,主要用來標記pod,給服務分組。微服務之間通過label選擇器(Selectors)來識別Pod。

  • Replication Controller是k8s Master節點的核心元件。用來確保任何時候Kubernetes叢集中有指定數量的pod副本(replicas)執行。即提供了自我修復機制的功能,並且對縮容擴容、滾動升級也很有用。

  • Service是對一組Pod的策略的抽象。也是k8s管理的基本元素之一。Service通過Label識別一組Pod。建立時也會建立一個本地叢集的DNS(儲存Service對應的Pod的服務地址)。所以在客戶端請求通過請求DNS來獲取一組當前可用的Pods的ip地址。之後通過每個Node中執行的kube-proxy將請求轉發給其中一個Pod。這層負載均衡是透明的,但是目前的k8s的負載均衡策略還不是很完善,預設是隨機的方式。

小結

微服務架構體系中,一個合適的持續整合的工具,可以很好得提升團隊的運維、開發效率。目前類似Jenkins也有針對Docker的持續整合的外掛,但是還是存在很多不完善。所以建議還是選擇專門應對Docker容器編排技術的Swarm,k8s,Mesos。或者多個技術結合起來,比如Jenkins做CI+k8s做CD。

Swarm,k8s,Mesos各有各的特性,他們對於容器的持續部署、管理以及監控都提供了支援。Mesos還支援資料中心的管理。Docker swarm mode擴充套件了現有的Docker API,通過Docker Remote API的呼叫和擴充套件,可以排程容器執行到指定的節點。Kubernetes則是目前市場規模最大的編排技術,目前很多大公司也都加入到了k8s家族,k8s應對叢集應用的擴充套件、維護和管理更加靈活,但是負載均衡策略比較粗糙。而Mesos更專注於通用排程,提供了多種排程器。想學文中的技術可以加入我的群:619881427

對於服務編排,還是要選擇最適合自己團隊的,如果初期機器數量很少,叢集環境不復雜也可以用Ansible+Docker Compose,再加上Gitlab CI來做持續整合。

服務叢集的解決方案

企業在實踐使用Docker部署、執行微服務應用的時候,無論是一開始就佈局微服務架構,或者從傳統的單應用架構進行微服務化遷移。都需要能夠處理複雜的叢集中的服務排程、編排、監控等問題。下面主要為介紹在分散式的服務叢集下,如何更安全、高效得使用Docker,以及在架構設計上,需要考慮的方方面面。

負載均衡

這裡說的是叢集中的負載均衡,如果是純服務端API的話就是指Gateway API的負載均衡,如果使用了Nginx的話,則是指Nginx的負載均衡。我們目前使用的是阿里雲的負載均衡服務SLB。其中一個主要原因是可以跟DNS域名服務進行繫結。對於剛開始進行創業的公司來說,可以通過Web介面來設定負載均衡的權重,比較便於部分發布、測試驗證,以及健康檢查監控等等。從效率和節約運維成本上來說都是個比較適合的選擇。

如果自己搭建七層負載均衡如使用Nginx或Haproxy的話,也需要保證負責負載均衡的叢集也是高可用的,以及提供便捷的叢集監控,藍綠部署等功能。

持久化及快取

1、關係型資料庫(RDBMS)

對於微服務來說,使用的儲存技術主要是根據企業的需要。為了節約成本的話,一般都是選用Mysql,在Mysql的引擎選擇的話建議選擇InnoDB引擎(5.5版本之前預設MyISAM)。InnoDB在處理併發時更高效,其查詢效能的差距也可以通過快取、搜尋等方案進行彌補。InnoDB處理資料拷貝、備份的免費方案有binlog,mysqldump。不過要做到自動化的備份恢復、可監控的資料中心還是需要DBA或者運維團隊。相對花費的成本也較高。如果初創企業,也可以考慮依託一些國內外比較大型的雲端計算平臺提供的PaaS服務。

微服務一般按照業務領域進行邊界劃分,所以微服務最好是一開始就進行分庫設計。是否需要進行分表需要根據每個微服務具體的業務領域的發展以及資料規模進行具體分析。但建議對於比較核心的領域的模型,比如“訂單”提前做好分表字段的設計和預留。

2、KV模型資料庫(Key-Value-stores)

Redis是開源的Key-Value結構的資料庫。其基於記憶體,具有高效快取的效能,同時也支援持久化。Redis主要有兩種持久化方式。一種是RDB,通過指定時間間隔生成資料集的時間點快照,從記憶體寫入磁碟進行持久化。RDB方式會引起一定程度的資料丟失,但效能好。另外一種是AOF,其寫入機制,有點類似InnoDB的binlog,AOF的檔案的命令都是以Redis協議格式儲存。這兩種持久化是可以同時存在的,在Redis重啟時,AOF檔案會被優先用於恢復資料。因為持久化是可選項,所以也可以禁用Redis持久化。

在實際的場景中,建議保留持久化。比如目前比較流行的解決簡訊驗證碼的驗證,就可使用Redis。在微服務架構體系中,也可以用Redis處理一些KV資料結構的場景。輕量級的資料儲存方案,也很適合本身強調輕量級方案的微服務思想。

我們在實踐中,是對Redis進行了快取、持久化,兩個功能特徵進行分庫的。

在整合Springboot專案中會使用到spring-boot-starter-data-redis來進行Redis的資料庫連線以及基礎配置、以及spring-data-redis提供的豐富的資料APIOperations。

另外,如果是要求高吞吐量的應用,可以考慮用Memcached來專門做簡單的KV資料結構的快取。其比較適合大資料量的讀取,但支援的資料結構型別比較單一。

3、圖形資料庫(Graph Database)

涉及到社交相關的模型資料的儲存,圖形資料庫是一種相交關係型資料庫更高效、更靈活的選擇。圖形資料庫也是Nosql的一種。其和KV不同,儲存的資料主要是資料節點(node),具有指向性的關係(Relationship)以及節點和關係上的屬性(Property)。

如果用Java作為微服務的主開發語言,最好選擇Neo4j。Neo4j是一種基於Java實現的支援ACID的圖形資料庫。其提供了豐富的JavaAPI。在效能方面,圖形資料庫的區域性性使遍歷的速度非常快,尤其是大規模深度遍歷。這個是關係型資料庫的多表關聯無法企及的。

下圖是使用Neo4j的WebUI工具展示的一個官方Getting started資料模型示例。示例中的語句MATCH p=()-[r:DIRECTED]->() RETURN p LIMIT 25是Neo4j提供的查詢語言——Cypher。

在專案使用時可以整合SpringData的專案Spring Data Neo4j。以及SpringBootStartersspring-boot-starter-data-neo4j

4、文件資料庫(Document database)

目前應用的比較廣泛的開源的面向文件的資料庫可以用Mongodb。Mongo具有高可用、高可伸縮性以及靈活的資料結構儲存,尤其是對於Json資料結構的儲存。比較適合部落格、評論等模型的儲存。

搜尋技術

在開發的過程中,有時候經常會看到有人寫了很長很繞、很難維護的多表查詢SQL,或者是各種多表關聯的子查詢語句。對於某一領域模型,當這種場景多的時候,就該考慮接入一套搜尋方案了。不要什麼都用SQL去解決,尤其是查詢的場景。慢查詢語句的問題有時候甚至會拖垮DB,如果DB的監控體系做的不到位,可能問題也很難排查。

Elasticsearch是一個基於Apache Lucene實現的開源的實時分散式搜尋和分析引擎。Springboot的專案也提供了整合方式: spring-boot-starter-data-elasticsearch以及spring-data-elasticsearch。

對於搜尋叢集的搭建,可以使用Docker。具體搭建方法可以參考用Docker搭建Elasticsearch叢集,對於Springboot專案的整合可以參考在Springboot微服務中整合搜尋服務。至今,最新版本的SpringDataElasticsearch已經支援到了5.x版本的ES,可以解決很多2.x版本的痛點了。

如果是小規模的搜尋叢集,可以用三臺低配置的機器,然後用ES的Docker進項進行搭建。也可以使用一些商業版的PaaS服務。如何選擇還是要根據團隊和業務的規模、場景來看。

目前除了ES,使用比較廣泛的開源搜尋引擎還有Solr,Solr也基於Lucene,且專注在文字搜尋。而ES的文字搜尋確實不如Solr,ES主要專注於對分散式的支援,並且內建了服務發現元件Zen來維護叢集狀態,相對Solr(需要藉助類似Zookeeper實現分散式)部署也更加輕量級。ES除了分析查詢,還可以整合日誌收集以及做分析處理。

訊息佇列

訊息佇列如前篇所述,可以作為很好的微服務解耦通訊方式。在分散式叢集的場景下,對於分散式下的最終一致性也可以提供技術基礎保障。並且訊息佇列也可以用來處理流量削鋒。

訊息佇列的對比在此不再贅述。目前公司使用的是阿里雲的ONS。因為使用訊息佇列還是考慮用在對高可用以及易於管理、監控上的要求,所以選擇了安全可靠的訊息佇列平臺。

安全技術

安全性是做架構需要考慮的基礎。網際網路的環境複雜,保護好服務的安全,也是對使用者的基本承諾。安全技術涉及到的範圍比較廣,本文選幾個常見問題以及常用方式來簡單介紹下。

服務例項安全

分散式叢集本身就是對於服務例項安全的一種保障。一臺伺服器或者某一個服務例項出現問題的時候,負載均衡可以將請求轉發到其他可用的服務例項。但很多企業是自建機房,而且是單機房的,這種佈局其實比較危險。因為伺服器的備份容災也得不到完整的保障。最怕的就是資料庫也是在同一機房,主備全都在一起。不單是安全性得不到很高的保障,平常的運維花銷也會比較大。而且需要注意配置防火牆安全策略。

如果可以,儘量使用一些高可用、高可伸縮的穩定性IaaS平臺。

網路安全

1、預防網路攻擊

目前主要的網路攻擊有一下幾種:

  • SQL注入:根據不同的持久層框架,應對策略不同。如果使用JPA,則只要遵循JPA的規範,基本不用擔心。

  • XSS攻擊:做好引數的轉義處理和校驗。具體參考XSS預防

  • CSRF攻擊:做好Http的Header資訊的Token、Refer驗證。具體參考CSRF預防

  • DDOS攻擊:大流量的DDoS攻擊,一般是採用高防IP。也可以接入一些雲端計算平臺的高防IP。

以上只是列舉了幾種常見的攻擊,想要深入瞭解的可以多看看REST安全防範表。在網路安全領域,一般很容易被初創企業忽視,如果沒有一個運維安全團隊,最好使用類似阿里雲-雲盾之類的產品。省心省成本。

2、使用安全協議

這個不用多說,無論是對於使用Restful API的微服務通訊,還是使用的CDN或者使用的DNS服務。涉及到Http協議的,建議都統一使用Https。無論是什麼規模的應用,都要防範流量劫持,否則將會給使用者帶來很不好的使用體驗。

3、鑑權

關於微服務的鑑權前面API Gateway已經有介紹。除了微服務本身之外,我們使用的一些如Mysql,Redis,Elasticsearch,Eureka等服務,也需要設定好鑑權,並且儘量通過內網訪問。不要對外暴露過多的埠。對於微服務的API Gateway,除了鑑權,最好前端通過Nginx反向代理來請求API層。

日誌採集、監控

基於容器技術的微服務的監控體系面臨著更復雜的網路、服務環境。日誌採集、監控如何能對微服務減少侵入性、對開發者更透明,一直是很多微服務的DevOps在不斷思考和實踐的。

1、微服務日誌的採集

微服務的API層的監控,需要從API Gateway到每個微服務的呼叫路徑的跟蹤,採集以及分析。使用Rest API的話,為了對所有請求進行採集,可以使用Spring Web的OncePerRequestFilter對所有請求進行攔截,在採集日誌的時候,也最好對請求的rt進行記錄。

除了記錄access,request等資訊,還需要對API呼叫進行請求跟蹤。如果單純記錄每個服務以及Gateway的日誌,那麼當Gateway Log出現異常的時候,就不知道其具體是微服務的哪個容器例項出現了問題。如果容器達到一定數量,也不可能排查所有容器以及服務例項的日誌。比較簡單的解決方式就是對log資訊都append一段含有容器資訊的、唯一可標識的Trace串。

日誌採集之後,還需要對其進行分析。如果使用E.L.K的技術體系,就可以靈活運用Elasticsearch的實時分散式特性。Logstash可以進行日誌進行收集、分析,並將資料同步到Elasticsearch。Kibana結合Logstash和ElasticSearch,提供良好的便於日誌分析的WebUI,增強日誌資料的視覺化管理。

對於資料量大的日誌的採集,為了提升採集效能,需要使用上文提到的訊息佇列。優化後的架構如下:

2、基礎服務的呼叫日誌採集

通過對微服務的所有Rest API的日誌採集、分析可以監控請求資訊。

在服務內部,對於中介軟體、基礎設施(包括Redis,Mysql,Elasticsearch等)呼叫的效能的日誌採集和分析也是必要的。

對於中介軟體服務的日誌採集,我們目前可以通過動態代理的方式,對於服務呼叫的如cache、repository(包括搜尋和DB)的基礎方法,進行攔截及回撥日誌記錄方法。具體的實現方式可以採用位元組碼生成框架ASM,關於方法的邏輯注入,可以參考之前寫的一篇ASM(四) 利用Method 元件動態注入方法邏輯,如果覺得ASM程式碼不太好維護,也可以使用相對API友好的Cglib。

架構五要素

最後,結合架構核心的五要素來回顧下我們在搭建Docker微服務架構使用的技術體系:

1、高效能

訊息佇列、RxJava非同步併發、分散式快取、本地快取、Http的Etag快取、使用Elasticsearch優化查詢、CDN等等。

2、可用性

容器服務叢集、RxJava的熔斷處理、服務降級、訊息的冪等處理、超時機制、重試機制、分散式最終一致性等等。

3、伸縮性

伺服器叢集的伸縮、容器編排Kubernetes、資料庫分庫分表、Nosql的線性伸縮、搜尋叢集的可伸縮等等。

4、擴充套件性

基於Docker的微服務本身就是為了擴充套件性而生!

5、安全性

JPA/Hibernate,SpringSecurity、高防IP、日誌監控、Https、Nginx反向代理、HTTP/2.0等等。

小結 對於服務叢集的解決方案,其實無論是微服務架構或者SOA架構,都是比較通用的。只是對於一些中介軟體叢集的搭建,可以使用Docker。一句Docker ps就可以很方便查詢執行的服務資訊,並且升級基礎服務也很方便。

對於優秀的叢集架構設計的追求是永無止境的。在跟很多創業公司的技術朋友們接觸下來,大家都是比較偏向於快速搭建以及開發、釋出服務。然而一方面也顧慮微服務的架構會比較複雜,殺雞用牛刀。但是微服務本身就是一種敏捷模式的優秀實踐。這些朋友往往會在業務飛速發展的時候面臨一個困擾,就是服務拆分,資料庫的分庫分表、通過訊息去解耦像麵條一樣的同步程式碼,想要優化效能但是無從下手的尷尬。

相關文件

Apache Thrift

使用Mesos和Marathon管理Docker叢集

基於docker-swarm搭建持續整合叢集服務

Kubernetes中文文件

後記

本文主要是對於Docker的微服務實踐進行技術方案選型以及介紹。不同的業務、團隊可能會適合不通過的架構體系和技術方案。

作為架構師應該結合公司近期、長期的戰略規劃,進行長遠的佈局。最起碼基礎的架構也是需要能支撐3年發展,期間可以不斷引入新的技術並進行服務升級和持續的程式碼層重構。

也許一個架構師從0開始搭建一整套體系並不需要花費多久時間,最需要其進行的就是不斷在團隊推行Domain-Driven Design。並且使團隊一起遵循Clean Code,進行敏捷開發OvO。 微服務架構知識點總結: 

在網際網路公司面試中,架構的底層一定是面試官會問問的問題,針對面試官一般會提到的問題,我錄製了一些分散式,微服務,效能優化等技術點底層原理的錄影視訊,加群375989619可以免費獲取這些錄影,裡面還有些分散式,微服務,效能優化,春天設計時,MyBatis的等原始碼知識點的錄影視訊。這些視訊都是 找一些資深架構師朋友一起錄製出來的,這些視訊幫助以下幾類程式設計師:

1.對現在的薪資不滿,想要跳槽,卻對自己的技術沒有信心,不知道如何面對面試官。

2.想從傳統行業轉行到網際網路行業,但沒有接觸過網際網路技術。

3.工作1 - 5年需要提升自己的核心競爭力,但學習沒有系統化,不知道自己接下來要學什麼才是正確的,踩坑後又不知道找誰,百度後依然不知所以然。

4.工作5 - 10年無法突破技術瓶頸(運用過很多技術,在公司一直寫著業務程式碼,卻依然不懂底層實現原理)

如果你現在正處於我上述所說的幾個階段可以加下我的群來學習。而且我也能夠提供一些面試指導,職業規劃等建議。