俯瞰 Java 服務端開發

原文首發於 github ,歡迎 star 。

Java 服務端開發是一個非常寬廣的領域,要概括其全貌,即使是幾本書也講不完,該文將會提到許多的技術及工具,但不會深入去講解,旨在以一個俯瞰的視角去探尋這片領域。

目錄

框架

Spring Boot

Spring 框架已經成為 Java 服務端開發領域裡的標配,無數的服務基於其開發,它整合了服務端開發所需的絕大多數組件,Spring Boot 在其基礎上又做了一層輕封裝並簡化了依賴管理,使得它用起來更加的便捷。

Vert.x

Spring 框架早已成為主流,但是我們也不能忽略了其他優秀框架的存在。

Vert.x 是在 JVM 基礎上構建響應式應用的一套工具集,支援多種語言,它不僅是一套工具集,也可視作是一套框架,其中包含使用 Netty 編寫的 Web 框架、gprc、redis 客戶端等眾多組件,囊括了大部分開發網路應用時所需用到的組件,它最重要的核心概念是使用了事件驅動的非阻塞模型,因此具備高度的可伸縮性。它使用了響應式的編程模型,這個話題在下文中會再提到。

網路

五層協議

學習電腦網路時一般採用折中的辦法,也就是中和 OSI 和 TCP/IP 的優點,採用一種只有五層協議的體系結構,即物理層、數據鏈路層、網路層、運輸層、應用層,每一層都有其各自的術語,比如:吞吐量、子網掩碼、VIP、DNS等等,這在平時工作的溝通過程中也是至關重要。要做好服務端編程,我們必須對網路的一些基本概念有一個清晰的認識,推薦閱讀《電腦網路:自頂向下方法》。

推薦閱讀:

HTTP 協議

對於服務端編程而言,在網路這個部分最重要的還是 HTTP 協議,從 TCP、DNS ,最後到瀏覽器響應,我們必須清楚整個過程是如何運轉的,中間再加入 CDN、反向代理、流量控制等服務時,其會更加複雜,但也正因為網路的分層模型,使得我們可以在這個中間過程中對服務端的響應性能做出優化。

具體到 HTTP 協議,其承載於 TCP 協議之上,中間再加上 TSL 或 SSL,就成了 HTTPS ,協議頭如何解析,響應體如何發送,搞清楚了這些,可以很容易地開發一個簡單的 HTTP 服務。HTTP 協議也在不斷改進,目前已經到了 2.0 版本,在傳輸性能上有大幅的提升。

HTTP 使用明文傳輸,因此很容易受到中間人攻擊,可以在路由器、代理等多個層面截獲傳輸資訊,因此 HTTP 終將退出歷史舞台,HTTPS 必然成為主流,但是 HTTPS 也並非絕對安全,由於證書籤發機構存在安全漏洞,曾導致許多網站使用了不安全的 SSL 證書,因此很多應用會採用自定義的加密方式來加強資訊傳輸的安全性。

TCP 擁塞控制

TCP 使用多種擁塞控制策略來避免發送方至接收方之間的鏈路變得擁塞,其有許多具體的實現演算法,具體的實現細節隱藏在作業系統的內核當中,通過使用不同的演算法,可以在不同的場景下獲得最佳的性能,例如 Google 設計並發布的 BBR(Bottleneck Bandwidth and Round-trip propagation time)擁塞演算法,它能更有效地利用網路環境,尤其在超遠距離的網路傳輸中能獲得更大的性能提升,目前已經移植到 linux 內核4.9版本。

由於許多網路層相關的演算法都隱藏在作業系統內核當中,普通電腦用戶一般無需理解這些概念,但是對於服務端開發者來說,若對其有一定的了解,則能夠從這一層面尋找解決方案來提升系統的吞吐量。

網路 I/O 模型

常見 I/O 模型主要有 BIO(阻塞I/O),NIO(非阻塞I/O),I/O復用、事件(訊號)驅動I/O、AIO(非同步I/O)。以讀取數據為例,傳統的 BIO 裡面調用 socket 的 read 方法,函數在收到數據前會一直阻塞,對於 NIO,如果有數據則返回,反之返回 0,不會發生阻塞,而 AIO 則更進一步,不光等待數據就緒是非阻塞,連數據從網卡到記憶體的過程也是非同步的。

