後端好書閱讀與推薦(續三)

後端好書閱讀與推薦系列文章:
後端好書閱讀與推薦
後端好書閱讀與推薦(續)
後端好書閱讀與推薦(續二)
後端好書閱讀與推薦(續三)html

這裏依然記錄一下每本書的亮點與本身讀書心得和體會,分享並求拍磚。java

實戰Java高併發程序設計

實戰Java高併發程序設計 (豆瓣) https://book.douban.com/subje...linux

這本書是國產書籍裏面質量較高的一本了(不少國產書都是東拼西湊或者敷衍了事),做者從實際出發,結合理論,講的頗有邏輯,並且還有不少形象的手繪,和那本Java併發編程實戰相比更新一些,讀起來也更容易一些。nginx

亮點:git

  • 並行不必定是從性能角度考慮,有的時候是天然而然的,好比獨立的任務分爲不一樣的線程更易於理解
  • 同步異步,阻塞非阻塞,並行併發,這幾個概念估計不少人都混亂了好久,和做者的觀點稍微有點出入,我這裏總結一下:同步異步的區別關鍵在於A對B請求發出後,若是A要等待B的結果那就是同步,若是A直接返回不須要B的結果或者等待B完成後再通知就是異步;阻塞強調的是A請求B事後不能作其它事,只能乾等着(自旋或者休眠),非阻塞指的是A在等B的過程當中能夠作其它事;並行是真正意義的的多個任務同時執行,併發多是並行,也可能只是多個任務交替執行,可是切換的很快,給咱們形成了並行的「假象」,真實的並行只可能出如今多核cpu上
  • 死鎖:是指兩個或兩個以上的或線程在執行過程當中,因爭奪資源而互相等待,都阻塞起來;活鎖:是指線程A可使用資源,但它讓其餘線程先使用資源,線程B也可使用資源,但它也讓其餘線程先使用資源。這樣線程雖然是活躍的,可是啥事也作不了;飢餓:是指若是線程T1佔用了資源R,線程T2又請求R,因而T2等待。T3也請求資源R,當T1釋放了R上的封鎖後,系統首先批准了T3的請求,T2仍然等待。而後T4又請求封鎖R,當T3釋放了R上的封鎖以後,系統又批准了T4的請求...T2一直等待。
  • 並行對於效率的提高主要取決於業務中串行代碼的比例和CPU數量,CPU數量越多,串行化代碼比例越少,那麼多線程的優化方式效果越好
  • JMM關注原子性(某個操做不能被中斷),可見性(一個線程對某變量的修改對另外一個線程立馬可見),有序性(CPU爲了性能可能指令重排,應用happen-before原則,能保證串行語義一致可是不必定保證多線程之間語義也一致)
  • 類能夠經過繼承Thread,重寫run方法來實現多線程,但考慮到Java是單繼承的,繼承是一種很寶貴的資源,因此類應該實現Runable接口並重寫run方法,並把本身做爲構造參數傳給Thread類來實現多線程,這種作法也符合Effective Java裏面提到的工做單元(Runable)與執行機制(Thread)分離的概念
  • 加鎖必定要注意加正確,主要有三種:指定加鎖對象,得到該對象的鎖才能進入同步區;做用於實例方法,鎖加在當前實例上;做用於靜態方法,鎖加在當前類上。並且要注意多線程的鎖必定要是真正的加在同一個對象上,好比程序員

    Integer i;
       synchronized(i){
           i++;
       }

    就不正確,由於 Integer 是不變類,在執行++運算的時候 其實是建立了新類,因此那個同步塊實際上指向了不一樣的對象,天然不會正確 。事實上這段代碼 在 IDEA 裏面他會提示你 synchronized 加在了非final變量上,均可能產生非預期結果。github

  • java 內置的線程池很是強大:newSingleThreadExecutor,newFixedThreadPool,newCachedThreadPool,newScheduledThreadPool等等,其核心都是ThreadPoolExecutor實現的,不過是參數不一樣。而ThreadPoolExecutor又是能夠高度定製的,threadFactory,handler 均可以自定義,實現本身的線程工廠,拒絕策略等。ThreadPoolExecutor能夠擴展來實現更豐富的功能,例如監聽全部任務的開始結束時間,避免線程池「吃掉異常」。
  • 做者研究了ConcurrentLinkedQueue的源碼,發現不用鎖而是用CAS來實現多線程安全,代碼複雜度高了不少,可是性能卻高了不少;其實凡事有得必有失,就像Node同樣,異步帶來的性能提高是巨大的,可是代碼的編寫難度也提高了不少。此外做者還分析了java.util.concurrent裏面其餘的大量的數據結構,如CopyOnWriteArrayList,BlockingQueue,SkipList。這些數據結構都是Java設計者們精心設計的多線程安全數據結構,比傳統的多線程安全數據結構性能提高不少
  • 提升鎖性能:減少鎖持有時間,亦即只在必要的時候加鎖;減少鎖粒度,亦即縮小加鎖範圍,好比ConcurrentHashMap不對整個對象加鎖而是一段;讀寫分離鎖(ReentrantReadWriteLock)替換獨佔鎖;讀寫鎖的擴展,亦即按照功能分離不一樣功能的鎖,使用多個ReentrantLock 來表達不一樣條件的鎖,使之不互相影響,LinkedBlockingQueue就採用了這種思想;鎖粗化,若是鎖不停地獲取釋放反而浪費資源,因此把全部的鎖整合成一個鎖來提升性能,好比虛擬機就會實現這種操做。按我理解,若是鎖裏面的操做耗時,那麼就要細化,給其餘線程機會,提升吞吐量,反之就應該粗化,讓本身早點執行完畢。
  • 做者總結了一系列多線程相關的設計模式,好比單例模式、不變模式、生產者消費者、介紹了用框架實現的無鎖生產者消費者、future模式實現的異步操做、並行流水線和搜索排序計算等等,這些都是咱們業務中經常用到的模式,總結一下,之後運用更加自如

