Node.js是一個(gè)基于Chrome V8引擎的JavaScript運(yùn)行時(shí)環(huán)境,使用了高效、輕量級(jí)的事件驅(qū)動(dòng)、非阻塞 I/O 模型,讓JavaScript 運(yùn)行在服務(wù)端的開發(fā)平臺(tái)。本書主要介紹基于Node.js構(gòu)建企業(yè)級(jí)后端服務(wù),內(nèi)容涉及Node.js和JavaScript的特性介紹、通信協(xié)議、擴(kuò)展、可觀測性、Docker容器、部署、容器編排、應(yīng)用程序容錯(cuò)、分布式單元、應(yīng)用程序安全性等內(nèi)容。本書不是面向 Node.js新手的,適用于擁有Node.js 實(shí)戰(zhàn)經(jīng)驗(yàn)且熟練掌握J(rèn)avaScript的開發(fā)人員。讀完本書,你會(huì)了解在生產(chǎn)環(huán)境中運(yùn)行 Node.js 服務(wù)所需的許多技術(shù)。
適讀人群 :擁有了Node.js的實(shí)戰(zhàn)經(jīng)驗(yàn)且能熟練使用JavaScript 從初創(chuàng)公司到世界500強(qiáng),大多數(shù)公司都喜歡使用Node.js來構(gòu)建高性能的后端服務(wù)。工程師對(duì)Node.js有很高的評(píng)價(jià),因?yàn)樗腥菀桌斫獾腁PI和大家熟悉的語法。在全球大的包存儲(chǔ)庫的強(qiáng)力支持下,Node.js的生態(tài)必將更加繁榮。
在本書中,作者證明了Node.js在構(gòu)建可觀察、可擴(kuò)展且有彈性的服務(wù)方面與傳統(tǒng)的企業(yè)平臺(tái)一樣適用。中高級(jí)Node.js開發(fā)人員會(huì)發(fā)現(xiàn),他們可以將應(yīng)用程序代碼和現(xiàn)代服務(wù)的各個(gè)層面結(jié)合起來。
【通過學(xué)習(xí)本書,你可以:】
了解為什么要運(yùn)行多個(gè)相同的Node.js服務(wù)副本。
根據(jù)業(yè)務(wù)場景選擇恰當(dāng)?shù)膮f(xié)議。
調(diào)整應(yīng)用程序容器以便在生產(chǎn)環(huán)境中運(yùn)行。
跟蹤分布式系統(tǒng)中的錯(cuò)誤,以確定哪個(gè)服務(wù)出錯(cuò)。
通過將工作轉(zhuǎn)移給反向代理來簡化應(yīng)用程序代碼并提高性能。
構(gòu)建數(shù)據(jù)面板來監(jiān)視服務(wù)運(yùn)行狀況和數(shù)據(jù)吞吐量。
了解在企業(yè)環(huán)境中操作時(shí)需要使用多種工具的原因。
在舊金山的 NodeSchool 和 Ann Arbor 的 PHP MySQL 工作組工作的這幾年間,我一直致力于教授別人編程。到目前為止,我已經(jīng)教授過數(shù)百名學(xué)生。教學(xué)通常都是從安裝和配置所需的軟件開始。接下來,我會(huì)用一小段代碼和大段的語言向?qū)W生們解釋程序的運(yùn)行原理,學(xué)生們只需“點(diǎn)擊”即可。當(dāng)代碼運(yùn)行起來時(shí),學(xué)生們總是特別開心,就像在游戲里習(xí)得了新技能一樣。
我的目標(biāo)就是讓讀者通過本書重現(xiàn)那種激動(dòng)人心的感覺。在本書中,你將發(fā)現(xiàn)許多實(shí)際操作的示例,在這些示例中,你可以在開發(fā)機(jī)上運(yùn)行各種備份服務(wù),然后使用示例Node.js應(yīng)用程序代碼與它們交互。書中同時(shí)伴隨著大量的原理解釋和小問題,足以充分滿足你的好奇心。
在閱讀本書的過程中,你將安裝并運(yùn)行許多不同的服務(wù),并且對(duì)于每一個(gè)服務(wù),你都將編寫與它們交互的Node.js應(yīng)用程序代碼。本書著重強(qiáng)調(diào)了這些交互,并沒有把重心放在分析代碼上。
JavaScript 是一種很強(qiáng)大的語言,它能夠同時(shí)開發(fā)前端和后端應(yīng)用。這便于我們避開外圍技術(shù),把全部精力都投入語言學(xué)習(xí)中。許多人認(rèn)為只有使用Java或.NET等傳統(tǒng)企業(yè)平臺(tái)的工程師才會(huì)熟悉這些技術(shù),但其實(shí)JavaScript工程師也能夠受益于擁有第一手的技術(shù)經(jīng)驗(yàn)。
【讀者對(duì)象】
本書不會(huì)教你如何使用 Node.js。你應(yīng)該已經(jīng)擁有了 Node.js 的實(shí)戰(zhàn)經(jīng)驗(yàn)且能熟練使用JavaScript。也就是說,本書確實(shí)涵蓋了一些與 Node.js 和 JavaScript 相關(guān)的鮮為人知的高級(jí)概念,如“JavaScript的單線程特性”和“Node.js事件循環(huán)”。你還應(yīng)該熟悉HTTP的基礎(chǔ)知識(shí),至少使用過一個(gè)數(shù)據(jù)庫來持久化狀態(tài),并知道在運(yùn)行的Node.js進(jìn)程中維護(hù)狀態(tài)是多么容易但又多么危險(xiǎn)。
也許你已經(jīng)在一家擁有運(yùn)行后端服務(wù)的基礎(chǔ)設(shè)施的公司工作,并且渴望了解它是如何工作的以及你的Node.js應(yīng)用程序如何從中受益。或者,你有一個(gè)作為副業(yè)項(xiàng)目運(yùn)行的 Node.js
應(yīng)用程序,并且已經(jīng)厭倦了它的崩潰情況。你甚至可能是一家初創(chuàng)公司的CTO,并決心滿足不斷增長的用戶群的需求。如果這些情況聽起來很熟悉,那么本書很適合你。
【目標(biāo)】
Node.js通常用于構(gòu)建前端Web應(yīng)用程序。本書不涉及任何與前端開發(fā)或?yàn)g覽器相關(guān)的主題。本書的目標(biāo)是讓你將后端Node.js服務(wù)與各種支持現(xiàn)代分布式系統(tǒng)的服務(wù)集成在一起。
當(dāng)你讀完本書的時(shí)候,你就會(huì)了解在生產(chǎn)環(huán)境中運(yùn)行 Node.js 服務(wù)所需的許多技術(shù)。例如,部署和擴(kuò)展應(yīng)用程序需要什么,如何使服務(wù)有冗余性和故障彈性,如何與其他分布式進(jìn)程進(jìn)行可靠的通信以及如何觀察應(yīng)用程序的運(yùn)行狀況。
當(dāng)然,僅僅通過閱讀本書就想成為專家不太現(xiàn)實(shí)。本書并未涉及調(diào)優(yōu)、分片和將可擴(kuò)展的 ELK 服務(wù)部署到生產(chǎn)環(huán)境中所需的操作。不過,你將了解如何運(yùn)行本地的 ELK 實(shí)例,如何從 Node.js 服務(wù)向它發(fā)送日志,以及如何創(chuàng)建一個(gè)可視化數(shù)據(jù)面板來查看服務(wù)的運(yùn)行狀況(參見4.2節(jié))。
本書也許并未涵蓋你公司使用的所有技術(shù)。雖然第7章討論了 Kubernetes(一種編排應(yīng)用程序代碼部署的技術(shù)),但你的公司可能使用不同的解決方案,比如Apache Mesos。還有一種情況是你所用的是云環(huán)境中的Kubernetes版本,其底層實(shí)現(xiàn)對(duì)你來說是黑箱。無論如何,通過學(xué)習(xí)分布式后端服務(wù)棧不同層級(jí)的工具,你將更容易理解可能遇到的其他技術(shù)棧。
【示例代碼】
可以從https://github.com/tlhunter/distributed-node下載補(bǔ)充材料(示例代碼、練習(xí)、勘誤等)。
這里的代碼是為了幫助你更好地理解本書的內(nèi)容。通常,可以在程序或文檔中使用本書中的代碼,而不需要聯(lián)系O’Reilly獲得許可,除非需要大段地復(fù)制代碼。例如,使用本書中所提供的幾個(gè)代碼片段來編寫一個(gè)程序不需要得到我們的許可,但銷售或發(fā)布O’Reilly的示例代碼則需要獲得許可。引用本書的示例代碼來回答問題也不需要許可,將本書中的很大一部分示例代碼放到自己的產(chǎn)品文檔中則需要獲得許可。
第1章 為什么要用分布式9
1.1 JavaScript的單線程特性9
1.2 Node.js 速覽13
1.3 Node.js的事件循環(huán)16
1.4 示例應(yīng)用程序21
第2章 協(xié)議26
2.1 使用HTTP請(qǐng)求和響應(yīng)27
2.2 使用GraphQL構(gòu)建API外觀39
2.3 使用gRPC進(jìn)行RPC通信46
第3章 擴(kuò)展54
3.1 集群模塊54
3.2 使用HAProxy實(shí)現(xiàn)反向代理61
3.3 SLA和負(fù)載測試72
第4章 可觀測性85
4.1 運(yùn)行環(huán)境85
4.2 ELK與日志87
4.3 Graphite、StatsD和Grafana度量指標(biāo)94
4.4 使用Zipkin進(jìn)行分布式請(qǐng)求跟蹤102
4.5 運(yùn)行狀況檢查110
4.6 使用 Cabot 進(jìn)行報(bào)警113
第5章 容器119
5.1 Docker簡介121
5.2 容器化Node.js服務(wù)127
5.3 使用 Docker Compose進(jìn)行基本編排135
5.4 內(nèi)部Docker 注冊(cè)表140
第6章 部署145
6.1 使用 Travis CI 構(gòu)建流水線146
6.2 自動(dòng)化測試151
6.3 部署Heroku162
6.4 模塊、包和SemVer168
6.5 內(nèi)部npm注冊(cè)表179
第7章 容器編排184
7.1 Kubernetes 簡介185
7.2 啟動(dòng)188
7.3 部署應(yīng)用程序192
7.4 服務(wù)發(fā)現(xiàn)199
7.5 修改部署204
第8章 彈性210
8.1 Node.js 進(jìn)程的終止210
8.2 構(gòu)建無狀態(tài)服務(wù)218
8.3 使用Memcached構(gòu)建外部緩存224
8.4 數(shù)據(jù)庫連接的彈性229
8.5 使用Knex進(jìn)行Schema 遷移238
8.6 冪等性和消息傳遞彈性248
8.7 彈性測試255
第9章 分布式基元259
9.1 ID 生成問題259
9.2 Redis 簡介262
9.3 Redis 操作263
9.4 尋求原子性272
9.5 事務(wù)274
9.6 Lua腳本276
第10章 安全性281
10.1 繁雜的代碼庫281
10.2 認(rèn)識(shí)攻擊面283
10.3 應(yīng)用程序配置287
10.4 升級(jí)依賴項(xiàng)292
10.5 升級(jí)Node.js298
附錄A 安裝HAProxy303
附錄B 安裝Docker305
附錄 C 安裝Minikube和Kubectl307