結合使用 NIO、AIO、I/O復用,可以解決執行緒瓶頸並處理海量連接,比如 nginx 使用了 AIO 模型,因此性能比 apache http server 性能更好。在 Java 領域,Netty 基於 Reactor 模式實現了一個非同步事件驅動的 NIO 框架,其已經運用在互聯網的許多領域,大到大數據、通訊行業、遊戲行業,小到 redis 客戶端、Web 框架等開源組件都有其身影。

資料庫

關係型資料庫

MySQL 是最流行的開源資料庫,PostgreSQL 是最高級的開源資料庫,SQL Server 是微軟開發的企業級資料庫,還有在大型公司用的較多的 Oracle 資料庫。在服務端開發方面,MySQL 的市場佔用率是最高的,但也推薦學習一下 PostgreSQL 和所謂的「企業級資料庫」,畢竟 MySQL 在這些資料庫面前有時確實顯得功能簡單、實用性不足。

在真實的工作中,資料庫的設計是一個非常需要平衡取捨的過程,有時為了優化查詢性能不得不做一些數據冗餘,而在數據量極大的情況下,又必須謹慎選擇每一列的存儲類型、避免冗餘。

數據量非常大的情況下,大多數時候還要進行分庫分表的設計。

  • ShardingSphere
    • 目前 Java 中主流的分庫分表中間件,支援客戶端架構、代理架構,Sidecar 架構目前還在開發中。
  • Vitess
    • Vitess 是 Youtube 開源的 MySQL 資料庫集群系統,採用的是中心化的資料庫代理架構,這套數據集群承載了 Youtube 數以億計的數據量和訪問請求。

存儲引擎

MySQL 中主流使用的是 InnoDB 存儲引擎,內部採用了 B+ 樹的索引結構,Percona XtraDB 是InnoDB 存儲引擎的增強版,Percona 兼容 MySQL,號稱擁有更好的性能,也具有一定的市場佔有率。

除了 InnoDB 及其衍生引擎,RocksDB 也是一個可選項,這是一個 LSM 存儲引擎,不同於傳統的基於 B+ 樹的存儲引擎,基於 LSM 存儲引擎的資料庫尤其適合寫多讀少的場景,由於最初是設計用來做持久化的鍵值數據存儲,因此在 KV 存儲上具有非常高的性能,可惜的是 MySQL 無法選擇 RocksDB 作為存儲引擎,目前支援的資料庫有 MariaDB 和 Percona。

NewSQL

NewSQL 這一新興領域也大量使用了 RocksDB 作為存儲引擎,TiDB 作為流行度較高的 NewSQL 產品,就是用其實現的數據持久化。

NoSQL 資料庫

  • MongoDB
    • MongoDB 介於關係資料庫和非關係資料庫之間,不要求數據存儲具有固定的模式,且能用於存儲超大規模的數據集。

時序資料庫

隨著互聯網的深入,應用場景越來越豐富,諸如系統運行狀態、系統指標採集等場景產生大量的數據,這類基於時間的一系列數據,以寫多讀少、數據量極大為特點,傳統的資料庫已經不適合存儲這類數據,時序資料庫由此誕生。

主流的時序資料庫有:

  • influxdb
  • Prometheus
  • graphite

列式資料庫

傳統的關係型資料庫採用行式存儲,大數據領域多採用列式存儲,列式存儲的主要優勢在於可以按需所取,在並行處理和數據壓縮上更有優勢。關係型資料庫適合 OLTP, 列式資料庫更適合 OLAP,為了使列式資料庫能更好地支援 OLTP,目前出現了像 kudu 和 Druid 這類優秀的開源產品,它們結合了列式存儲的優勢,並在 OLTP 方面也做了特別的優化。

主流的列式資料庫有:

  • HBase
  • Cassandra
  • kudu
  • Druid

嵌入式資料庫

傳統的關係型資料庫能夠支援企業級的應用,但在許多場景下,我們可能只需要一個小型應用,這個時候使用嵌入式資料庫是一個方便的選擇,除此之外,嵌入式資料庫非常適合用於做單元測試。

Java 中流行的嵌入式資料庫有:

  • h2base
  • moby

中間件