爲了體會到本書的點,我寫了一些代碼。另外AKKA部分我沒有看,由於沒有用過,即便看了也體會不到精髓,因此暫時先不瞭解了。web

計算機網絡(第5版)

計算機網絡(第5版) (豆瓣) https://book.douban.com/subje...docker

這本書當年大二的時候是教材,沒意識到它的珍貴,本科畢業的時候竟然拿去賣了,不事後來我又買了回來,好好的讀下來,感受對整個計算機網絡都有了一個更清晰地概念。固然此書太厚,若非必要,不宜一一細讀,挑些重要的基礎概念(好比TCP/IP)和現在愈來愈重要的內容(好比CDN)細讀,其他看個大概便可。數據庫

亮點:

  • 首先講了計算機網絡的重要性(郵件,電子商務,web,在線娛樂遊戲,GPS)以及廣闊前景(IOT的萬物互聯,可穿戴計算機),事實上如今的人早就習慣了網絡的存在,反而不以爲它有那麼重要,就像空氣同樣,可是一旦你把它的做用列出來你就會發現,它是如此的重要,試着想一想,若是沒有網絡,現代社會怎麼運轉?
  • 爲了下降網絡設計的複雜性,絕大多數網絡都組織成一個層次棧,每一層都構建於其下一層之上。這種分層的概念在計算機科學中普遍存在,好比面向對象、ADT、信息隱藏等,其根本思想都是提供服務可是隱藏實現。這種分而治之的思想可被咱們借鑑,用來簡化架構,邏輯解耦。好比 nginx 處理請求也是分了不一樣的階段,Java 裏面的 servlet 也是同樣分階段處理的
  • 數據鏈路層只關注幀(frame)從一個節點到另外一個節點的傳輸,是點到點的,而網絡層的目的是採用數據報或者虛電路技術將數據包(package)從發送方傳輸至接收方,中間可能要通過不少點,是處理端到端數據傳輸的最底層,但仍然是點到點的(由於它必須關心發送方到接收方的中間節點),而傳輸層是真正的端到端,亦即發送接收方沒必要關心傳輸過程當中有多少個節點,能夠認爲數據段(segment)是直接從發送方到接收方的。從另外一方面來看,一個數據報在傳輸過程當中,源/目的IP是不變的(除非NAT),可是源/目的MAC倒是一跳一跳地變化的
  • 擁塞控制和流量控制有很大差別。前者指確保網絡可以承載全部到達的流量,是一個全局問題;後者指發送方不會持續以超過接收方能力的速率傳輸數據,解決這兩個問題的最佳解法一般都是主機慢下來
  • 網絡層與傳輸層提供的服務有些相似,那麼爲何不用一層作完呢?答案就是傳輸層代碼主要運行在用戶主機上,網絡層主要運行在運營商的路由器上,對於網絡層,用戶本身有着真正的控制權,能夠經過差錯控制、順序控制、流量控制等方式來得到比網絡層(盡力而爲的服務,無保證)更加可靠的服務;另外一個方面,分層也是解耦的思想體現,只要實現了傳輸原語,就沒必要在意網絡層的實現(以太網或者WiMAX)
  • 簡單狀況下,我發一包,你回一包,可是網絡不佳的狀況下,要保證包傳輸到位就必須引入重傳機制,重傳機制一引入就必須考慮如何解決包重複接受的問題,因此限制了包生存週期(跳計數器),而後經過段序號、日時鐘、滑動窗口協議來丟棄已經接受的重複數據包,經過三步握手解決了初始序號得到的問題。這一個出現問題、解決問題、出現新問題、解決新問題的反覆的過程體現了協議設計者們的智慧和不屈不撓的毅力,很是值得咱們學習
  • 由「兩軍對壘」問題引出釋放鏈接的問題,不管怎麼確認通訊,也沒法百分之百保證對方收到的消息,兩次、三次、四次握手其實都是可行的(不必定是無誤的),事實上釋放鏈接的四步揮手徹底就是「兩軍對壘」的一個折中方案,既保證了準確率,又避免了帶寬浪費。創建鏈接的三次握手也一樣是一種折中
  • 內容分發不一樣於通訊任務,目標主機不重要,重要的是獲取了什麼內容,獲取內容的代價。主要有兩個結構,CDN和P2P。CDN採用分發樹結構,擴展性很高,實現原理是DNS重定向;P2P把多臺計算機(對等節點)的資源集中起來,每臺計算機既能夠做爲服務器向其餘計算機提供資源,也能夠做爲客戶端向其餘計算機請求資源

