後端好書閱讀與推薦系列文章:
後端好書閱讀與推薦
後端好書閱讀與推薦(續)
後端好書閱讀與推薦(續二)
後端好書閱讀與推薦(續三)
後端好書閱讀與推薦(續四)php
這裏依然記錄一下每本書的亮點與本身讀書心得和體會,分享並求拍磚。html
Docker生產環境實踐指南
Docker生產環境實踐指南 (豆瓣) https://book.douban.com/subje...java
前面docker的基本概念和一些核心原理都看的差很少了,那麼如今該關注一下具體的生產環境的使用方法了。node
亮點:nginx
- 在生產環境中運行docker與在其它環境中相比,最主要的差別是須要在其安全性與穩定性上投入更多的注意力
- 書中提到docker 容器與宿主機是經過IPtables實現的nat轉換來進行通訊,這點官網有說明 Docker container networking,而後就說了不適宜網絡吞吐量有很高要求的應用(可是能夠禁用Docker的NAT來提高網絡性能),可是docker已經作出了一些努力,效果並不差,見:1,2,3
- 書中對於docker相關常見的概念解釋得很是清晰易懂,這一部分尤爲適合初學者
- docker生產環境最好的方式是將應用程序及其依賴預先打包成一個鏡像,而包含數據庫憑證等銘感信息在運行時動態添加(安全起見);常見流程是開發機上打包並推送到倉庫,而後服務器從倉庫拉取鏡像,這種用例簡單可是從工做流和安全角度看並不理想,更標準的作法是使用持續集成 / 持續交付系統在應用程序代碼或者dockerfile發生變化時自動重新構建鏡像
- 實現開發速度和生產環境穩定的方法之一是擁抱簡單,亦即系統的每個部分——容器——有且只有一個目標。系統的簡單須要設計時遵守以下原則:傾向無狀態服務,傾向靜態配置,傾向靜態的網絡佈局,區別對待有狀態和無狀態的服務
- 保持鏡像小巧:能夠從空的文件系統開始構建,從相似於busybox、aipine這種輕量級操做系統開始構建,若是嫌包少就能夠從主流Linux發行版的容器優化版開始構建,最明智的作法是標準化一個特定的鏡像版本,並儘量的用於全部容器;儘量減小層數,也就是相關的命令儘可能放到一行,並且下載的內容用完後要在同一行刪除;能夠使用docker-squash來減少鏡像體積
- 存儲鏡像:開源、公共項目建議存共有倉庫;安全性和性能要求較高的存私有倉庫;須要定製的使用save / load。此外,不少人可能不知道,DockerHub實際上是提供了自動構建功能的,只要經過WebHook連上Github就行(親測)
- 一致性是擴展環境和傳播知識的關鍵,因此應該在一個構建系統中構建全部鏡像,並且要實現鏡像標準化,讓全部鏡像(儘量)繼承於一個標準基礎鏡像
- AUFS引擎的掛載速度很是快,能很快的建立新容器因此成爲了Docker存儲引擎的默認解決方案。其性能瓶頸主要在須要寫入大文件的場景,所以使用AUFS來存放數據庫文件可能不是一個好主意,一樣太多的鏡像層可能致使文件查找時間過長,因此不要讓本身的文件有太多分層。AUFS有一個最大的問題是沒有被容納到Linux主流發行版。事實上,在生產環境選擇存儲引擎,一個要點是看業務與特性是否吻合,另外一個要點就是選最有把握能穩定運維的工具
- Docker網絡實現包含三方面內容,IP分配、域名解析、容器或服務發現,這也是零配置網絡的理論基礎。零配置網絡便是一組在沒有人工干預的狀況下自動建立和配置一個TCP/IP網絡的技術。
- Docker集羣之中的服務發現,目前是consul作得最好,能夠自定義健康檢查機制,不像zookeeper(和TCP會話週期綁定)和etcd(和TTL值掛鉤),提供了一個很是完備的服務發現解決方案
本書名副其實,對於在生產環境中使用docker有不錯的方向指導意義,固然細節還得本身扣啊。
注意:因爲時間緣由,書中有些內容有些過期可是譯者給出了註解(可是譯者的註解也可能過期呀,因此必定要本身注意跟蹤docker的最新變化)git
The Go Programming Language
The Go Programming Language (豆瓣) https://book.douban.com/subje...程序員
爲何要了解一下 golang 呢?最明顯的緣由就是,這個語言有一款殺手級應用,也就是前面說過不少次的:Docker;並且前一段時間 nodejs 的創始人不是要擁抱 go 語言了嗎,做爲一個編程語言的創始人轉投另外一門語言,仍是很值得了解一下的;最後,對 go 的協程是早有耳聞,傳言能夠用同步的方式寫出異步的代碼,輕鬆實現高併發......github
亮點:golang
- 正如Rob Pike所說,「軟件的複雜性是乘法級相關的」,經過增長一個部分的複雜性來修復問題一般將慢慢地增長其餘部分的複雜性。經過增長功能和選項和配置是修復問題的最快的途徑,可是這很容易讓人忘記簡潔的內涵,即便從長遠來看,簡潔依然是好軟件的關鍵因素。秉承着簡潔原則,golang沒有內置大多數語言都有的隱式轉換、宏、異常、繼承等等
- 依然是簡潔原則的貫徹,golang 不容許 import 沒有使用的包,也不能定義沒有使用的變量,不然連編譯都不能經過。還有左大括號必須和代碼在同一行......感受這些強制要求很是有用,多一些標準,少一些歧義,這應該是利於工程化的
- break 和 continue 均可以加label來實現跳出任一循環,這個有點像 goto 語句,這種語句咱們要少用,通常是在編譯器生成代碼過程使用的
- 並非全部的詞法域都顯式地對應到由花括弧包含的語句;還有一些隱含的規則。好比for語句建立了兩個詞法域:花括弧包含的是顯式的部分是for的循環體部分詞法域,另一個隱式的部分則是循環的初始化部分,好比用於迭代變量i的初始化。隱式的詞法域部分的做用域還包含條件測試部分和循環後的迭代部分(i++),固然也包含循環體詞法域
- 結構體中的匿名成員是一個比較有意思的特色,能夠用來無縫的實現「對象組合」這一需求,組合是 go 實現面向對象編程的核心
- 大部分語言使用固定大小的函數調用棧,常見的大小從64KB到2MB不等。固定大小棧會限制遞歸的深度,當你用遞歸處理大量數據時,須要避免棧溢出;除此以外,還會致使安全性問題。與相反,Go語言使用可變棧,棧的大小按需增長(初始時很小)。這使得咱們使用遞歸時沒必要考慮溢出和安全問題
- 在Go中,錯誤處理有一套獨特的編碼風格。檢查某個子函數是否失敗後,咱們一般將處理失敗的邏輯代碼放在處理成功的代碼以前。若是某個錯誤會致使函數返回,那麼成功時的邏輯代碼不該放在else語句塊中,而應直接放在函數體中。Go中大部分函數的代碼結構幾乎相同,首先是一系列的初始檢查,防止錯誤發生,以後是函數的實際邏輯
- 當defer語句被執行時,跟在defer後面的函數會被延遲執行。直到包含該defer語句的函數執行完畢時,defer後的函數纔會被執行,不論包含defer語句的函數是經過return正常結束,仍是因爲panic致使的異常結束。deferred相似於java的finally,可用於保證資源回收、鎖釋放等
- 看到第八章終於知道傳言的大概意思了,只須要在原來同步的調用函數的代碼以前加一個 go 關鍵字,就能新建一個goroutine(能夠類比線程,可是有不一樣之處),而後主線程就能繼續幹活而沒必要等待函數執行結束了
- 線程和goroutine的區別主要有幾方面:goroutine的棧不是固定大小的,通常從2KB開始動態變化,因此能夠打開幾百上千的goroutine,而線程是固定棧大小,不可能開不少;goroutine由Go調度器進行調度,而不是操做系統,採用m:n模型(最多n個線程執行m個goroutine),因此goroutine的切換代價較小
- 雖然及時修改了一個源文件也要從新編譯該文件對應的包及其依賴包,可是go的編譯速度很是快,主要有三點緣由:全部導入包開頭顯示聲明,快速找到;禁止環裝依賴,能夠併發編譯;編譯後的包記錄了包的依賴關係,編譯器不須要遍歷全部依賴文件只需讀取直接導入包的目標文件
- 程序的複雜性是能夠控制的,其中兩種技術在實踐中被證實頗有效:軟件正式部署前的代碼評審;自動化測試(寫一些小的程序用來檢測被測試代碼的行爲和預期的同樣)。go test 命令是一個按照必定的約定和組織的測試代碼的驅動程序,在*_test.go文件中:測試函數以Test爲函數名前綴,用於測試程序的一些邏輯行爲,go test命令會調用這些測試函數並報告PASS或FAIL;基準測試函數以Benchmark爲函數名前綴,用於衡量函數的性能,go test命令會屢次運行基準函數以計算一個平均的執行時間;示例函數以Example爲函數名前綴,提供一個由編譯器保證正確性的示例文檔
本書名不虛傳,對go的基礎知識介紹的很詳盡,底層原理也稍微有一些涉及,同時還有一些高級的話題好比各類併發、測試等,是一本入門go的好書,看完後對golang就有一個幾乎完整的概念了。web
PS:gitbook有對應中文版。
從PAXOS到ZOOKEEPER分佈式一致性原理與實踐
從Paxos到Zookeeper (豆瓣) https://book.douban.com/subje...
現在搞分佈式的彷佛都離不開Zookeeper了,Zookeeper通常是做爲分佈式的基礎設施,仍是頗有必要了解一下的。本書闡釋了從集中式到分佈式的問題,如何解決,層層遞進引入了Zookeeper,而後介紹了應用場景和技術內幕,算是一個很是全面的介紹了,並且做者的思路很是清晰,咱們讀起來很流暢,可是書中涉及的一些協議自己是比較複雜的,讀起來有些麻煩。
亮點:
- 集中式的系統保證事務的 ACID 相對而言是比較容易的,並且有不少成熟的解決方案。可是根據 CAP 理論:「一個分佈式系統系統不可能同時知足一致性、可用性、和分區容錯性,最多隻能知足兩樣」,因此分佈式系統不大可能嚴格知足 ACID 的強一致性,而分區容錯性 P 是分佈式系統自己存在的意義,因此通常設計者就在 A 和 C 之間尋求平衡了,根據 BASE 理論,通常分佈式系統都實現以實現最終一致性、保證高可用性爲目標。BASE理論不只應用於分佈式系統,也普遍應用於現代關係數據庫
- 數據的一致性與可用性之間的反覆權衡產生了 一系列的一致性協議,最經典莫過於二階段、三階段提交協議和Paxos算法了。這三者層層遞進,分別解決了前者的一些問題,並各自在不一樣的領域被使用
- Zookeeper是一個典型的分佈式數據一致性解決方案(工業級產品),致力於提供一個高性能(高吞吐量)、高可用(解決單點問題)、具備嚴格順序訪問(主要是寫)控制能力(實現複雜同步原語)的分佈式協調服務。其設計目標:簡單的數據模型(樹型、共享、內存)、能夠構建集羣、順序訪問(請求有惟一遞增編號)、高性能,能夠保證許多一致性特性:順序一致性、原子性、單一視圖、可靠性、實時性。分佈式應用程序能夠基於它實現數據發佈訂閱、負載均衡、命名服務、分佈式協調通知、集羣管理、Master選舉、分佈式鎖和分佈式隊列等功能
- 做者對ZooKeeper的常見應用場景進行了詳盡的描述,很是有借鑑意義,好比:client利用節點建立的API能夠建立一個順序節點,再加上其type就造成了一個全局惟一的ID了,從而實現命名服務;不一樣機器經過在同一節點建立臨時子節點,並根據其餘機器的臨時子節點來判斷對應的機器是否存活,從而實現心跳檢測;經過強一致性的惟一節點保證來實現master選舉(誰能創建特定節點誰就是master,其餘機器註冊watcher,一旦當前master掛了節點刪除,就又開始新的選舉);經過節點惟一性來實現排它鎖、子節點排序來實現共享鎖......總而言之,能夠在ZooKeeper子節點惟一性上面作不少文章
- 具體使用案例,Canal這款基於Mysql BinLog的增量訂閱消費組件使用ZooKeeper來實現Canal Server的主備切換功能,主要原理就是臨時節點和節點惟一性;Canal Client利用ZooKeeper來時刻關注Canal Server的變化,進行消費並記錄消費點
- 數據模型:由ZNode(稱爲節點,類型有持久、臨時、順序節點,可組合)層次化組織而構成的樹,路徑相似於Unix文件系統,每一個ZNode能夠存數據、建立子節點(臨時節點無子節點);採用版本號以及CAS來實現樂觀鎖機制;採用ACL來實現細粒度的權限管理;採用一次性、客戶端回調串行執行、推拉結合的輕量級watcher來實現時間發佈訂閱
- Leader選舉的原理簡單說來就是誰的數據越新,那麼其ZXID(事務ID)越大,就越可以保證數據的恢復,就越能成爲Leader,對於相同的ZXID,那麼SID較大的成爲Leader,這個應該沒啥特別的緣由,只是做爲一種肯定機制。
- Leader是集羣中的核心,主要工做:事務請求的惟一調度者和處理者,保證集羣事務處理的順序性;集羣內部各個服務的調度者。Follower是集羣狀態跟隨者,主要工做:處理客戶端非事務請求,轉發事務請求給Leader;參與事務請求Proposal的投票;參與Leader選舉。Observer觀察集羣最新變化狀態並同步過來,工做相似於Follower,只是不參與任何投票,一般用於在不影響集羣事務處理的狀況下提高集羣的非事務處理能力
看徹底書再去看看應用案例可能會產生更好的理解。
現代操做系統(原書第4版)
現代操做系統(原書第4版) (豆瓣) https://book.douban.com/subje...
操做系統是咱們一切編程的根基,不瞭解操做系統就只是「粘貼複製員」而不是「程序員」更別提「工程師」了。這本書既講到了傳統的重點概念:內存、進程、文件、安全等,又講到了如今普遍應用的虛擬化、雲、Linux、Windows等,無愧於「現代操做系統」的名稱。
亮點:
- 抽象是管理複雜性的一個關鍵,好的抽象能夠把一個幾乎不可能管理的任務劃分爲兩個可管理的部分,其一是抽象的定義與實現,其二是用這些抽象解決問題。操做系統就是把硬件醜陋的接口轉換爲一個良好、清晰、優雅、一致的抽象。最爲人熟知的抽象就是「文件」,它統一了各類格式的數據、各類IO設備對於用戶的接口(操做系統3大抽象:文件,進程與線程,地址空間,分別對應磁盤,處理器,內存)。能夠把操做系統理解爲一個資源管理者,管理硬件資源如何分配給應用程序,讓應用程序更好地使用這些資源
- 技術的變化會致使某些思想迅速過期,可是也可能使得另外一種是思想復活,當技術的變化影響了系統內部不一樣組件的相對性能之時就更是如此。好比早期計算機指令由硬件直接執行,微程序設計出現後採用解釋執行,RISC又採用了直接執行,java又採用瞭解釋執行,這樣來回擺動主要是由於執行速度不老是關鍵因素,還有多是網絡延遲。再好比計算服務過期了,可是又以雲計算的形式從新流行,因此對待技術要保持客觀、辯證的態度,不要由於如今看起來過期就對它唾棄,說不定未來它又能流行起來發揮大的做用
- 有了進程還要線程的緣由:邏輯上,一個應用中自己能夠劃分爲多個活動,一個活動一個線程便於理解;線程更輕量級,容易建立、撤銷;若存在大量IO處理,多線程彼此重疊進行是能夠提高吞吐量的(若每一個線程都是CPU密集型則不能);多線程能夠真正利用多核。
- 都知道java有偏向鎖、輕量級鎖、重量級鎖的升級,實際上操做系統也有相似鎖的概念,並且Linux還採起了「Futex」這個方案來結合自旋鎖和重量級鎖(阻塞)的優勢。一個Futex包含兩部分:一個內核服務和一個用戶庫,簡單說來就是在用戶態建立一個futex同步變量,當有進程要得到鎖時,對futex執行"down"操做即原子性的給futex同步變量減1,若是成功便可繼續不需進入內核態,不然進入內核態阻塞,這樣就大大減小了低競爭時的吞吐量
- 經過交換技術,系統能夠同時運行超過實際內存大小的多個進程;現代計算機都使用某種虛擬內存技術,每一個進程地址被分爲一樣大小的頁面(一般四、8KB),能夠被放入空閒內存的任何頁框內,有多種頁面置換算法,實際應用中用的最多的是老化算法和工做集時鐘算法;若是在執行過程當中有大小變化的數據結構能夠採用分段的方法,可是幾乎沒有主流的操做系統考慮分段算法
- 文件系統的存儲區分配方案有連續文件、鏈表、文件分配表和iNode。磁盤空間能夠經過位圖的空閒表來管理。提高文件系統性能的作法有高速緩存、預讀取、以及儘量將一個文件的塊放在一塊兒等方法
- 操做系統除了負責提供抽象還要負責管理全部IO,IO主要有三種方式實現:程序控制IO、中斷驅動IO、DMA
- 死鎖發生有四個條件:互斥條件、佔有和等待條件、不可搶佔條件、環路等待;解決辦法有四個:鴕鳥對策、死鎖檢測與恢復、合理資源分配動態避免死鎖、經過破壞引發死鎖發生的四個必要條件之一來防止死鎖發生
- 虛擬化的好處:能夠在節省硬件與電力資源的狀況下實現強隔離性、使得各個應用程序很容易擁有本身的運行環境、設置檢查點和虛擬機遷移比在普通操做系統中容易的多,目前虛擬化最重要的用途就是雲
- 編寫操做系統不容易,那麼從何入手呢?從對外接口開始,三大原則:簡單,不是當沒什麼東西能夠添加而是當沒什麼東西能夠減小時才能達到盡善盡美,或者說KISS原則;完備,完事應該簡單,可是不能過於簡單,必需要能完成用戶所需的一切事情;效率,若是功能不能有效實現那就不值得擁有這個功能。這些原則對於咱們全部的系統設計都有借鑑意義
這本書的字真是太多了,也過小了,吐槽一下印刷,此外,內容也很細很全,仍是應該採起先觀其大略、使用時細讀的策略。
大規模分佈式存儲系統
大規模分佈式存儲系統 (豆瓣): https://book.douban.com/subje...
看了許多分佈式概念性的書籍,也瞭解了java中間件、分佈式一致性、ZooKeeper做爲基礎設施等等概念,是時候找個具體的方向瞭解分佈式了,那麼這本書就是分佈式在存儲這一塊的具體實戰了。本書從概念到實戰,講了分佈式文件、鍵值系統、表格系統、數據庫等等,幾乎覆蓋了全部涉及存儲的方向,看完就能對分佈式存儲有一個較爲完整的瞭解了。
亮點:
- 分佈式存儲有幾個特性:可擴展(容易擴展到幾百幾千臺集羣規模,且性能隨數量線性增加)、低成本(構建於普通PC機之上)、高性能、易用(提供易用的對外接口);主要挑戰在於數據分佈均勻、數據一致性、容錯性、負載均衡、事務併發與控制、易用性、壓縮解壓縮;數據分爲非結構化數據(圖、文)、結構化數據(關係數據庫)、半結構化數據(HTML);不一樣的存儲系統適合不一樣的數據類型,分佈式文件系統主要存儲Blob對象(文檔、圖片、視頻)等非結構化數據和做爲其餘分佈式系統的基礎,分佈式鍵值系統存儲簡單的半結構化數據,分佈式表格存儲複雜的半結構化數據,分佈式數據庫存儲結構化數據
- 設計網絡系統的基本原則是:網絡永遠是不可靠的,任何一個消息只有收到對方回覆後纔可認爲發送成功,系統設計時老是假設網絡將會出現異常並採起相應處理措施(可是咱們必須假設信道是可靠的,否則任何工做於其之上的任何協議都不能是可靠的)
- 分佈式系統在CAP理論的C和A之間權衡時能夠參照Oracle的DataGuard複製組件的三種模式:最大保護模式(亦即強同步模式,主庫先將操做日誌同步到至少一個備庫才能返回給客戶端成功結果),應用於餘額等關鍵記錄;最大性能模式(亦即異步複製,主庫完成執行就返回客戶端,將重作日誌以異步的方式複製到備庫),應用於用戶操做日誌等非關鍵記錄;最大可用性模式(上述兩種模式的折中,正常狀況至關於最大保護模式,當主備之間的網絡出現故障切換爲最大性能模式),應用於通常記錄
- 故障檢測能夠經過心跳檢測來作,這是最原始的想法,可是機器也可能由於太忙,或者與控制節點的網絡斷掉而沒法進行心跳,這種狀況下使用時鐘同步(須要考慮一個時間提早量,由於時鐘並不能嚴格一致通常都會有小於1秒的微小偏差)加租約(Lease)的形式能夠較好地避免這個問題
- 跨機房部署有三種方案:集羣總體切換(實際最多見作法,兩個機房保持獨立,保持相同的副本數,有主備之分(Primary,Secondary),可能強同步或者異步複製),單個集羣跨機房(不一樣數據分片的主副本位於不一樣機房)、Paxos選主副本(每一個數據分片的多個副本構成一個Paxos複製組,自動選舉主副本,下降了對總控節點的依賴可是工程複雜度很高)。
- GFS成功的經驗代表:單Master的設計是可行的,不只簡化了系統,並且能較好地實現一致性。這是一種中心化的架構,是目前互聯網的主流架構,而去中心化的Gossip協議雖然藉着Cassandra(Amazon的Dynamo的開源實現)大火了一把,可是因爲其複雜性與一致性問題實際上分佈式系統不多使用
- OceanBase是一款可擴展的關係型數據庫(支持強一致性和跨表事務),主要架構份內四部分:RootServer一主一備,主備強同步,負責集羣管理,數據分佈以及副本管理;UpdateServer一主一備,主備同步模式可配置,接受寫操做,而且按期把新數據同步給Chunkserver;ChunkServer存儲基線數據,只提供讀取服務,並按期接受UpdateServer的數據同步;MergeServer解析用戶Mysql兼容請求,將請求轉發給對應的ChunkServer和UpdateServer,無狀態,相似於網關的做用
- OceanBase寫操做強一致性的原理是:UpdateServer將redo日誌發送給備機,redo日誌寫到本地磁盤,redo日誌應用到主機內存表,返回客戶端成功。這樣即便主備機切換也能保證新的主機有之前全部的操做記錄而不會丟失,能夠經過增長備機數量來提升可用性保證。固然UpdateServer主備同步也支持異步模式,支持最終一致性,通常用來實現異地容災。此外主備集羣也能夠實現錯峯合併
- OceanBase藉助UpdateServer邏輯單點來實現強一致性,那麼這個單點會不會成爲瓶頸呢?通常來講,互聯網業務讀寫比都比較高,因此不會成爲瓶頸,即便是雙十一這種,也能夠經過自動凍結內存錶轉入SSD硬盤、按期合併與分發、旁路導入、多塊網卡配置、RAID卡緩存模塊、成組提交等優化方式來避免內存、網絡、磁盤的瓶頸;經過主備強一致備份策略與實時同步避免單點故障,這樣這個單點問題就幾乎不存在了
- 列式存儲的主要目的有兩個:大部分OLAP只須要讀取部分列而不是所有列數據,列式存儲能夠避免讀取無用數據;將同一列的數據在物理上存放在一塊兒,可以極大的提升數據壓縮率
- 大表左鏈接是互聯網的一個常見問題,通常採起引用(多表主鍵鏈接)、或者嵌套(主表冗餘連表信息),可是這分別只能適應讀取次數少、讀寫比較高的場景,若是讀取次數多且讀寫比不高那麼這兩種作法就沒轍了。OceanBase採用基線數據冗餘連表+修改增量合併的方式解決了這個問題
看完這本書是真的頗有收穫,對整個分佈式架構有了一個完整的瞭解,從大大的跨機房到一個小小的數據分片副本,從上到下很是清晰。此外最佳實踐那一部分也是很讚的,強烈推薦此書。
微服務設計
微服務設計 (豆瓣): https://book.douban.com/subje...
微服務最近兩年愈來愈火,其實這並非什麼新鮮概念,計算機體系裏面早就有單內核與微內核的架構思想了,微服務也是一種相似的思想,可是是處於更高級別的應用架構層(因此計算機領域裏面的許多思想是能夠相互借鑑的好比抽象、緩存、LRU算法、並行處理等等)。微服務的好處是不少的,單個服務容易開發、理解和維護;容納異構技術;部署簡單、迭代速度快、變化小bug少;彈性、擴展性好等等。本書就帶領咱們從建模、集成、測試到部署和監控,全面瞭解微服務,爲進一步學習指引方向。
亮點:
- 微服務是一種分佈式系統解決方案,推進細粒度服務的使用,這些小而自治的服務協同工做,都有本身的生命週期,圍繞業務領域建模,根據業務的邊界來肯定服務的邊界,所以也很容易肯定某個功能代碼的位置,避免了傳統分層架構的許多問題。一個微服務就是一個實體,不一樣微服務經過網絡通訊互相調用。咱們知道,直接進程內方法調用是很快,可是也意味着兩個對象緊密耦合了,經過網絡通訊調用雖然慢一些,可是兩個對象就鬆耦合了,能夠隨時替換掉一個而另外一個徹底不用知道,我以爲隨着網速愈來愈快,網絡通訊代價愈來愈小,微服務的優點將愈來愈明顯,直接耦合調用的方式的優點將愈來愈弱
- 架構師就相似於城市規劃師應該專一於大方向,只能參與少許細節,須要保證系統能知足當前的需求,還要可以應對未來的變化,以一種演化的方式來進行規劃,這是一個很大的標準,從何入手呢?答案是:分區,定好服務邊界與交互方式,能夠使用限界上下文。演化的方式就是咱們要理解,隨着項目發展,服務必定會愈來愈大,咱們要作的就是讓架構增量變化,在拆分這件事變得過度昂貴以前進行拆分
- 重用代碼可能引入危險,由於咱們可能引入服務之間的耦合。因此雖然咱們要作到DRY原則,可是也要防止過分追求DRY原則帶來的系統過分耦合,這是一個比較微妙的話題,要記住,DRY不是意味着避免重複的代碼,而是意味着避免系統行爲和知識的重複,在微服務內部不要違反DRY,跨服務時能夠適當違反來避免服務之間耦合
- 處理跨服務的業務流程時能夠選擇:編排,一箇中心節點調度其餘全部服務完成,這樣流程很清晰,可是會致使中心節點承擔過多,其它服務淪爲貧血的基於CURD的服務;協同,相關服務訂閱特定的事件,事件由客戶端觸發以後每一個服務各自完成本身的處理,這樣能明顯消除耦合,可是就看不到明顯的流程圖了,並且可能須要跨服務監控,可是整體而言傾向於協同,利大於弊
- 真正的持續集成要理解3個問題:是否天天簽入代碼到主線?是否有一組測試來驗證修改?構件失敗事後是否把修復CI當作第一要務?最好是每個微服務都有本身的代碼庫和CI,只有這樣才能真正實現獨立部署
- 微服務部署最好採用單主機(能夠是物理主機、虛擬機、容器)單服務的方式,這樣利於團隊自治、服務部署、監控、故障排查、擴展性更好等,可是這個模式會引入大量主機,這就意味着重複勞動會多起來,因此咱們必定要實現自動化(無論什麼技術棧都要追求自動化)
- 自動化測試類型分爲單元測試、服務測試、用戶測試(端到端測試)。其中單元測試是針對一個函數的、面向技術、幫助開發人員快速發現錯誤和增長重構信心;服務測試針對一系列函數構成的完整服務,提升測試隔離性,幫助快速定位問題;端到端測試包含整個系統,加強咱們發佈服務的信心。這三者的比例最好是前者比後者多一個數量級
- 監控當然要看低層指標好比CPU利用率、空閒內存、帶寬使用等等,可是這些指標每每太多而帶來噪聲不利於監控咱們真正關心的行爲,因此須要語義監控,亦即準備一些合成數據和事件來觀察系統是否按照咱們的指望完成任務,固然這些數據要注意不能和真實生產數據混淆
- 任何組織在設計一套系統時,所交付的方案在結構上都與該組織的溝通結構一致。這被稱爲康威定律
- 構建分佈式系統須要思惟的轉變,那就是故障總會出現,不是全部人都須要像Google或者Netflix同樣使用ChaosMonkey來模擬故障測試系統的健壯性,可是咱們都須要爲各類故障作好準備好比:超時(設置默認超時並記錄日誌)、斷路器(請求失敗必定次數後斷路器打開,下次快速失敗就不用再等待了)、艙壁(服務內外均可以使用,關注點分離,爲每一個下游單獨準備鏈接池)、隔離
PS:書中提到了很多參考書,都是能夠看看的。
算法(第4版)
算法(第4版) (豆瓣) https://book.douban.com/subje...
本書講解的算法和數據結構都是咱們必須掌握的,屬於入門級知識,可是做者講的很仔細,頗有趣,沒有那麼多的數學證實,比《算法導論》讀起來跟容易一些,可是做者的觀點也都是立得住的,有理有據,值得通看,造成本身對於算法的初步體系。
亮點:
- 本書提供了全部代碼還有教學視頻,能夠輔助學習,網址。我把代碼fork了一份,在這
- 本書對算法性能的分析是科學式的,亦即先對性能提出假設,創建數學模型,而後用多種實驗驗證它們,必要時重複這個過程
- API的目的是將調用和實現分離(模塊化編程),能夠將API看作調用和實現之間的一份契約,他詳細說明了每一個方法的做用,實現的目標就是遵照這份契約。讀到這裏就有一個感想,咱們程序的進步都是在努力地把人爲的契約固化到代碼中,減小出錯機率。好比程序員之間直接約定不夠可靠,那麼就經過接口來強制約定;再好比生產與開發環境不容易保持一致,就經過DockerFile來強制約定
- 做者循循善誘,爲了給咱們分析算法性能提供動力,講了一個3-sum問題的逐步優化過程:暴力的3-sum是一個立方級別的算法,先從簡單的狀況考慮2-sum,經過線性對數級別的排序,而後用對數級別的二分查找一個元素的相反數來進行統計,這個算法就是線性對數級別的,而後天然擴展到3-sum,獲得平方對數級別的快速的3-sum,並查集也是相似按部就班的教法
- 初級算法雖然簡單,可是它幫咱們創建了一些基本規則,展現了一些性能基準,在某些特殊狀況下也是很好的選擇,也是開發更強大的算法的基礎,因此仍有必要系統的學習它們
- 把排序算法講了一遍以後,講到了規約(爲了解決某個問題而發明的算法能夠解決另外一個問題),好比排序就能夠用瞭解決不少其餘問題,通常能將暴力的平方級別解法降低到非暴力的線性對數級別,好比:找出重複元素、排名、優先隊列、中位數、第K個最小/大的值(模仿快速排序的partition操做就能達到線性級別)等
- 散列表的意義是在時間與空間之間取得一個平衡,選擇適當大小的數組M,既不會由於空鏈表形成內存浪費也不會由於鏈表太長而致使查找效率低
- 書中對於圖的表述中,深度優先等遍歷方式都給出了詳細的算法與示例的軌跡圖,你想看不懂都難
- 就解決圖的連通性問題,理論上來講,深度優先比union-find(聯合查找或者說並查集)更快,可是實際上union-find更快,由於它不須要對圖進行預處理,是一種動態的算法(能用接近常數的時間檢查兩點是否相通,甚至是添加邊),而對於已是圖的數據類型使用深度優先更快,由於它能利用已知信息
- 用於子串查找的KMP算法的基本思想是,當文本出現不匹配時就能知曉一部分文本內容,能夠利用這些信息避免將指針會退到全部這些已知字符以前,亦即充分利用已知信息,這也是插入排序優於選擇排序的緣由。KMP主要亮點是提早判斷如何從新開始查找,這種判斷不須要文本指針i徹底回退,只需根據模式自己信息從新進行比較位置的選擇
- 許多問題均可以規約爲排序問題(中位數、不一樣值統計)、最短路徑問題(任務調度、套匯)、最大流量問題(就業安置、網絡可靠性)、線性規劃(最大流量)
- NP是全部搜索問題(有解且驗證解的正確性的時間不會超過輸入規模的多項式的問題)的集合;P是可以在多項式時間內解決的全部搜索問題的集合
本書的java基礎部分是至關的豐富,學完算法也能夠順帶複習一遍java了,很划算 (* ̄︶ ̄)。
還有,本書雖厚,可是必定要看完,這樣纔有一個完整的體系,而且算法的細節也能掌握了,之因此不採起往常對待大部頭的觀其大略的方法是由於這是算法,是常常須要咱們實施的領域,和代碼編寫直接相關(不像操做系統的知識),因此必須掌握細節。能夠參見個人另外幾篇專門講算法的博客
Hadoop權威指南
Hadoop權威指南(第3版) (豆瓣): https://book.douban.com/subje...
Hadoop的出現開啓了大數據的序幕,到了如今已經成爲一個比較完善的生態,服務於雲計算與大數據。記得大三的時候學校有免費的雲服務器,我申請了5臺本身搭建了一個Hadoop集羣跑了一下 Hello World 級別的 Word Count,而後就開始期末考試了,沒有再繼續深刻了解,如今是時候全面的瞭解一下了,這本書號稱權威指南,看它沒錯。
亮點:
- MapReduce相對於其餘系統的優點:比RDBMS更適合一次寫入屢次讀取的任務,適合批處理任務,是一種線性可伸縮的編程模型;由於儘可能作到數據本地存儲,因此比網格計算(帶寬限制,只適宜CPU密集型任務)更能處理巨量數據的任務,同時處理CPU密集型任務也不弱;比志願計算(貢獻CPU而非帶寬)更可靠,更易實施,更好控制
- HDFS是Hadoop的旗艦級文件系統,可是Hadoop也能集成其它文件系統如S3,HDFS設計要點:超大文件、流式數據訪問、商用硬件(零售店可買)、低延遲訪問不太適用(HBASE更佳)、大量的小文件、僅支持單用戶寫入且不能隨機寫
- 分佈式文件系統的塊(chunk)抽象有許多好處:一個文件能夠大於任意磁盤的容量(由於無需把一個文件存在一個磁盤上);抽象塊簡化了存儲設計(塊大小固定,默認64MB磁盤性能越好越大,故每塊盤能存多少塊是固定的,並且元數據也能夠單獨管理);適合數據備份,從而提升容錯能力和可用性(每一塊能夠複製到多個機器上,默認是3個,若是塊、磁盤或機器發生故障系統會從其餘機器讀取副本,此過程對用戶透明。並且多個副本能夠提升讀取性能)
- HDFS 有兩種節點,一個namenode做爲管理者,管理整個文件系統的命名空間,維護整個文件系統樹及其文件與目錄,同時也記錄着每一個文件中各個塊所在的數據節點信息,namenode相當重要必須正常運行,因此提供了兩種容錯機制,實時同步元數據至其它地方和運行輔助namenode;多個datanode做爲實際工做者,存儲數據塊供讀寫並按期向namenode發送存儲的塊的列表
- YARN將JobTracker劃分爲多個職能的實體(資源管理器和應用管理器),改善了經典的MapReduce面臨的擴展性問題,實際上比MapReduce更具通常性,MapReduce只是YARN應用的一種形式,有不少其餘的YARN應用如分佈式shell
- MapReduce提供了計數器(統計無效數據)、排序、鏈接(join操做,將兩個數據集合二爲一)、邊數據分佈(配置額外的只讀數據來完成做業)、MapReduce庫類等常見功能
- 部署hadoop時典型配置是同一個機架有一些節點,不一樣機架經過交換機鏈接起來的二級網絡架構。由於機架內部通訊更快因此必定要把這些配置告訴Hadoop系統,這樣分配MapReduce任務時會傾向於機架內節點,節省傳輸成本,同時HDFS的文件塊的3個副本也會盡可能分佈在兩個機架上
- Pig是一種探索大規模數據集的腳本語言,省去MapReduce繁瑣耗時的步驟(寫mapper、reducer,代碼編譯,打包,提交做業),僅需控制檯的幾行pig Latin代碼就能處理TB級別的數據,並且支持更豐富的數據結構
- Hive能把SQL查詢轉換爲一些列運行在Hadoop上運行的MapReduce做業,它把數據組織爲表,經過這種方式爲HDFS中的數據賦予結構。Hive與傳統數據庫有不少相似之處(如SQL語言的支持,尤爲相似於Mysql),可是其底層依賴於HDFS和MapReduce而非傳統的文件系統,Hive採用讀時模式(查詢時進行模式檢查)而非寫時模式(寫入時檢查模式)能夠使得數據加載很是迅速,由於他只是移動數據而不須要讀取、解析、序列化等。寫時模式有利於提高查詢性能,由於能夠創建索引、數據壓縮等,Hive沒有考慮過這些特性(以及事務、更新、刪除等),由於MapReduce下,全表掃描是常態
- HBASE是在HDFS上開發的面向列[族]的分佈式數據庫,若是須要實時的訪問超大規模的數據集,就能夠使用HBASE。與RDBMS相比,HBASE能解決不少伸縮性問題(表能夠高達幾十億行,幾百萬列)、能水平分區並在上千個普通節點上自動複製、線性擴展與新節點自動處理。RDBMS對於中小規模應用提供的易用性、靈活性和完整的功能性是幾乎無可取代的,可是要在數據規模和併發讀中任意方面向上擴展就會損失不少性能,由於RDBMS是面向行的具備ACID和事務的強一致性等特性,向上擴展意味着要打破這些特性,使得管理變得複雜
- ZooKeeper通常用來構建分佈式服務具備許多特性:簡單(核心是一個精簡的文件系統)、豐富(提供分佈式隊列、鎖、領導選舉等功能)、高可用(運行於一組機器,避免單點故障)、鬆耦合交互(參與者沒必要互相瞭解)、資源庫(提供通用協調模式的開源共享庫)
本書做爲了解Hadoop的設計思想以及關鍵點的手段,我還沒有進入真正的使用,不少代碼以及API部分就省略沒看了,因此雖然是個大部頭,可是看起來並不會特別慢。固然若是真的要使用,書中的接口和代碼可能就已通過時了,要搭配最新官方文檔來看
HTTP權威指南
HTTP權威指南 (豆瓣): https://book.douban.com/subje...
Http協議構成了當今互聯網的基石,不管是瀏覽網頁仍是使用APP都離不開這個協議,很是有必要進行全面的瞭解。這本書也是一個權威指南,看完就能有一個完整的概念了,並且本書還講到了許多架構方面的經驗,只賺不賠哈哈。
亮點:
- URI 統一資源標識符,在世界範圍惟一標誌並定位一個信息資源,包含URL和URN;URL 統一資源定位符,描述一臺特定服務器上的某特定資源的位置;URN 統一資源名稱,做爲特定內容的惟一名稱而與資源所在地無關(因此資源能夠遷移到另外一處而不影響其訪問,URL就不行)。如今幾乎全部URI都是URL,URN因爲架構的缺少(雖然引入了PURL)和巨大的工程變更仍處於試驗階段並未普遍使用
- HTTP延時通常都是由TCP延時形成的(除非是客戶端、服務端超載或者處理複雜的動態資源),若是要編寫高性能HTTP程序就要考慮許多的TCP層面的問題與解決方案:TCP握手產生的延時對於傳輸少許的http報文而言是巨大的開銷(複用已有TCP鏈接);延遲確認算法不太適用於HTTP這種雙峯特徵的請求響應式行爲(調整或禁用這個算法);慢啓動影響新的Http鏈接的傳輸速度(複用鏈接,持久鏈接);Nagle算法影響小的Http報文傳輸(能夠禁用該算法,TCP_NODELAY);TIME_WAIT累計與端口耗盡,TIME_WAIT狀態會持續2MSL(如120s)的時間纔會轉換到CLOSE狀態,而後才能建立相同IP和端口的鏈接(服務器端口有限,如60000個),限制了服務器的鏈接速率(60000/120=500次每秒),能夠增長客戶端負載生成器的數量或者虛擬IP
- 減小Http鏈接延時的方法:並行鏈接(並行執行多個Http事務),管道化鏈接(經過共享的TCP鏈接發起請求),複用鏈接(交替傳送請求與響應報文),持久鏈接(因爲站點本地性,http事務結束後沒必要立刻釋放TCP鏈接,由於頗有可能立刻又要向該站點發起請求)。其中持久鏈接與並行鏈接搭配多是最高效的方式
- web代理鏈接的是兩個使用相同協議的應用,而網關鏈接的是兩個或多個使用不一樣協議的端點。因此web代理扮演的是中間人傳輸者的角色(改善安全性、提升性能,好比完成訪問控制、防火牆、匿名者、緩存、反向代理負載均衡、內容路由器、轉碼器等等),網關扮演的是協議轉換器的角色(好比PHP-FPM能把Nginx轉發的http請求解析出來而後調用php-cgi來注入參數並執行PHP代碼獲得結果真後封裝爲http協議回覆給nginx)
- 大規模web爬蟲對其訪問管理(避免重複)用到了一些技術:樹和散列表(加速查找)、有損的位圖(url映射成數字,url無限數字有線因此可能有衝突)、檢查點(已訪問URL存入本地)、分類(集羣爬蟲經過通信來分配URL,各自爬取部分)、規範化URL、廣度優先爬取、節流、限制url大小、黑名單、內容指紋、人工監視等等
- 內容協商技術能夠使得服務器把內容的不一樣版本發送給對應的用戶,主要有3種機制:客戶端驅動、服務器驅動、透明。
- 重定向廣泛存在,緣由無非:可靠的執行Http事務(備用節點)、最小化時延(就近訪問)、節約網絡帶寬(服務器分散,減小擁塞)。用到的主要技術有:Http重定向、DNS重定向、任播尋址、IP MAC轉發、IP地址轉發、顯示瀏覽器配置、代理自動配置、web Proxy代理自動發現等等
這本書詳細描述了HTTP協議的方方面面,並且給出了許多參考,若是咱們真的要作一個完美的Http應用,仍是值得咱們細細翻閱的。
閱讀原文