Web Server

  • Nginx
    • Nginx 使用 AIO 的模型實現高並發,Apache 每個請求獨佔一個執行緒。
    • AIO 模型適合於 IO 密集型服務,多進程或執行緒適合於 CPU 密集型服務,由於大多數 Web 服務都屬於 IO 密集型,nginx 的市場佔有率逐漸超過了 Apache。由於這一特點,Nginx 也非常適合做反向代理,通過這種機製做負載均衡也是非常主流的一種方案。
  • tomcat、jetty、weblogic 等傳統 Java Web 伺服器
    • 隨著容器化技術的流行,這類伺服器日漸式微,市場佔有率逐漸下降,進行容器化部署時tomcat一般內置在程式中,這種進步使得開發者可以更關注業務程式碼本身,而無需關注此類伺服器的種種細節,可謂是對開發人員的減負。
  • OpenResty
    • 優秀的開源產品經常出現許多優秀的衍生產品,比如 Percona 之於 MySQL,OpenResty 之於 Nginx,Kong 之於 OpenResty。
    • Nginx 市場佔有率之高,但許多場景下是用其做反向代理,OpenResty 的設計目標則是讓 Web 服務直接跑在 Nginx 服務內部。
    • OpenResty 同時也是基於 LuaJIT 的 Web 平台,開發者可以很方便地使用 Lua 調用 Nignx 模組,具有強大的可擴展性,比如可將典型的 Nginx + Tomcat + MySQL 架構更換為 Nginx + Lua + Redis + Tomcat + MySQL 的架構。
    • Kong 從技術上講也屬於 Web Server,但一般用來做 API 網關,下文中再詳述。

分散式快取

  • Redis
    • Redis 作為一個高性能的記憶體資料庫,目前已被廣泛使用,其支援多種數據結構,根據不同場景使用不同的數據結構,才能最有效地使用它。

KV 存儲

  • Pika
    • Redis 的性能非常高,但在將其做資料庫使用時存在數據持久化的問題,Pika 就是為了解決這一問題而出現,它底層基於 RocksDB,修改了其部分源程式碼,在 KV 數據持久化上有非常高的性能,與基於記憶體的 redis 相比僅有較小的性能下降,同時它還兼容大部分的 redis 協議,與 Redis 的使用幾乎沒有差異,上手簡單。
  • Tair
    • Tair 與 Pika 類似,底層支援多種存儲引擎,包括 mdb、rdb、ldb,其中 ldb 基於 leveldb(google開源,rocksdb 在其基礎上優化),它可將記憶體存儲和持久化相結合,具有高可用的分散式架構,目前開源版本已經不再維護,阿里雲上則提供了企業級的 Tair 存儲服務。
  • SSDB
    • SSDB 也是兼容 Redis 的一款 KV 資料庫,目前更新頻率較低,相比而言 Pika 目前還在更新中,且有企業進行背書。

消息隊列

消息隊列在請求削峰、跨系統間通訊解耦、發布訂閱等許多場景下都會使用到,不光能解決這些問題,採用消息驅動的架構可以增強系統的擴展性,比如新增一個訂閱方,即可以實現新的功能,並且對當前的系統沒有任何的侵入性。

常用的消息隊列產品有 kafka、rabbitmq 等,它們各有優缺點,在大數據領域 kafka 佔有絕對優勢,總體的市場佔有率也較高,而 rabbitmq 由於產品成熟,也被廣泛使用。

在使用消息隊列的過程中,需要處理一系列的細節,比如:定義消息處理者、如何發送消息、如何發布事件、消息如何序列化、如何記錄消息記錄、設計消息路由、消息處理失敗的重試機制、消息 id 等等,在具體的編碼過程中不能完全專註於業務程式碼開發,因此市面上有一些 ESB 產品在內部處理好了這些細節,並從更高的抽象層級提供更加簡潔的 API,在開發過程中則能更加聚焦在業務邏輯本身,當我們的系統面臨這些問題的時候,不妨選擇一個 ESB 產品來提升研發效率。

定時調度

簡單的定時任務可以採用 linux cron 進行配置,複雜的場景也可以使用分散式任務調度框架,可選的實現方式非常多,這裡簡單的列舉幾種。

  • Quartz
    • 老牌任務調度系統,許多分散式任務調度框架基於它而擴展。
  • Spring Scheduler
    • 用它來做簡單的任務調度非常方便,但要注意由於現在的系統大多採用分散式部署,因此當使用它來做任務調度時最好做到單獨的服務中,避免與其他系統耦合。
  • 國產分散式任務調度系統
    • 目前較為流行的有 Elastic-Job、XXL-JOB,Elastic-Job 採用去中心化的架構,依賴 zookeeper 存儲任務調度數據,XXL-JOB 採用中心化調度的架構,調度採用 RPC 方式。
    • PowerJob 是新興的一個開源任務調度系統,在功能上更為強大,支援 MapReduce 分片,值得關注。