本文最大特色就是故事性強,一環扣一環,引人入勝。

Netty實戰

Netty實戰 (豆瓣) https://book.douban.com/subje...

Netty是網絡編程中不可不談的一個大做,也是許多成功的網絡應用的基礎設施,本書就從爲何是Netty,引導咱們嘗試使用,並進行了細緻的講解,爲咱們全面的剖析了Netyy這個龐大而精妙的框架,組織得頗有條理。

可是要注意,看本書以前或者說學習Netty以前,務必要對Java IO、NIO、AIO以及Reactor和Proactor的概念有必定的瞭解,否則就是沒學會走先去學跑了。

亮點:

  • 低級別的 API 不只暴露了高級別直接使用的複雜性,並且引入了過度依賴於這項技術所形成的短板。所以,面向對象有一個基本原則:經過抽象來隱藏背後的複雜性。Netty提供了高層次的抽象來簡化TCP和UDP服務器的編程,可是你仍然可使用底層地API。(David John Wheeler有一句名言「計算機科學中的任何問題均可以經過加上一層邏輯層來解決」,這個原則在計算機各技術領域被普遍應用)
  • 一個 Netty 的設計的主要目標是促進「關注點分離」:將你的業務邏輯從網絡基礎設施應用程序中分離
  • Netty組件說明:BOOTSTRAP啓動應用,配置,爲應用提供一個容器;Channel是一條通訊信道,相似於socket;ChannelHandler是數據處理的容器,也是咱們要寫業務邏輯的地方,也是咱們一般關注最多的地方;ChannelPipeline屬於一個Channel,是ChannelHandler鏈的容器;EventLoop 用於處理 Channel 的 I/O 操做,一個單一的 EventLoop一般會處理多個 Channel事件,一個 EventLoopGroup 能夠含有多於一個的 EventLoop;ChannelFuture 的 addListener 方法註冊了一個 ChannelFutureListener ,當操做完成時,能夠被通知(無論成功與否)。可見,Netty的組件劃分真的很細緻精小,優勢就是模塊間易於解耦,模塊自己可重用性高,可是也就有點囉嗦,這也是Java自己比較受到詬病的緣由,仍是那句話,凡事有得必有失嘛,它的優勢能讓你忍受它的缺點就好了
  • Transport 使用情景:OIO(即老的,最原始的阻塞IO)-在低鏈接數、須要低延遲時、阻塞時使用;NIO-在高鏈接數時使用;Local-在同一個JVM內通訊時使用;Embedded-測試ChannelHandler時使用
  • Netty提出的ByteBuf優於JDK原生的ByteBuffer由於:能夠自定義緩衝類型(堆緩衝區,直接緩衝區,複合緩衝區),經過複合緩衝類型實現零拷貝;擴展性好,好比 StringBuilder;不須要調用 flip() 來切換讀/寫模式;讀取和寫入索引分開
  • 直接緩衝區」是另外一個 ByteBuf 模式,容許 JVM 經過本地方法調用分配內存,優勢:經過免去 socket 發送數據以前,JVM 先將數據從用戶區複製到內核區, 提高IO處理速度, 直接緩衝區的內容能夠駐留在垃圾回收掃描的堆區之外;DirectBuffer 在 -XX:MaxDirectMemorySize=xxM大小限制下, 使用 Heap 以外的內存, GC對此」無能爲力」,也就意味着規避了在高負載下頻繁的GC過程對應用線程的中斷影響
  • Netty 的使用一個包含 EventLoop 的 EventLoopGroup 爲 Channel 的 I/O 和事件服務。EventLoop 建立並分配方式不一樣基於傳輸的實現。異步實現使用只有少數 EventLoop(和Threads)共享於 Channel 之間 。這容許最小線程數服務多個 Channel,不須要爲他們每一個Channel都有一個專門的 Thread

本書中對於異步同步和阻塞非阻塞的觀念有些模糊,請見上面實戰Java高併發程序設計一節個人理解,讀者能夠參考一下,本身取捨。事實上,Java的NIO不是異步的,AIO(或者說NIO2.0)纔是,Netty基於NIO(嘗試過並拋棄了AIO),經過本身的封裝,實現了從使用者角度看起來的異步。學習Netty還有一個好地方就是官方文檔

分佈式java應用

分佈式java應用 (豆瓣) https://book.douban.com/subje...

後端要搞得好,不上分佈式確定是不行的,由於寫個小網站你能夠懂點 SSM 或者 Spring Boot 就好了,可是若是要想搭建一個(或者說成爲構建過程的一份子)用戶成千上萬甚至百萬、千萬、上億的站點,那就必需要懂分佈式了。這本書就能夠當作學習分佈式的入門書籍。

亮點:

  • 實踐是最好的成長,發表是最好的記憶。這句話的確能夠放在電腦上當桌面背景
  • 分佈式系統通訊底層都依賴於TCP、UDP,可是爲了易用性,一般會使用一些更貼近應用層的協議,書中提到了原始的jdk通訊,以及webservice,Mina,實際上還有許多,好比RPC、WebService、RMI、JMS(p2p或者發佈訂閱)、JNDI等等
  • 網絡IO分三類。BIO:用戶線程在進行IO操做的時候進行系統調用,阻塞,只有讀到(寫入)了數據才釋放資源;NIO:同步非阻塞IO,用戶線程在發起IO操做以後能夠當即返回,只有流可讀(可寫)操做系統纔會通知用戶線程進行讀取(寫入),可是用戶線程須要不斷輪詢來請求數據,Linux採用epoll實現;AIO:用戶線程發起請求時,由操做系統來進行讀取(寫入),IO事件就緒的時候,操做系統會通知對應的用戶線程來處理,實現真正的異步IO,Windows下IOCP實現了AIO,Linux只有epoll實現模擬實現的AIO。同時,因爲服務器的主力是Linux,因此AIO的用處目前不是特別廣
  • BIO對應的是一鏈接一線程,能夠引入線程池來優化,可是一個操做系統線程數量終究有限,因此不可能支撐大量鏈接數;NIO對應的是一請求一線程,只有某個鏈接有讀寫事件時才爲其生成一個線程來處理,只有連接數很少或者鏈接數多且都請求頻繁時纔沒有優點,但實際狀況中,服務器一般會支持大量鏈接數,可是同時發送請求的鏈接不會太多,因此NIO應用比價普遍;AIO對應一個有效請求一個線程,亦即OS處理IO完畢後再生成用戶線程處理,充分調用了OS參與,能夠應對鏈接數多且操做頻繁的場景,若是Linux對AIO的支持更好,這個模型可能會流行起來
  • SOA亦即面向服務的架構,強調系統之間以標準服務的方式進行交互,各系統能夠採用不一樣的語言、框架來實現,交互則所有采用服務來進行,目前SCA和ESB是主流標準,分別有Tuscany和Mule等經常使用框架實現
  • 調優的步驟:衡量系統現狀,設定調優目標,尋找性能瓶頸,性能調優,衡量是否達標,反覆進行前面三步直至達標。
  • 之前我對負載均衡的理解仍是停留在引入一個(羣)中間節點做爲調度者,調度者(硬件或軟件)接受請求並轉發給實際應用服務器。這實際上叫作中心化負載均衡,書中提到Gossip實現了無中間節點的軟件負載均衡其實是一種去中心化傳播事件的負載均衡,去掉中心節點後請求響應直接進行加快了速度,並且能避免調度者單點故障問題。最高級別的負載均衡是全局負載均衡,實現不一樣地域機房的負載均衡,既能夠避免單點故障還能夠就近響應,提升訪問速度,實現高可用,通常由硬件GSLB實現(在合肥 ping 了一下 qq.com 獲得的結果是深圳的,在天津獲得的結果就是北京的,雖然不必定,可是看得出來有差異),可是多機房的一致性很難保證,一般都要用消息中間件來實現
  • 除了上面提到的機房等硬件上的故障,應用軟件自己的故障也是高可用的大敵,因此要注意避免故障,及時發現並處理故障,具體包括:明確使用場景,作到最貼近場景的最簡單系統,或者分階段最簡單系統;設計可容錯系統,fail fast;系統可自我保護,對第三方依賴保持弱依賴,避免連鎖失效;創建分級報警系統和日誌記錄與分析系統;注意總結故障分析便於下次快速利用,這也是架構即將來裏面提到過的;按照業務拆分子系統......
  • 構建可伸縮的系統關鍵在於水平伸縮,由於垂直伸縮是有限的(一臺機器的性能終究有限),而水平伸縮理論上是無限的(能夠添加「無數」臺機器),水平伸縮一般經過SNA(share nothing architecture)實現,亦即應用系統之間不共享狀態,把狀態信息統一放入緩存或數據庫(能夠是分佈式)。文件系統的水平擴展思想也是相似的