RPC

提到 RPC 不得不提到日暮西山的 Web Service,其採用 XML 作為消息格式,並以 SOAP 協議進行封裝,由於過於複雜且性能開銷較大,其逐漸被採用 JSON 格式的 REST 服務所取代,相比之下,REST 簡單且採用更高效的序列化方式,所以目前許多系統廣泛採用 HTTP 的方式進行遠程過程調用。

在對於性能要求特別高的場景,或從整體架構上考慮,人們才會選用專門的 RPC 產品,這類系統一般擁有更高效的通訊協議和數據傳輸格式,典型的有 dubbo、grpc、thrift,其中 grpc 具有最優秀的性能。

RPC 框架的原理其實與 HTTP 調用類似,只是採用了更精簡的協議頭和數據序列化方式,此外在服務註冊發現及負載均衡上也做了專門的封裝。在 Spring Cloud 中,使用 OpenFeign 進行服務間調用是非常方便的一個選擇,其使用 HTTP 方式,當性能無法滿足時,可考慮替換序列化方式,或選用 grpc 進行通訊。

資料庫中間件

資料庫本身就是一個龐大的產品,除了前面提到的 ShardingSphere、Vitess 這類中間件,還有一類專門做數據處理的中間件。

  • otter
    • 分散式資料庫同步系統,支援 MySQL、Oracle。
  • canal
    • 基於 MySQL 資料庫增量日誌解析,提供增量數據訂閱和消費。
  • DataX-Web
    • 分散式數據同步工具,可用來簡化 ETL 工作。
  • gh-ost
    • 對數據表結構進行架構變更時,可能導致表被鎖住,如果數據量特別大,這種問題對於線上發布的影響是比較大的,可以採用建新表並遷移數據再修改表名的方式手工處理,這種方式容易出錯且耗時,Github 開源的 MySQL 在線架構遷移工具則是程式化完成這一類操作的很好的選擇。

日誌系統

  • ELK
    • 日誌系統一般採用 ELK 技術棧,這其中包含三個子系統,因此要擴展一個新功能,可以有多種方式切入,比如做監控報警,可以使用 logstash 將 metrics 寫入到 Prometheus,也可以使用 kibana 上的 sentinl 插件或者 ElastAlert 插件。
    • logstash 支援從許多管道收集數據,其中包括 kafka,在日誌量特別大的情況下,可以將日誌先發送至 kafka。
  • Sentry
    • 日誌在很大一部分場景下都是用於排查錯誤的,除了 ELK 外還有專註於應用程式錯誤報告的系統,比如 Sentry。

配置中心

由於越來越多的系統基於 docker 部署,配置中心不僅可以簡化系統的配置管理,也可簡化系統的發布流程,目前較為流行的開源配置中心是 Apollo。另外也可以通過 zookeeper、Consul 等工具來實現統一配置管理。

Nacos 是阿里開源的一款集配置中心和註冊中心於一體的系統,使用它來做配置中心也較為方便,服務端部署相比 Apollo 簡化了許多。

微服務

由於單體應用牽一髮而動全身的特點,許多大型應用在開發時都會自覺拆分為多個子系統,這是在微服務概念提出前就被廣泛採用的方式,而微服務概念的提出則更進一步,提出了一種全新的系統開發方式,使系統可以方便地拆分到更小的粒度,即微型服務,那麼在服務數量越來越多的情況下,服務治理、熔斷降級、鏈路追蹤等問題也浮出水面,於是解決這些問題的 Spring Cloud 框架冉冉升起。

服務註冊與發現

主流的服務註冊與發現組件有:Eureka、Consul、Nacos 等等,它們採用不同的 CAP 分散式一致性規則或多種都支援,但不管使用哪一種,其實還是存在服務失聯的問題,比如在滾動更新的過程中,註冊中心未能及時剔除掉服務,導致調用方仍在調用停止的服務,首先我們可以通過調整配置減少更新周期,必要時需要修改其源程式碼,使用長連接,只要連接中斷即從註冊中心剔除服務,具體的細節需要專門寫一篇文章來講解。

在可能的情況下,盡量使用消息機制來進行服務間通訊,這是一個更好的選擇,除了更好地進行解耦,在滾動更新這個部分也能更好地保持系統不間斷運轉。

熔斷與降級