本書能夠當作入門書籍,可是書中真正關於分佈式的內容彷佛少了些,卻是Java基礎知識佔據了很大篇幅,感受有點不對題目,畢竟要看這些知識我能夠看Java核心技術,Java併發編程實戰或者深刻理解jvm啊,可是也能夠用來複習一下,並且有許多實驗數據可供參考,仍是能夠的。

PS:我以前已經看了Netty了,因此書中關於Mina的部分,時間不夠我就跳着看了,時間夠仍是能夠了解一下的,二者對比

分佈式系統 概念與設計

分佈式系統 原書第5版 (豆瓣) https://book.douban.com/subje...

讀了上面一本分佈式Java,難免對分佈式系統想要有一個更全面、更系統的認識,那麼這本書就是一本絕佳的書籍。

亮點:

  • 資源共享是構建分佈式系統的主要目;併發、缺少全局時鐘、故障獨立性是其主要特徵;處理其構件的異構性、開放性(容許增長或替換組件)、安全性(機密完整可用)、可伸縮性(用戶的負載增長時能正常運行的能力)、故障處理、組件併發性、透明性(分佈式的組件對外展現爲一個總體)、QoS(在傳輸數據時知足要求的能力)等是其主要挑戰
  • 不管是 請求-應答(好比http) 仍是 RPC 或者 RMI(相似於RPC可是僅限於Java且支持對象概念),收發雙發都是雙向的(直接通訊),要想解耦收發雙方(空間解耦和時間解耦),那麼就得用間接通訊:組通訊(廣播),發佈訂閱系統,消息隊列,元組空間(生成通訊),分佈式共享內存等方式
  • 中間件是一組計算機上的進程或對象,其目的是屏蔽異構性,亦即底層的通信,交互,鏈接等複雜又通用的功能以服務的形式提供出來,分佈式系統應用在交互時,直接使用中間件提供的高層編程抽象便可,實現了簡潔的分佈式系統應用的通訊和資源共享的支持
  • 套接字(socket)是通訊的抽象,不管是TCP仍是UDP的方式,它提供了進程間通訊的端點,必須和協議,主機地址(分爲目的端與源端),端口(分爲目的端與源端)綁定起來
  • RPC的概念表明着分佈式計算的重大突破,使得分佈式編程和傳統編程相似,實現了高級的透明性,這種類似性將傳統的過程調用模型擴展到分佈式環境中,隱藏了底層分佈式環境的重要細節部分,簡化了分佈式開發
  • 操做系統的任務是提供一個物理層(處理器,內存,硬盤等)之上的面向問題的抽象,例如給程序員提供文件和套接字而不是磁盤塊和原始網絡訪問。操做系統分爲網絡操做系統(具備內置聯網功能,能自主管理本身的資源併網絡透明地訪問其它一些資源可是不能跨節點管理進程,也就是有多個系統映像)和分佈式操做系統(用戶沒必要關心程序運行的地點和資源位置,能透明的將新的進程調度到合理的節點上,有單一的系統映像),後者幾乎沒有廣泛應用的案例,由於中間件和網絡操做系統的結合就能很好的知足用戶需求
  • 最重要的兩種中間件風格:分佈式對象(容許面向對象編程模型開發分佈式系統,通訊實體被表示成對象,通訊使用RMI,但也可使用其餘的好比分佈式事件);組件(基於對象方法的天然演化,主要克服其限制:隱式依賴,編程複雜性,缺乏關注點分離支持,無部署支持)
  • 面向服務的體系結構(SOA)是一套設計原則,分佈式系統用鬆耦合的服務集開發,服務能被動態發現,能互相通訊並經過編排進行協調從而提供更強的服務。能夠基於分佈式對象或者組件來實現,但實際中主要經過web服務實現,主要是由於web服務內在的鬆耦合性(好比無論子系統是CORBA仍是.NET,只要用web服務暴露接口,就能輕易實現集成)

分佈式是一門結合計算機網絡與操做系統等多種門類的交叉學科,因此這本書也包含了許多這些方面的知識,不失爲一種複習的方式。

大型網站系統與Java中間件開發實踐

大型網站系統與Java中間件開發實踐 (豆瓣) https://book.douban.com/subje...

上面的分佈式Java是一本很基礎的入門書籍,這本書算是一本更加全面和仔細的書籍,把它沒講到的部分都講了一些,並且更注重中間件(支撐大型網站關鍵、必要的技術之一)的講解。

亮點:

  • 分佈式系統中的控制節點協調系統之間的協做,能夠用:硬件均衡負載設備(昂貴)、軟件方式的透明代理(增長流量、易出現單點失效)、採用名稱服務的直連請求(不易單點失效、流量少)、採用規則服務器的直連調用、採用master+worker的架構
  • 從一個最基本、簡單、部署在單機上的網站開始,數據量和訪問量慢慢上去了,一步步演進:數據庫與應用分離到兩臺服務器;多應用服務器與單數據庫,涉及到session問題(sticky、replication、集中存儲、cookie Based);數據庫讀寫分離、引入搜索引擎、引入數據和頁面緩存;引入分佈式存儲系統;數據庫垂直拆分(一個業務的數據放到一個專用數據庫)、水平拆分(單個表放到兩個數據庫中);拆分應用,能夠根據業務特性把應用拆開或者走服務化的路,亦即每一個web系統經過不一樣的服務來完成特定的業務;引入消息中間件來完成拆分、服務化等目的
  • 大型網站主要用到三類中間件:遠過程調用和對象訪問中間件(解決分佈式下應用互相訪問的問題);消息中間件(解決應用之間消息傳遞、解耦、異步的問題);數據訪問中間件(解決數據庫訪問共性的問題);
  • 服務框架帶來的好處:結構上,架構更清晰,底層資源由服務層統一管理,也更利於提升效率;穩定性上,一些散落在多個系統中的代碼變成了服務,由專門的團隊統一維護,能夠提升代碼質量,另外一方面因爲核心穩定,修改發佈次數減小,也提升了穩定性
  • 經過消息中間件,業務系統沒必要知道有多少個其餘業務系統須要瞭解某一項業務,只須要把消息發佈給消息中間價,消息中間價負責把消息投遞給相關的其餘業務系統,這樣每一個業務系統都能專一本身自己的業務,沒必要維護臃腫的依賴關係,達到解耦和消息異步的目的
  • 消息中間件要點:保證業務與發佈消息的一致性,通常直接緊挨着寫代碼就行,出錯機率較小,可是對於要保證強一致的系統,須要採用相似於TCP三步握手的方式來保證;解決強依賴關係,儘可能保證中間件的可靠性,最好達到和業務系統自己可靠性相同,從業務數據上能對消息進行補發是最完全的容災手段;消息模型對消息接受的影響,Queue(點對點)和Topic(發佈/訂閱)都不能徹底適應集羣模式(發送接收方都是集羣,要作到不重不漏、互不干擾),解決方法是結合二者使用,集羣之間用Topic模型,集羣內部用Queue模型;作到持久訂閱(除非顯示取消訂閱,不然即便訂閱者宕機了重啓後也應該能收到全部消息)
  • 服務框架,數據訪問層,消息中間價背後的基礎產品就是軟負載和配置中心。軟負載中心的基本職責有兩個:聚合地址信息,將全部方面的地址造成列表供其餘方使用;生命週期感知,對服務的上下線自動感知並更新服務地址。軟負載中心管理非持久數據,集中配置管理中心管理持久數據
  • ESI將頁面分爲相對靜態的內容和動態的內容,若是整個頁面在服務端渲染的話,能夠將相對靜態的內容進行緩存,而不是每次都所有從新渲染
  • 在解決具體的問題的時候,徹底從頭寫代碼仍是基於開源代碼去發展必定要慎重思考,若是場景相似那麼以比較活躍的開源產品爲基礎並根據本身的場景定製會起到事半功倍的效果,若是沒有合適的那就須要從零開始了