服務間的調用過多,一定程度上增加了系統的耦合度,當其他微服務出問題或響應較慢時,整個系統都受影響,在必要時需要對出問題的服務進行熔斷或降級。

  • Hystrix
    • Spring Cloud 框架默認集成的熔斷組件。
  • Sentinel
    • Spring Cloud Alibaba 中集成的熔斷組件,提供了一個外部控制台,可以實時調整系統的熔斷降級配置,在這個部分強於 Hystrix 。

鏈路追蹤 / APM

服務間互相調用,使得調試變得比單體應用複雜不少,這個時候使用鏈路追蹤工具能夠簡化調試,同時也能夠對應用程式的性能有更直觀的監控。

主流的鏈路追蹤組件有:

  • zipkin
  • pinpoint
  • SkyWalking
  • jaeger

API 網關

Spring Cloud 體系中常用的網關前有 Zuul,後有 Gateway,這一類跟 Spring Cloud 結合緊密,使用方便,但由於它們都是 Java 寫成,在許多場景下還是比不上一些專門的網關產品。

  • Kong
    • Kong 是 OpenResty 的衍生開源網關產品,擁有優秀的性能和豐富的插件,可滿足許多的擴展性需求。
  • Traefik
    • Traefik 是用 Go 語言編寫的網關,定位是雲原生的邊界路由網關產品,它擁有豐富的特性、易用的控制面板,與雲原生場景深度結合,提供了實時的流量指標可對接到 Prometheus 中。其企業版包含限流、高可用等特性,開源版在這一部分有所缺失。

服務網格

從單體應用到微服務的演進,我們會發現服務治理、熔斷、Tracing 這些幾乎是必不可少的部分,即使是使用 Spring Cloud 框架,我們也需要關注大量的微服務技術細節,為了分離這一關注點並使這些技術成為基礎設施一般的存在,服務網格應運而生。

什麼是Service Mesh(服務網格)?

服務網格好比微服務間的 TCP/IP,負責服務之間的網路調用、限流、熔斷和監控。對於編寫應用程式來說一般無須關心 TCP/IP 這一層(比如通過 HTTP 協議的 RESTful 應用),同樣使用 Service Mesh 也就無須關心服務之間的那些原本通過服務框架實現的事情,比如 Spring Cloud、Netflix OSS 和其他中間件,現在只要交給 Service Mesh 就可以了。

目前主流的服務網格有:

  • Istio
  • Linkerd

常用開源組件

上文有提及的,這裡不再累述。

數據訪問

  • MyBatis Plus
  • Mapper
  • jOOQ
  • JPA
  • dynamic-datasource-spring-boot-starter
  • sharding-jdbc

工具組件

  • guava
  • commons-lang3
  • hutool

快取

  • redission
  • jetcache
  • caffeine

位元組碼修改

  • asm
  • javassist
  • cglib

http客戶端

  • okhttp
  • Aache HttpClient
  • retrofit
  • openfeign

響應式編程

  • RxJava
  • reactor-core

序列化

  • protobuf
  • protostuff
  • hessian

分散式事務

  • seata

事件驅動框架

  • AxonFramework

規則引擎

  • drools

測試

  • junit
  • mockito
  • Spock

編程思想

編程思想是一個抽象的概念,要將其具象化我們必須透過現象看其本質,優秀的編程思想是對各種優秀想法的組織,這些想法可以精鍊成許多原則,原則是構成編程思想的一個重要部分,也是所有編程方式都可以遵守的通用準則。在原則的基礎上,在編碼過程中反覆解決的一些問題又被歸納為模式,這兩者是思想的主要構成,另外也有不同的編程範式及方法論,我在這裡簡單的講一下設計原則。

原則