京東基礎架構建設之路

京東基礎架構建設之路(全綵) (豆瓣) https://book.douban.com/subje...

本書主要做者是咱們學校的一位師兄,前不久來學校辦了個報告,主要講了他在京東的基礎架構經驗,介紹了新的架構從無到有的過程,他們團隊的技術如今一年能爲京東省了不少億,這本書裏凝聚了他們的技術精華,固然值得咱們去了解一下咯,並且當時的QA環節我提了個問題,主辦方就送了這本書,師兄當場親筆簽名,我就更應該把這本書好好研究研究了。

亮點:

  • 跳過虛擬化,直接容器化,結合團隊的OpenStack經驗,選擇OpenStack+Docker的架構,用OpenStack來管理調度Docker容器
  • 建議鏡像和根目錄只保留只讀或者少許讀寫文件,對於頻繁的讀寫或者大量寫的文件儘可能用外掛的volume,規範業務對容器的使用行爲
  • MySQL運維自動化包括:自動備份,包括按時間點精準恢復;自動歷史數據轉移,將再也不變動的歷史數據按期轉入大容量分佈式存儲系統(如HBASE),控制MySQL數據量;自動故障檢測與切換,採用Orchestrator做爲管理工具;全面容器化,提高MySQL實例交付效率
  • 在故障檢測和故障切換的方案中,比較容易想到的就是ZooKeeper的臨時節點探測不存活的服務,可是因爲須要修改服務端代碼,不便於跨機房部署和鏈接數過多的問題,京東本身開發了分佈式探測系統,爲了不臨時網絡不通致使的誤判,採起多個探測程序部署到機房的不通機架裏,對實例進行分佈式投票,只要有一個探測存活就判斷爲存活的,不然通知故障恢復程序進行主從切換
  • 容器中的數據最原始的是直接使用物理機上的volume來存儲,可是這樣容器數據就和物理機綁定了,沒法實現數據的遷移也沒法作到超大容量的存儲。京東的ContainerFS就是爲容器而生的分佈式文件系統,它的每一個volume均可以被一個或者多個容器當作本地文件直接使用,容器之間能夠共享數據,支持彈性伸縮、線性擴展
  • JMQ因爲要支撐訂單、支付等要求對服務質量要求極其嚴格的業務,因此必須保證在整個機房都失效的狀況下依然能恢復數據,因此採起了一主一從且至少一個備份的架構。主從分佈在同一個數據中心,採起同步複製;備份在另外一個數據中心,採起異步複製
  • 分佈式服務跟蹤系統CallGraph經過核心的調用鏈(依靠全局惟一的ID實現)的概念能追蹤到一次調用的從請求發出到最底層系統的全部環節,便於排查問題,並且具備低侵入性
  • 全鏈路壓測經過全國各個公網節點發來的數據請求來較好地模擬真實用戶操做,同時壓測會有參數標識,進行真實流量與測試流量的隔離,避免污染生產數據
  • 大型互聯網公司的數據中心架構通常都會經歷單機房,同城雙機房,異地災備,最後是異地多活的各個階段。京東目前有三大數據中心,每一箇中心都能承擔讀寫業務(這就是異地多活),依據GLSB和HTTPDNS和全國網絡質量檢測數據來動態優化用戶到某個具體中心得到服務,中心之間用專線打通保證數據秒級同步提供低延遲數據最終一致性保障

本書雖然很薄,可是講述的知識日常咱們可能都用不到(不是誰都有機會接觸這麼大的規模的集羣管理),看的時候要想徹底吸取仍是有些費勁,還得在之後的實踐中加以琢磨才行。

Docker進階與實戰

Docker進階與實戰 (豆瓣) https://book.douban.com/subje...

第一本docker書 爲咱們入門docker提供了很好的途徑,這本書爲咱們提供了深刻了解整個docker技術棧所須要的更多的知識,好比關鍵技術原理,高級技巧如安全、測試、集羣管理等等。這兩本書有重疊,可是後者對前者有許多的補充,利於咱們更好的使用、更好的理解docker。