很多原則不僅適用於編程領域,也適用於其他領域,我想這也是為什麼喬布斯提倡人人都應該學習編程,因為它能讓你擁有更好的思考方式。

  • 保持簡單
    • Keep It Simple, Stupid (KISS)
      • 最重要的原則之一,可靠來源於簡單,只有不斷保持系統的簡單、程式碼的簡單,才能更好地創造優秀的軟體。
    • You Ain』t Gonna Need It (YAGNI)
      • 如無必要,勿增複雜性,避免過度設計。
    • Separation of Concerns (SoC) – 關注點分離
      • 將目標相關聯的部分封裝在一起,標識為關注點。這是降低複雜性的一個重要原則,MVC 或 MVP 模式都是該原則的應用,將模型、視圖和控制器作為不同的關注點,使得每一個關注點可以更有效地理解及重用。
      • 在編碼過程中,也可以應用這一思想,比如我們首先關注應用程式是否可用,當其運行正確後再關心運行效率,這比同時進行這兩項工作要簡單的多。
  • 不要重複
    • Don』t Repeat Yourself (DRY)
      • 最簡單也最容易理解的原則,每個程式設計師都應該以隨意複製粘貼程式碼而感到羞愧。
    • Convention over Configuration(CoC)- 慣例優於配置原則
      • 將約定的配置方式和資訊作為預設的規則來使用,可以減少開發人員做決定的數量,減少編碼量,獲得簡單的好處,又不會丟失靈活性。
      • Spring Boot 框架解決的問題之一就是簡化項目的配置,其大量應用了 CoC 原則。
  • S.O.L.I.D 原則
    • Single Responsibility Principle (SRP) – 單一職責原則
      • 一個類,只做一件事,並把這件事做好,其只有一個引起它變化的原因。
      • 很簡單的原則,但是很多程式設計師在工作時經常違反這一原則,比如一個 service 類中引入許多 dao 對象,提供多種不相關服務。
    • Open/Closed Principle (OCP) – 開閉原則
      • 模組是可擴展的,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的。
      • 設計模式中的代理、策略和觀察者模式比較好地實現了這一原則。
      • 當我們定義的一個API可接受函數作為參數時,實際上也是一種策略模式的變體,同樣也體現了這一原則。
    • Liskov substitution principle (LSP) – 里氏代換原則
      • 子類必須能夠替換成它們的基類。
      • 這個原則可作為我們設計類繼承關係的基準。
    • Interface Segregation Principle (ISP) – 介面隔離原則
      • 對介面進行拆分,使用多個專門的介面比使用單一的總介面要好。
      • 介面可以多繼承,那為何要因為懶惰而將其隨便定義在一個總介面里呢?
    • Dependency Inversion Principle (DIP) – 依賴倒置原則
      • 高層模組不應該依賴於低層模組的實現,而是依賴於高層抽象。
      • IoC 是 DIP 的一個具體實現,其已經深入到程式語言當中,Spring 框架最初就只是作為一個 IoC 容器,而後才不斷擴展出許多實用功能並最終成為一個開發框架。
      • 相關原則:Hollywood Principle – 好萊塢原則(所有的組件都是被動的,所有的組件初始化和調用都由容器負責)。
  • 高內聚、低耦合
    • Law of Demeter – 迪米特法則
      • 又稱「最少知識原則」(Principle of Least Knowledge),一個類對於其他類知道的越少越好,知道的越多其耦合程度就越高。
      • 門面模式和中介模式都是迪米特法則應用的例子。
      • 這一原則強調低耦合。
    • Common Closure Principle(CCP)– 共同封閉原則
      • 如果必須修改應用程式里的程式碼,我們希望所有的修改都發生在一個包里(修改關閉),而不是遍布在很多包里。
      • 在微服務架構中,若修改一個功能時,經常需要修改多個服務,那麼其很有可能違反了 CCP 原則不恰當地進行了服務拆分。
      • 這一原則強調高內聚。
    • Common Reuse Principle (CRP) – 共同重用原則
      • 包的所有類被一起重用,沒有被一起重用的類不應該被組合在一起。依賴一個包就是依賴這個包所包含的一切。
      • CCP則讓系統的維護者受益,CCP讓包儘可能大(CCP原則加入功能相關的類),CRP則讓包儘可能小(CRP原則剔除不使用的類)。它們的出發點不一樣,但不相互衝突。
      • 這一原則同樣強調高內聚。

結語

正如開頭所言,服務端開發領域極其龐大,本文還有許多枝節尚未提及,比如安全、DevOps等等。技術的演進使這個領域加速擴大,未來還會有許多的變化,也許 Service Mesh 將會成為主流,也許 NewSql 將成為開發標配,任何一門技術的演進歷史變長,它的總體學習時間相應也會增加,但這並不意味著對其的應用也會變得複雜,我們不能忽視雲計算這一因素,雲服務的提供為開發者隱藏了許多的細節,在這個時代不需要知曉每一項技術的原理,也能夠開發出服務千萬用戶的產品。

未來會演進成什麼樣,可以去期待,但不要只是去期待,因為未來已經到來,只是還沒有平均分布。