亮點:

  • Docker並無傳統虛擬化中的Hypervisor層,使用輕量級虛擬化技術,基於Cgroup和Namespace等內核容器技術,與內核深度融合,性能與物理機很是接近。通訊上,Docker不與內核直接通訊,而是經過LibContainer。libContainer是真正意義上的容器引擎,經過clone系統調用直接建立容器(一個新的子進程),經過pivot_root進入容器(新的rootfs),經過cgroupfs控制資源,Docker自己更側重處理更上層的業務。
  • Docker主要工做是在LXC(linuxContainer亦即linux內核容器技術)的基礎上提供了一些更高級的控制工具,包括:定義鏡像格式,包含全部程序和依賴,使得鏡像能夠跨主機部署,實現了進程沙盒,同時保證程序及其依賴環境的一致性;提供自動構建工具,使得當前機器的配置不會影響鏡像構建過程;提供了相似git的版本管理功能,支持鏡像版本追蹤、校驗、回退等功能;經過鏡像分層實現組件重用,減少鏡像大小,加快構建速度;工具生態鏈......
  • 虛擬機是硬件級別的虛擬化,利用VT-x、AMD-V等硬件虛擬化技術經過Hypervisor來實現對資源的完全隔離;容器是操做系統級別的虛擬化,利用內核的Cgroup和Namespace等軟件實現的特性實現來實現進程隔離,Docker容器與主機共享操做系統內核,不一樣容器能夠共享部分資源,所以容器更加輕量級,資源消耗更少,啓動更快。而虛擬機獨佔本身的資源,各個虛擬機幾乎徹底獨立,不存在共享,消耗更多資源,啓動也慢
  • 容器技術是一種操做系統級別的虛擬化技術(還有硬件虛擬化、半虛擬化等技術),已經集成進linux內核,是內核提供的原生特性,主要包含Namespace(主要作訪問隔離,針對一類資源進行抽象,並將其封裝在一塊兒供容器使用)和Cgroup(control group,主要作資源控制,將一組進程放進一個控制組,給這個控制組分配指定可用的資源,其原生接口由cgroupfs提供)。可是光有這兩個還不夠,還須要rootfs(文件系統隔離)和容器引擎(生命週期控制)
  • Docker引入聯合掛載技術(把多個目錄掛載到同一目錄,對外呈現這些目錄的聯合)使得鏡像分層成爲可能,使用git式的管理方式使得基礎鏡像的重用成爲可能
  • 若是你在尋找一個清晰、簡單、低耦合、無狀態、面向資源的API設計方式,那麼RESTFul API就是一種不錯的選擇,它充分利用了HTTP自己的語義,使你的API更易用更具備擴展性,同時優雅的展現你的資源。Docker API 就是一種 RESTFul API
  • Cgroup對系統資源的限制已經比較完善了,可是Namespace的隔離還不算很好,好比procfs的不少接口都沒隔離,能夠經過procfs能夠讀取和修改宿主系統的相關信息,因此procfs是以只讀方式掛載的,還有syslog也是沒隔離的。Namespace的隔離不完善,也不太可能完善,這是共享內核固有的缺陷。有許多安全策略被用來保護系統,好比Cgroup限制、容器運行在虛擬機中、鏡像簽名、日誌審計、監控、文件保護
  • 在製做鏡像的時候,源碼導入有兩種策略:靜態導入(使用COPY命令直接把代碼放入鏡像);動態導入(使用VOLUME命令把代碼文件動態掛載到容器)。建議使用兩個dockerfile,一個開發版本(dev)用動態掛載,便於隨時修改代碼,一個發佈版本用靜態導入,便於減小依賴、到處運行
  • 做者還講述了怎麼參與到docker的開發和維護的過程當中,若是咱們在使用過程當中趕上了問題,去看看源碼和社區也是不錯的,說不定就能解決

雖然只過去了1年多,可是書中已經有內容過期了,好比不要再安裝 docker.io 或者 docker-engine ,而是使用docker-ce (免費版)或者 ee (企業版)。並且,現在 Docker-Compose、Swarm 已經比較成熟了,徹底能夠用在生產環境中,固然,(超)大規模的部署最終都得按照本身的業務狀況來造輪子,徹底依靠開源的確定是不行的,這樣是上面那本書的做者提到過的觀點。

相關文章
相關標籤/搜索