前言
歡迎工作一到五年的Java工程師朋友們加入我們,私信回復【資料】即可獲取我們提供免費的Java架構學習資料(里面有高可用、高并發、高性能及分布式、Jvm性能調優、Spring源碼,
MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)
java二分法查找代碼?合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!
數據結構
隊列
- 《java隊列——queue詳細分析》
- 非阻塞隊列:ConcurrentLinkedQueue(無界線程安全),采用CAS機制(compareAndSwapObject原子操作)。
- 阻塞隊列:ArrayBlockingQueue(有界)、LinkedBlockingQueue(無界)、DelayQueue、PriorityBlockingQueue,采用鎖機制;使用 ReentrantLock 鎖。
- 《LinkedList、ConcurrentLinkedQueue、LinkedBlockingQueue對比分析》
集合
java心得體會,鏈表、數組
字典、關聯數組
- 《Java map 詳解 - 用法、遍歷、排序、常用API等》
棧
- 《java數據結構與算法之棧(Stack)設計與實現》
- 《Java Stack 類》
- 《java stack的詳細實現分析》
- Stack 是線程安全的。
- 內部使用數組保存數據,不夠時翻倍。
java中main方法的兩種定義、樹
二叉樹
每個節點最多有兩個葉子節點。
java表示一個范圍、完全二叉樹
- 《完全二叉樹》
- 葉節點只能出現在最下層和次下層,并且最下面一層的結點都集中在該層最左邊的若干位置的二叉樹。
平衡二叉樹
左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。
- 《淺談數據結構-平衡二叉樹》
- 《淺談算法和數據結構: 八 平衡查找樹之2-3樹》
二叉查找樹(BST)
二叉查找樹(Binary Search Tree),也稱有序二叉樹(ordered binary tree),排序二叉樹(sorted binary tree)。
紅黑樹
- 《最容易懂得紅黑樹》
- 添加階段后,左旋或者右旋從而再次達到平衡。
- 《淺談算法和數據結構: 九 平衡查找樹之紅黑樹》
B,B+,B*樹
MySQL是基于B+樹聚集索引組織表
- 《B-樹,B+樹,B*樹詳解》
- 《B-樹,B+樹與B*樹的優缺點比較》
- B+樹的葉子節點鏈表結構相比于 B-樹便于掃庫,和范圍檢索。
LSM 樹
LSM(Log-Structured Merge-Trees)和 B+ 樹相比,是犧牲了部分讀的性能來換取寫的性能(通過批量寫入),實現讀寫之間的。 Hbase、LevelDB、Tair(Long DB)、nessDB 采用 LSM 樹的結構。LSM可以快速建立索引。
- 《LSM樹 VS B+樹》
- B+ 樹讀性能好,但由于需要有序結構,當key比較分散時,磁盤尋道頻繁,造成寫性能。
- LSM 是將一個大樹拆分成N棵小樹,先寫到內存(無尋道問題,性能高),在內存中構建一顆有序小樹(有序樹),隨著小樹越來越大,內存的小樹會flush到磁盤上。當讀時,由于不知道數據在哪棵小樹上,因此必須遍歷(二分查找)所有的小樹,但在每顆小樹內部數據是有序的。
- 《LSM樹(Log-Structured Merge Tree)存儲引擎》
- 極端的說,基于LSM樹實現的HBase的寫性能比MySQL高了一個數量級,讀性能低了一個數量級。
- 優化方式:Bloom filter 替代二分查找;compact 小數位大樹,提高查詢性能。
- Hbase 中,內存中達到一定閾值后,整體flush到磁盤上、形成一個文件(B+數),HDFS不支持update操作,所以Hbase做整體flush而不是merge update。flush到磁盤上的小樹,定期會合并成一個大樹。
BitSet
經常用于大規模數據的排重檢查。
- 《Java Bitset類》
- 《Java BitSet(位集)》
常用算法
排序、查找算法
選擇排序
- 《Java中的經典算法之選擇排序(SelectionSort)》
- 每一趟從待排序的記錄中選出最小的元素,順序放在已排好序的序列最后,直到全部記錄排序完畢。
冒泡排序
- 《冒泡排序的2種寫法》
- 相鄰元素前后交換、把最大的排到最后。
- 時間復雜度 O(n2)
插入排序
快速排序
- 《坐在馬桶上看算法:快速排序》
- 一側比另外一次都大或小。
歸并排序
- 《圖解排序算法(四)之歸并排序》
- 分而治之,分成小份排序,在合并(重建一個新空間進行復制)。
希爾排序
TODO
堆排序
- 《圖解排序算法(三)之堆排序》
- 排序過程就是構建最大堆的過程,最大堆:每個結點的值都大于或等于其左右孩子結點的值,堆頂元素是最大值。
計數排序
- 《計數排序和桶排序》
- 和桶排序過程比較像,差別在于桶的數量。
桶排序
- 《【啊哈!算法】最快最簡單的排序——桶排序》
- 《排序算法(三):計數排序與桶排序》
- 桶排序將[0,1)區間劃分為n個相同的大小的子區間,這些子區間被稱為桶。
- 每個桶單獨進行排序,然后再遍歷每個桶。
基數排序
按照個位、十位、百位、...依次來排。
二分查找
- 《二分查找(java實現)》
- 要求待查找的序列有序。
- 時間復雜度 O(logN)。
- 《java實現二分查找-兩種方式》
- while + 遞歸。
Java 中的排序工具
- 《Arrays.sort和Collections.sort實現原理解析》
- Collections.sort算法調用的是合并排序。
- Arrays.sort() 采用了2種排序算法 -- 基本類型數據使用快速排序法,對象數組使用歸并排序。
布隆過濾器
常用于大數據的排重,比如email,url 等。 核心原理:將每條數據通過計算產生一個指紋(一個字節或多個字節,但一定比原始數據要少很多),其中每一位都是通過隨機計算獲得,在將指紋映射到一個大的按位存儲的空間中。注意:會有一定的錯誤率。 優點:空間和時間效率都很高。 缺點:隨著存入的元素數量增加,誤算率隨之增加。
- 《布隆過濾器 -- 空間效率很高的數據結構》
- 《大量數據去重:Bitmap和布隆過濾器(Bloom Filter)》
- 《基于Redis的布隆過濾器的實現》
- 基于 Redis 的 Bitmap 數據結構。
- 《網絡爬蟲:URL去重策略之布隆過濾器(BloomFilter)的使用》
- 使用Java中的 BitSet 類 和 加權和hash算法。
字符串比較
KMP 算法
KMP:Knuth-Morris-Pratt算法(簡稱KMP) 核心原理是利用一個“部分匹配表”,跳過已經匹配過的元素。
深度優先、廣度優先
貪心算法
- 《算法:貪婪算法基礎》
- 《常見算法及問題場景——貪心算法》
回溯算法
剪枝算法
動態規劃
- 《詳解動態規劃——鄒博講動態規劃》
- 《動態規劃算法的個人理解》
樸素貝葉斯
- 《帶你搞懂樸素貝葉斯分類算法》
- P(B|A)=P(A|B)P(B)/P(A)
- 《貝葉斯推斷及其互聯網應用1》
- 《貝葉斯推斷及其互聯網應用2》
推薦算法
- 《推薦算法綜述》
- 《TOP 10 開源的推薦系統簡介》
最小生成樹算法
- 《算法導論--最小生成樹(Kruskal和Prim算法)》
最短路徑算法
并發
Java 并發
多線程
線程安全
一致性、事務
事務 ACID 特性
事務的隔離級別
- 未提交讀:一個事務可以讀取另一個未提交的數據,容易出現臟讀的情況。
- 讀提交:一個事務等另外一個事務提交之后才可以讀取數據,但會出現不可重復讀的情況(多次讀取的數據不一致),讀取過程中出現UPDATE操作,會多。(大多數數據庫默認級別是RC,比如SQL Server,Oracle),讀取的時候不可以修改。
- 可重復讀: 同一個事務里確保每次讀取的時候,獲得的是同樣的數據,但不保障原始數據被其他事務更新(幻讀),Mysql InnoDB 就是這個級別。
- 序列化:所有事物串行處理(犧牲了效率)
- 《理解事務的4種隔離級別》
- 數據庫事務的四大特性及事務隔離級別
- 《MySQL的InnoDB的幻讀問題 》
- 幻讀的例子非常清楚。
- 通過 SELECT ... FOR UPDATE 解決。
- 《一篇文章帶你讀懂MySQL和InnoDB》
- 圖解臟讀、不可重復讀、幻讀問題。
MVCC
- 《【mysql】關于innodb中MVCC的一些理解》
- innodb 中 MVCC 用在 Repeatable-Read 隔離級別。
- MVCC 會產生幻讀問題(更新時異常。)
- 《輕松理解MYSQL MVCC 實現機制》
- 通過隱藏版本列來實現 MVCC 控制,一列記錄創建時間、一列記錄刪除時間,這里的時間
- 每次只操作比當前版本小(或等于)的 行。
鎖
Java中的鎖和同步類
- 《Java中的鎖分類》
- 主要包括 synchronized、ReentrantLock、和 ReadWriteLock。
- 《Java并發之AQS詳解》
- 《Java中信號量 Semaphore》
- 有數量控制
- 申請用 acquire,申請不要則阻塞;釋放用 release。
- 《java開發中的Mutex vs Semaphore》
- 簡單的說 就是Mutex是排它的,只有一個可以獲取到資源, Semaphore也具有排它性,但可以定義多個可以獲取的資源的對象。
公平鎖 & 非公平鎖
公平鎖的作用就是嚴格按照線程啟動的順序來執行的,不允許其他線程插隊執行的;而非公平鎖是允許插隊的。
- 《公平鎖與非公平鎖》
- 默認情況下 ReentrantLock 和 synchronized 都是非公平鎖。ReentrantLock 可以設置成公平鎖。
悲觀鎖
悲觀鎖如果使用不當(鎖的條數過多),會引起服務大面積等待。推薦優先使用樂觀鎖+重試。
- 《【MySQL】悲觀鎖&樂觀鎖》
- 樂觀鎖的方式:版本號+重試方式
- 悲觀鎖:通過 select ... for update 進行行鎖(不可讀、不可寫,share 鎖可讀不可寫)。
- 《Mysql查詢語句使用select.. for update導致的數據庫死鎖分析》
- mysql的innodb存儲引擎實務鎖雖然是鎖行,但它內部是鎖索引的。
- 鎖相同數據的不同索引條件可能會引起死鎖。
- 《Mysql并發時經典常見的死鎖原因及解決方法》
樂觀鎖 & CAS
- 《樂觀鎖的一種實現方式——CAS》
- 和MySQL樂觀鎖方式相似,只不過是通過和原值進行比較。
ABA 問題
由于高并發,在CAS下,更新后可能此A非彼A。通過版本號可以解決,類似于上文Mysql 中提到的的樂觀鎖。
- 《Java CAS 和ABA問題》
- 《Java 中 ABA問題及避免》
- AtomicStampedReference 和 AtomicStampedReference。
CopyOnWrite容器
可以對CopyOnWrite容器進行并發的讀,而不需要加鎖。CopyOnWrite并發容器用于讀多寫少的并發場景。比如白名單,黑名單,商品類目的訪問和更新場景,不適合需要數據強一致性的場景。
- 《JAVA中寫時復制(Copy-On-Write)Map實現》
- 實現讀寫分離,讀取發生在原始數據上,寫入發生在副本上。
- 不用加鎖,通過最終一致實現一致性。
- 《聊聊并發-Java中的Copy-On-Write容器》
RingBuffer
- 《線程安全的無鎖RingBuffer的實現【一個讀線程,一個寫線程】》
可重入鎖 & 不可重入鎖
- 《可重入鎖和不可重入鎖》
- 通過簡單代碼舉例說明可重入鎖和不可重入鎖。
- 可重入鎖指同一個線程可以再次獲得之前已經獲得的鎖。
- 可重入鎖可以用戶避免死鎖。
- Java中的可重入鎖:synchronized 和 java.util.concurrent.locks.ReentrantLock
- 《ReenTrantLock可重入鎖(和synchronized的區別)總結》
- synchronized 使用方便,編譯器來加鎖,是非公平鎖。
- ReenTrantLock 使用靈活,鎖的公平性可以定制。
- 相同加鎖場景下,推薦使用 synchronized。
互斥鎖 & 共享鎖
互斥鎖:同時只能有一個線程獲得鎖。比如,ReentrantLock 是互斥鎖,ReadWriteLock 中的寫鎖是互斥鎖。 共享鎖:可以有多個線程同時或的鎖。比如,Semaphore、CountDownLatch 是共享鎖,ReadWriteLock 中的讀鎖是共享鎖。
死鎖
- 《“死鎖”四個必要條件的合理解釋》
- 互斥、持有、不可剝奪、環形等待。
- Java如何查看死鎖?
- JConsole 可以識別死鎖。
- java多線程系列:死鎖及檢測
- jstack 可以顯示死鎖。
操作系統
計算機原理
- 《操作系統基礎知識——操作系統的原理,類型和結構》
CPU
多級緩存
典型的 CPU 有三級緩存,距離核心越近,速度越快,空間越小。L1 一般 32k,L2 一般 256k,L3 一般12M。內存速度需要200個 CPU 周期,CPU 緩存需要1個CPU周期。
進程
TODO
線程
協程
- 《終結python協程----從yield到actor模型的實現》
- 線程的調度是由操作系統負責,協程調度是程序自行負責
- 與線程相比,協程減少了無謂的操作系統切換.
- 實際上當遇到IO操作時做切換才更有意義,(因為IO操作不用占用CPU),如果沒遇到IO操作,按照時間片切換.
Linux
設計模式
設計模式的六大原則
- 《設計模式的六大原則》
- 開閉原則:對擴展開放,對修改關閉,多使用抽象類和接口。
- 里氏替換原則:基類可以被子類替換,使用抽象類繼承,不使用具體類繼承。
- 依賴倒轉原則:要依賴于抽象,不要依賴于具體,針對接口編程,不針對實現編程。
- 接口隔離原則:使用多個隔離的接口,比使用單個接口好,建立最小的接口。
- 迪米特法則:一個軟件實體應當盡可能少地與其他實體發生相互作用,通過中間類建立聯系。
- 合成復用原則:盡量使用合成/聚合,而不是使用繼承。
23種常見設計模式
- 《設計模式》
- 《23種設計模式全解析》
- 《設計模式類圖與示例》
應用場景
- 《細數JDK里的設計模式》
- 結構型模式:
- 適配器:用來把一個接口轉化成另一個接口,如 java.util.Arrays#asList()。
- 橋接模式:這個模式將抽象和抽象操作的實現進行了解耦,這樣使得抽象和實現可以獨立地變化,如JDBC;
- 組合模式:使得客戶端看來單個對象和對象的組合是同等的。換句話說,某個類型的方法同時也接受自身類型作為參數,如 Map.putAll,List.addAll、Set.addAll。
- 裝飾者模式:動態的給一個對象附加額外的功能,這也是子類的一種替代方式,如 java.util.Collections#checkedList|Map|Set|SortedSet|SortedMap。
- 享元模式:使用緩存來加速大量小對象的訪問時間,如 valueOf(int)。
- 代理模式:代理模式是用一個簡單的對象來代替一個復雜的或者創建耗時的對象,如 java.lang.reflect.Proxy
- 創建模式:
- 抽象工廠模式:抽象工廠模式提供了一個協議來生成一系列的相關或者獨立的對象,而不用指定具體對象的類型,如 java.util.Calendar#getInstance()。
- 建造模式(Builder):定義了一個新的類來構建另一個類的實例,以簡化復雜對象的創建,如:java.lang.StringBuilder#append()。
- 工廠方法:就是 一個返* 回具體對象的方法,而不是多個,如 java.lang.Object#toString()、java.lang.Class#newInstance()。
- 原型模式:使得類的實例能夠生成自身的拷貝、如:java.lang.Object#clone()。
- 單例模式:全局只有一個實例,如 java.lang.Runtime#getRuntime()。
- 行為模式:
- 責任鏈模式:通過把請求從一個對象傳遞到鏈條中下一個對象的方式,直到請求被處理完畢,以實現對象間的解耦。如 javax.servlet.Filter#doFilter()。
- 命令模式:將操作封裝到對象內,以便存儲,傳遞和返回,如:java.lang.Runnable。
- 解釋器模式:定義了一個語言的語法,然后解析相應語法的語句,如,java.text.Format,java.text.Normalizer。
- 迭代器模式:提供一個一致的方法來順序訪問集合中的對象,如 java.util.Iterator。
- 中介者模式:通過使用一個中間對象來進行消息分發以及減少類之間的直接依賴,java.lang.reflect.Method#invoke()。
- 空對象模式:如 java.util.Collections#emptyList()。
- 觀察者模式:它使得一個對象可以靈活的將消息發送給感興趣的對象,如 java.util.EventListener。
- 模板方法模式:讓子類可以重寫方法的一部分,而不是整個重寫,如 java.util.Collections#sort()。
- 《Spring-涉及到的設計模式匯總》
- 《Mybatis使用的設計模式》
單例模式
- 《單例模式的三種實現 以及各自的優缺點》
- 《單例模式--反射--防止序列化破壞單例模式》
- 使用枚舉類型。
責任鏈模式
TODO
MVC
- 《MVC 模式》
- 模型(model)-視圖(view)-控制器(controller)
IOC
- 《理解 IOC》
- 《IOC 的理解與解釋》
- 正向控制:傳統通過new的方式。反向控制,通過容器注入對象。
- 作用:用于模塊解耦。
- DI:Dependency Injection,即依賴注入,只關心資源使用,不關心資源來源。
AOP
- 《輕松理解AOP(面向切面編程)》
- 《Spring AOP詳解》
- 《Spring AOP的實現原理》
- Spring AOP使用的動態代理,主要有兩種方式:JDK動態代理和CGLIB動態代理。
- 《Spring AOP 實現原理與 CGLIB 應用》
- Spring AOP 框架對 AOP 代理類的處理原則是:如果目標對象的實現類實現了接口,Spring AOP 將會采用 JDK 動態代理來生成 AOP 代理類;如果目標對象的實現類沒有實現接口,Spring AOP 將會采用 CGLIB 來生成 AOP 代理類
UML
微服務思想
康威定律
- 《微服務架構的理論基礎 - 康威定律》
- 定律一:組織溝通方式會通過系統設計表達出來,就是說架構的布局和組織結構會有相似。
- 定律二:時間再多一件事情也不可能做的完美,但總有時間做完一件事情。一口氣吃不成胖子,先搞定能搞定的。
- 定律三:線型系統和線型組織架構間有潛在的異質同態特性。種瓜得瓜,做獨立自治的子系統減少溝通成本。
- 定律四:大的系統組織總是比小系統更傾向于分解。合久必分,分而治之。
- 《微服務架構核?20講》
運維 & 統計 & 技術支持
常規監控
- 《騰訊業務系統監控的修煉之路》
- 監控的方式:主動、被動、旁路(比如輿情監控)
- 監控類型: 基礎監控、服務端監控、客戶端監控、 監控、用戶端監控
- 監控的目標:全、塊、準
- 核心指標:請求量、成功率、耗時
- 《開源還是商用?十大云運維監控工具橫評》
- Zabbix、Nagios、Ganglia、Zenoss、Open-falcon、監控寶、 360網站服務監控、阿里云監控、百度云觀測、小蜜蜂網站監測等。
- 《監控報警系統搭建及二次開發經驗》
命令行監控工具
- 《常用命令行監控工具》
- top、sar、tsar、nload
- 《20個命令行工具監控 Linux 系統性能》
- 《JVM性能調優監控工具jps、jstack、jmap、jhat、jstat、hprof使用詳解》
APM
APM — Application Performance Management
- 《Dapper,大規模分布式系統的跟蹤系統》
- CNCF OpenTracing,中文版
- 主要開源軟件,按字母排序
- Apache SkyWalking
- CAT
- CNCF jaeger
- Pinpoint
- Zipkin
- 《開源APM技術選型與實戰》
- 主要基于 Google的Dapper(大規模分布式系統的跟蹤系統) 思想。
統計分析
- 《流量統計的基礎:埋點》
- 常用指標:訪問與訪客、停留時長、跳出率、退出率、轉化率、參與度
- 《APP埋點常用的統計工具、埋點目標和埋點內容》
- 第三方統計:友盟、百度移動、魔方、App Annie、talking data、神策數據等。
- 《美團點評前端無痕埋點實踐》
- 所謂無痕、即通過可視化工具配置采集節點,在前端自動解析配置并上報埋點數據,而非硬編碼。
持續集成(CI/CD)
Jenkins
環境分離
開發、測試、生成環境分離。
自動化運維
Ansible
- 《Ansible中文權威指南》
- 《Ansible基礎配置和企業級項目實用案例》
puppet
chef
測試
TDD 理論
- 《深度解讀 - TDD(測試驅動開發)》
- 基于測試用例編碼功能代碼,XP(Extreme Programming)的核心實踐.
- 好處:一次關注一個點,降低思維負擔;迎接需求變化或改善代碼的設計;提前澄清需求;快速反饋;
單元測試
- 《Java單元測試之JUnit篇》
- 《JUnit 4 與 TestNG 對比》
- TestNG 覆蓋 JUnit 功能,適用于更復雜的場景。
- 《單元測試主要的測試功能點》
- 模塊接口測試、局部數據結構測試、路徑測試 、錯誤處理測試、邊界條件測試 。
壓力測試
- 《Apache ab 測試使用指南》
- 《大型網站壓力測試及優化方案》
- 《10大主流壓力/負載/性能測試工具推薦》
- 《真實流量壓測工具 tcpcopy應用淺析》
- 《nGrinder 簡易使用教程》
全鏈路壓測
- 《京東618:升級全鏈路壓測方案,打造軍演機器人ForceBot》
- 《餓了么全鏈路壓測的探索與實踐》
- 《四大語言,八大框架|滴滴全鏈路壓測解決之道》
- 《全鏈路壓測經驗》
A/B 、灰度、藍綠測試
- 《技術干貨 | AB 測試和灰度發布探索及實踐》
- 《nginx 根據IP 進行灰度發布》
- 《藍綠部署、A/B 測試以及灰度發布》
虛擬化
- 《VPS的三種虛擬技術OpenVZ、Xen、KVM優缺點比較》
KVM
- 《KVM詳解,太詳細太深入了,經典》
- 《【圖文】KVM 虛擬機安裝詳解》
Xen
OpenVZ
- 《開源Linux容器 OpenVZ 快速上手指南》
容器技術
Docker
- 《幾張圖幫你理解 docker 基本原理及快速入門》
- 《Docker 核心技術與實現原理》
- 《Docker 教程》
云技術
OpenStack
DevOps
- 《一分鐘告訴你究竟DevOps是什么鬼?》
- 《DevOps詳解》
文檔管理
- Confluence-收費文檔管理系統
- GitLab?
- Wiki
中間件
Web Server
Nginx
- 《Ngnix的基本學習-多進程和Apache的比較》
- Nginx 通過異步非阻塞的事件處理機制實現高并發。Apache 每個請求獨占一個線程,非常消耗系統資源。
- 事件驅動適合于IO密集型服務(Nginx),多進程或線程適合于CPU密集型服務(Apache),所以Nginx適合做反向代理,而非web服務器使用。
- 《nginx與Apache的對比以及優缺點》
- nginx只適合靜態和反向代理,不適合處理動態請求。
OpenResty
- 官方網站
- 《淺談 OpenResty》
- 通過 Lua 模塊可以在Nginx上進行開發。
- agentzh 的 Nginx 教程
Tengine
Apache Httpd
Tomcat
架構原理
- 《TOMCAT原理詳解及請求過程》
- 《Tomcat服務器原理詳解》
- 《Tomcat 系統架構與設計模式,第 1 部分: 工作原理》
- 《四張圖帶你了解Tomcat系統架構》
- 《JBoss vs. Tomcat: Choosing A Java Application Server》
- Tomcat 是輕量級的 Serverlet 容器,沒有實現全部 JEE 特性(比如持久化和事務處理),但可以通過其他組件代替,比如Spring。
- Jboss 實現全部了JEE特性,軟件開源免費、文檔收費。
調優方案
《Tomcat 調優方案》
- 啟動NIO模式(或者APR);調整線程池;禁用AJP連接器(Nginx+tomcat的架構,不需要AJP);
- 《tomcat http協議與ajp協議》
- 《AJP與HTTP比較和分析》
- AJP 協議(8009端口)用于降低和前端Server(如Apache,而且需要支持AJP協議)的連接數(前端),通過長連接提高性能。
- 并發高時,AJP協議優于HTTP協議。
Jetty
- 《Jetty 的工作原理以及與 Tomcat 的比較》
- 《jetty和tomcat優勢比較》
- 架構比較:Jetty的架構比Tomcat的更為簡單。
- 性能比較:Jetty和Tomcat性能方面差異不大,Jetty默認采用NIO結束在處理I/O請求上更占優勢,Tomcat默認采用BIO處理I/O請求,Tomcat適合處理少數非常繁忙的鏈接,處理靜態資源時性能較差。
- 其他方面:Jetty的應用更加快速,修改簡單,對新的Servlet規范的支持較好;Tomcat 對JEE和Servlet 支持更加全面。
緩存
- 《緩存失效策略(FIFO 、LRU、LFU三種算法的區別)》
本地緩存
- 《HashMap本地緩存》
- 《EhCache本地緩存》
- 堆內、堆外、磁盤三級緩存。
- 可按照緩存空間容量進行設置。
- 按照時間、次數等過期策略。
- 《Guava Cache》
- 簡單輕量、無堆外、磁盤緩存。
- 《Nginx本地緩存》
- 《Pagespeed—懶人工具,服務器端加速》
客戶端緩存
- 《瀏覽器端緩存》
- 主要是利用 Cache-Control 參數。
- 《H5 和移動端 WebView 緩存機制解析與實戰》
服務端緩存
Web緩存
- nuster - nuster cache
- varnish - varnish cache
- squid - squid cache
Memcached
- 《Memcached 教程》
- 《深入理解Memcached原理》
- 采用多路復用技術提高并發性。
- slab分配算法: memcached給Slab分配內存空間,默認是1MB。分配給Slab之后 把slab的切分成大小相同的chunk,Chunk是用于緩存記錄的內存空間,Chunk 的大小默認按照1.25倍的速度遞增。好處是不會頻繁申請內存,提高IO效率,壞處是會有一定的內存浪費。
- 《Memcached軟件工作原理》
- 《Memcache技術分享:介紹、使用、存儲、算法、優化、命中率》
- 《memcache 中 add 、 set 、replace 的區別》
- 區別在于當key存在還是不存在時,返回值是true和false的。
- 《memcached全面剖析》
Redis
- 《Redis 教程》
- 《redis底層原理》
- 使用 ziplist 存儲鏈表,ziplist是一種壓縮鏈表,它的好處是更能節省內存空間,因為它所存儲的內容都是在連續的內存區域當中的。
- 使用 skiplist(跳躍表)來存儲有序集合對象、查找上先從高Level查起、時間復雜度和紅黑樹相當,實現容易,無鎖、并發性好。
- 《Redis持久化方式》
- RDB方式:定期備份快照,常用于災難恢復。優點:通過fork出的進程進行備份,不影響主進程、RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。缺點:會丟數據。
- AOF方式:保存操作日志方式。優點:恢復時數據丟失少,缺點:文件大,回復慢。
- 也可以兩者結合使用。
- 《分布式緩存--序列3--原子操作與CAS樂觀鎖》
架構
回收策略
Tair
- 官方網站
- 《Tair和Redis的對比》
- 特點:可以配置備份節點數目,通過異步同步到備份節點
- 一致性Hash算法。
- 架構:和Hadoop 的設計思想類似,有Configserver,DataServer,Configserver 通過心跳來檢測,Configserver也有主備關系。
幾種存儲引擎:
- MDB,完全內存性,可以用來存儲Session等數據。
- Rdb(類似于Redis),輕量化,去除了aof之類的操作,支持Restfull操作
- LDB(LevelDB存儲引擎),持久化存儲,LDB 作為rdb的持久化,google實現,比較高效,理論基礎是LSM(Log-Structured-Merge Tree)算法,現在內存中修改數據,達到一定量時(和內存匯總的舊數據一同寫入磁盤)再寫入磁盤,存儲更加高效,縣比喻Hash算法。
- Tair采用共享內存來存儲數據,如果服務掛掉(非服務器),重啟服務之后,數據亦然還在。
消息隊列
- 《消息隊列-推/拉模式學習 & ActiveMQ及JMS學習》
- RabbitMQ 消費者默認是推模式(也支持拉模式)。
- Kafka 默認是拉模式。
- Push方式:優點是可以盡可能快地將消息發送給消費者,缺點是如果消費者處理能力跟不上,消費者的緩沖區可能會溢出。
- Pull方式:優點是消費端可以按處理能力進行拉去,缺點是會增加消息延遲。
- 《Kafka、RabbitMQ、RocketMQ等消息中間件的對比 —— 消息發送性能和區別》
消息總線
消息總線相當于在消息隊列之上做了一層封裝,統一入口,統一管控、簡化接入成本。
消息的順序
RabbitMQ
支持事務,推拉模式都是支持、適合需要可靠性消息傳輸的場景。
- 《RabbitMQ的應用場景以及基本原理介紹》
- 《消息隊列之 RabbitMQ》
- 《RabbitMQ之消息確認機制(事務+Confirm)》
RocketMQ
Java實現,推拉模式都是支持,吞吐量遜于Kafka。可以保證消息順序。
- 《RocketMQ 實戰之快速入門》
- 《RocketMQ 源碼解析》
ActiveMQ
純Java實現,兼容JMS,可以內嵌于Java應用中。
Kafka
高吞吐量、采用拉模式。適合高IO場景,比如日志同步。
- 官方網站
- 《各消息隊列對比,Kafka深度解析,眾人推薦,精彩好文!》
- 《Kafka分區機制介紹與示例》
Redis 消息推送
生產者、消費者模式完全是客戶端行為,list 和 拉模式實現,阻塞等待采用 blpop 指令。
- 《Redis學習筆記之十:Redis用作消息隊列》
ZeroMQ
TODO
定時調度
單機定時調度
- 《linux定時任務cron配置》
- 《Linux cron運行原理》
- fork 進程 + sleep 輪詢
- 《Quartz使用總結》
- 《Quartz源碼解析 ---- 觸發器按時啟動原理》
- 《quartz原理揭秘和源碼解讀》
- 定時調度在 QuartzSchedulerThread 代碼中,while()無限循環,每次循環取出時間將到的trigger,觸發對應的job,直到調度器線程被關閉。
分布式定時調度
- 《這些優秀的國產分布式任務調度系統,你用過幾個?》
- opencron、LTS、XXL-JOB、Elastic-Job、Uncode-Schedule、Antares
- 《Quartz任務調度的基本實現原理》
- Quartz集群中,獨立的Quartz節點并不與另一其的節點或是管理節點通信,而是通過相同的數據庫表來感知到另一Quartz應用的
- 《Elastic-Job-Lite 源碼解析》
- 《Elastic-Job-Cloud 源碼解析》
RPC
- 《從零開始實現RPC框架 - RPC原理及實現》
- 核心角色:Server: 暴露服務的服務提供方、Client: 調用遠程服務的服務消費方、Registry: 服務注冊與發現的注冊中心。
- 《分布式RPC框架性能大比拼 dubbo、motan、rpcx、gRPC、thrift的性能比較》
Dubbo
** SPI ** TODO
Thrift
- 官方網站
- 《Thrift RPC詳解》
- 支持多語言,通過中間語言定義接口。
gRPC
服務端可以認證加密,在外網環境下,可以保證數據安全。
數據庫中間件
Sharding Jdbc
日志系統
日志搜集
- 《從零開始搭建一個ELKB日志收集系統》
- 《用ELK搭建簡單的日志收集分析系統》
- 《日志收集系統-探究》
配置中心
- Apollo - 攜程開源的配置中心應用
- Spring Boot 和 Spring Cloud
- 支持推、拉模式更新配置
- 支持多種語言
- 《基于zookeeper實現統一配置管理》
- 《 Spring Cloud Config 分布式配置中心使用教程》
servlet 3.0 異步特性可用于配置中心的客戶端
API 網關
主要職責:請求轉發、安全認證、協議轉換、容災。
- 《API網關那些兒》
- 《談API網關的背景、架構以及落地方案》
- 《使用Zuul構建API Gateway》
- 《Spring Cloud Gateway 源碼解析》
- 《HTTP API網關選擇之一Kong介紹》
網絡
協議
OSI 七層協議
- 《OSI七層協議模型、TCP/IP四層模型學習筆記》
TCP/IP
- 《深入淺出 TCP/IP 協議》
- 《TCP協議中的三次握手和四次揮手》
HTTP
HTTP2.0
- 《HTTP 2.0 原理詳細分析》
- 《HTTP2.0的基本單位為二進制幀》
- 利用二進制幀負責傳輸。
- 多路復用。
HTTPS
- 《https原理通俗了解》
- 使用非對稱加密協商加密算法
- 使用對稱加密方式傳輸數據
- 使用第三方機構簽發的證書,來加密公鑰,用于公鑰的安全傳輸、防止被中間人串改。
- 《八大免費SSL證書-給你的網站免費添加Https安全加密》
網絡模型
- 《web優化必須了解的原理之I/o的五種模型和web的三種工作模式》
- 五種I/O模型:阻塞I/O,非阻塞I/O,I/O復用、事件(信號)驅動I/O、異步I/O,前四種I/O屬于同步操作,I/O的第一階段不同、第二階段相同,最后的一種則屬于異步操作。
- 三種 Web Server 工作方式:Prefork(多進程)、Worker方式(線程方式)、Event方式。
- 《select、poll、epoll之間的區別總結》
- select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程是阻塞的。
- select 有打開文件描述符數量限制,默認1024(2048 for x64),100萬并發,就要用1000個進程、切換開銷大;poll采用鏈表結構,沒有數量限制。
- select,poll “醒著”的時候要遍歷整個fd集合,而epoll在“醒著”的時候只要判斷一下就緒鏈表是否為空就行了,通過回調機制節省大量CPU時間;select,poll每次調用都要把fd集合從用戶態往內核態拷貝一次,而epoll只要一次拷貝。
- poll會隨著并發增加,性能逐漸下降,epoll采用紅黑樹結構,性能穩定,不會隨著連接數增加而降低。
- 《select,poll,epoll比較 》
- 在連接數少并且連接都十分活躍的情況下,select和poll的性能可能比epoll好,畢竟epoll的通知機制需要很多函數回調。
- 《深入理解Java NIO》
- NIO 是一種同步非阻塞的 IO 模型。同步是指線程不斷輪詢 IO 事件是否就緒,非阻塞是指線程在等待 IO 的時候,可以同時做其他任務
- 《BIO與NIO、AIO的區別》
- 《兩種高效的服務器設計模型:Reactor和Proactor模型》
Epoll
Java NIO
- 《深入理解Java NIO》
- 《Java NIO編寫Socket服務器的一個例子》
kqueue
連接和短連接
框架
- 《Netty原理剖析》
- Reactor 模式介紹。
- Netty 是 Reactor 模式的一種實現。
零拷貝(Zero-copy)
- 《對于 Netty ByteBuf 的零拷貝(Zero Copy) 的理解》
- 多個物理分離的buffer,通過邏輯上合并成為一個,從而避免了數據在內存之間的拷貝。
序列化(二進制協議)
Hessian
- 《Hessian原理分析》 Binary-RPC;不僅僅是序列化
Protobuf
- 《Protobuf協議的Java應用例子》 Goolge出品、占用空間和效率完勝其他序列化類庫,如Hessian;需要編寫 .proto 文件。
- 《Protocol Buffers序列化協議及應用》
- 關于協議的解釋;缺點:可讀性差;
- 《簡單的使用 protobuf 和 protostuff》
- protostuff 的好處是不用寫 .proto 文件,Java 對象直接就可以序列化。
數據庫
基礎理論
數據庫設計的三大范式
- 《數據庫的三大范式以及五大約束》
- 第一范式:數據表中的每一列(每個字段)必須是不可拆分的最小單元,也就是確保每一列的原子性;
- 第二范式(2NF):滿足1NF后,要求表中的所有列,都必須依賴于主鍵,而不能有任何一列與主鍵沒有關系,也就是說一個表只描述一件事情;
- 第三范式:必須先滿足第二范式(2NF),要求:表中的每一列只與主鍵直接相關而不是間接相關,(表中的每一列只能依賴于主鍵);
MySQL
原理
- 《MySQL的InnoDB索引原理詳解》
- 《MySQL存儲引擎--MyISAM與InnoDB區別》
- 兩種類型最主要的差別就是Innodb 支持事務處理與外鍵和行級鎖
- 《myisam和innodb索引實現的不同》
InnoDB
優化
- 《MySQL36條軍規》
- 《MYSQL性能優化的最佳20+條經驗》
- 《SQL優化之道》
- 《mysql數據庫死鎖的產生原因及解決辦法》
- 《導致索引失效的可能情況》
- 《 MYSQL分頁limit速度太慢優化方法》
- 原則上就是縮小掃描范圍。
索引
聚集索引, 非聚集索引
- 《MySQL 聚集索引/非聚集索引簡述》
- 《MyISAM和InnoDB的索引實現》
MyISAM 是非聚集,InnoDB 是聚集
復合索引
對于復合索引,在查詢使用時,最好將條件順序按找索引的順序,這樣效率最高; select * from table1 where col1=A AND col2=B AND col3=D 如果使用 where col2=B AND col1=A 或者 where col2=B 將不會使用索引
- 原文中提到索引是按照“col1,col2,col3”的順序創建的,而mysql在按照最左前綴的索引匹配原則,且會自動優化 where 條件的順序,當條件中只有 col2=B AND col1=A 時,會自動轉化為 col1=A AND col2=B,所以依然會使用索引。
- 《MySQL查詢where條件的順序對查詢效率的影響》
自適應哈希索引(AHI)
explain
- 《MySQL 性能優化神器 Explain 使用分析》
NoSQL
MongoDB
- MongoDB 教程
- 《Mongodb相對于關系型數據庫的優缺點》
- 優點:弱一致性(最終一致),更能保證用戶的訪問速度;內置GridFS,支持大容量的存儲;Schema-less 數據庫,不用預先定義結構;內置Sharding;相比于其他NoSQL,第三方支持豐富;性能優越;
- 缺點:mongodb不支持事務操作;mongodb占用空間過大;MongoDB沒有如MySQL那樣成熟的維護工具,這對于開發和IT運營都是個值得注意的地方;
Hbase
- 《簡明 HBase 入門教程(開篇)》
- 《深入學習HBase架構原理》
- 《傳統的行存儲和(HBase)列存儲的區別》
- 《Hbase與傳統數據庫的區別》
- 空數據不存儲,節省空間,且適用于并發。
- 《HBase Rowkey設計》
- rowkey 按照字典順序排列,便于批量掃描。
- 通過散列可以避免熱點。
搜索引擎
搜索引擎原理
Lucene
Elasticsearch
- 《Elasticsearch學習,請先看這一篇!》
- 《Elasticsearch索引原理》
Solr
- 《 Apache Solr入門教程》
- 《elasticsearch與solr比較》
sphinx
性能
性能優化方法論
- 《15天的性能優化工作,5方面的調優經驗》
- 代碼層面、業務層面、數據庫層面、服務器層面、前端優化。
- 《系統性能優化的幾個方面》
容量評估
- 《聯網性能與容量評估的方法論和典型案例》
- 《互聯網架構,如何進行容量設計?》
- 評估總訪問量、評估平均訪問量QPS、評估高峰QPS、評估系統、單機極限QPS
CDN 網絡
- 《CDN加速原理》
- 《國內有哪些比較好的 CDN?》
連接池
性能調優
大數據
流式計算
Storm
Flink
Kafka Stream
- 《Kafka Stream調研:一種輕量級流計算模式》計;
- 推薦系統用戶畫像標簽實時更新;
- 線上服務健康狀況實時監測;
- 實時榜單;
- 實時數據統計。
Hadoop
- 《用通俗易懂的話說下hadoop是什么,能做什么》
- 《史上最詳細的Hadoop環境搭建》
HDFS
MapReduce
- 《用通俗易懂的大白話講解Map/Reduce原理》
- 《 簡單的map-reduce的java例子》
Yarn
Spark
安全
web 安全
XSS
CSRF
SQL 注入
Hash Dos
- 《邪惡的JAVA HASH DOS攻擊》
- 利用JsonObject 上傳大Json,JsonObject 底層使用HashMap;不同的數據產生相同的hash值,使得構建Hash速度變慢,耗盡CPU。
- 《一種高級的DoS攻擊-Hash碰撞攻擊》
- 《關于Hash Collision DoS漏洞:解析與解決方案》
腳本注入
漏洞掃描工具
驗證碼
- 《驗證碼原理分析及實現》
- 《詳解滑動驗證碼的實現原理》
- 滑動驗證碼是根據人在滑動滑塊的響應時間,拖拽速度,時間,位置,軌跡,重試次數等來評估風險。
- 《淘寶滑動驗證碼研究》
DDoS 防范
- 《學習手冊:DDoS的攻擊方式及防御手段》
- 《免費DDoS攻擊測試工具大合集》
用戶隱私信息保護
- 用戶密碼非明文保存,加動態salt。
- 身份證號,手機號如果要顯示,用 “*” 替代部分字符。
- 聯系方式在的顯示與否由用戶自己控制。
- TODO
- 《個人隱私包括哪些》
- 《在互聯網上,隱私的范圍包括哪些?》
- 《用戶密碼保存》
序列化漏洞
加密解密
對稱加密
- 《常見對稱加密算法》
- DES、3DES、Blowfish、AES
- DES 采用 56位秘鑰,Blowfish 采用1到448位變長秘鑰,AES 128,192和256位長度的秘鑰。
- DES 秘鑰太短(只有56位)算法目前已經被 AES 取代,并且 AES 有硬件加速,性能很好。
哈希算法
- 《常用的哈希算法》
- MD5 和 SHA-1 已經不再安全,已被棄用。
- 目前 SHA-256 是比較安全的。
- 《基于Hash摘要簽名的公網URL簽名驗證設計方案》
非對稱加密
- 《常見非對稱加密算法》
- RSA、DSA、ECDSA(螺旋曲線加密算法)
- 和 RSA 不同的是 DSA 僅能用于數字簽名,不能進行數據加密解密,其安全性和RSA相當,但其性能要比RSA快。
- 256位的ECC秘鑰的安全性等同于3072位的RSA秘鑰。
- 《區塊鏈的加密技術》
服務器安全
- 《Linux強化論:15步打造一個安全的Linux服務器》
數據安全
數據備份
TODO
網絡隔離
內外網分離
TODO
登錄跳板機
在內外環境中通過跳板機登錄到線上主機。
授權、認證
RBAC
- 《基于組織角色的權限設計》
- 《權限系統與RBAC模型概述》
- 《Spring整合Shiro做權限控制模塊詳細案例分析》
OAuth2.0
- 《理解OAuth 2.0》
- 《一張圖搞定OAuth2.0》
雙因素認證(2FA)
2FA - Two-factor authentication,用于加強登錄驗證
常用做法是 登錄密碼 + 手機驗證碼(或者令牌Key,類似于與網銀的 USB key)
- 【《雙因素認證(2FA)教程》】(http://www.ruanyifeng.com/blog/2017/11/2fa-tutorial.html)
單點登錄(SSO)
常用開源框架
開源協議
日志框架
Log4j、Log4j2
- 《log4j 詳細講解》
- 《log4j2 實際使用詳解》
- 《Log4j1,Logback以及Log4j2性能測試對比》
- Log4J 異步日志性能優異。
Logback
- 《最全LogBack 詳解、含java案例和配置說明》
ORM
- 《ORM框架使用優缺點》
- 主要目的是為了提高開發效率。
MyBatis:
- 《mybatis緩存機制詳解》
- 一級緩存是SqlSession級別的緩存,緩存的數據只在SqlSession內有效
- 二級緩存是mapper級別的緩存,同一個namespace公用這一個緩存,所以對SqlSession是共享的;使用 LRU 機制清理緩存,通過 cacheEnabled 參數開啟。
- 《MyBatis學習之代碼生成器Generator》
網絡框架
TODO
Web 框架
Spring 家族
Spring
Spring Boot
Spring Cloud
- Spring Boot 中文索引站
- Spring Cloud 中文文檔
- 《Spring Cloud基礎教程》
工具框架
- 《Apache Commons 工具類介紹及簡單使用》
- 《Google guava 中文教程》
分布式設計
擴展性設計
- 《架構師不可不知的十大可擴展架構》
- 總結下來,通用的套路就是分布、緩存及異步處理。
- 《可擴展性設計之數據切分》
- 水平切分+垂直切分
- 利用中間件進行分片如,MySQL Proxy。
- 利用分片策略進行切分,如按照ID取模。
- 《說說如何實現可擴展性的大型網站架構》
- 分布式服務+消息隊列。
- 《大型網站技術架構(七)--網站的可擴展性架構》
穩定性 & 高可用
- 《系統設計:關于高可用系統的一些技術方案》
- 可擴展:水平擴展、垂直擴展。 通過冗余部署,避免單點故障。
- 隔離:避免單一業務占用全部資源。避免業務之間的相互影響 2. 機房隔離避免單點故障。
- 解耦:降低維護成本,降低耦合風險。減少依賴,減少相互間的影響。
- 限流:滑動窗口計數法、漏桶算法、令牌桶算法等算法。遇到突發流量時,保證系統穩定。
- 降級:緊急情況下釋放非核心功能的資源。犧牲非核心業務,保證核心業務的高可用。
- 熔斷:異常情況超出閾值進入熔斷狀態,快速失敗。減少不穩定的外部依賴對核心服務的影響。
- 自動化測試:通過完善的測試,減少發布引起的故障。
- 灰度發布:灰度發布是速度與安全性作為妥協,能夠有效減少發布故障。
- 《關于高可用的系統》
- 設計原則:數據不丟(持久化);服務高可用(服務副本);絕對的100%高可用很難,目標是做到盡可能多的9,如99.999%(全年累計只有5分鐘)。
硬件負載均衡
- 《轉!!負載均衡器技術Nginx和F5的優缺點對比》
- 主要是和F5對比。
- 《軟/硬件負載均衡產品 你知多少?》
軟件負載均衡
- 《幾種負載均衡算法》 輪尋、權重、負載、最少連接、QoS
- 《DNS負載均衡》
- 配置簡單,更新速度慢。
- 《Nginx負載均衡》
- 簡單輕量、學習成本低;主要適用于web應用。
- 《借助LVS+Keepalived實現負載均衡 》
- 配置比較負載、只支持到4層,性能較高。
- 《HAProxy用法詳解 全網最詳細中文文檔》
- 支持到七層(比如HTTP)、功能比較全面,性能也不錯。
- 《Haproxy+Keepalived+MySQL實現讀均衡負載》
- 主要是用戶讀請求的負載均衡。
- 《rabbitmq+haproxy+keepalived實現高可用集群搭建》
限流
- 《談談高并發系統的限流》
- 計數器:通過滑動窗口計數器,控制單位時間內的請求次數,簡單粗暴。
- 漏桶算法:固定容量的漏桶,漏桶滿了就丟棄請求,比較常用。
- 令牌桶算法:固定容量的令牌桶,按照一定速率添加令牌,處理請求前需要拿到令牌,拿不到令牌則丟棄請求,或進入丟隊列,可以通過控制添加令牌的速率,來控制整體速度。Guava 中的 RateLimiter 是令牌桶的實現。
- Nginx 限流:通過 limit_req 等模塊限制并發連接數。
應用層容災
- 《防雪崩利器:熔斷器 Hystrix 的原理與使用》
- 雪崩效應原因:硬件故障、硬件故障、程序Bug、重試加大流量、用戶大量請求。
- 雪崩的對策:限流、改進緩存模式(緩存預加載、同步調用改異步)、自動擴容、降級。
- Hystrix設計原則:
- 資源隔離:Hystrix通過將每個依賴服務分配獨立的線程池進行資源隔離, 從而避免服務雪崩。
- 熔斷開關:服務的健康狀況 = 請求失敗數 / 請求總數,通過閾值設定和滑動窗口控制開關。
- 命令模式:通過繼承 HystrixCommand 來包裝服務調用邏輯。
- 《緩存穿透,緩存擊穿,緩存雪崩解決方案分析》
- 《緩存擊穿、失效以及熱點key問題》
- 主要策略:失效瞬間:單機使用鎖;使用分布式鎖;不過期;
- 熱點數據:熱點數據單獨存儲;使用本地緩存;分成多個子key;
跨機房容災
- 《“異地多活”多機房部署經驗談》
- 通過自研中間件進行數據同步。
- 《異地多活(異地雙活)實踐經驗》
- 注意延遲問題,多次跨機房調用會將延時放大數倍。
- 建房間專線很大概率會出現問題,做好運維和程序層面的容錯。
- 不能依賴于程序端數據雙寫,要有自動同步方案。
- 數據永不在高延遲和較差網絡質量下,考慮同步質量問題。
- 核心業務和次要業務分而治之,甚至只考慮核心業務。
- 異地多活監控部署、測試也要跟上。
- 業務允許的情況下考慮用戶分區,尤其是游戲、郵箱業務。
- 控制跨機房消息體大小,越小越好。
- 考慮使用docker容器虛擬化技術,提高動態調度能力。
- 容災技術及建設經驗介紹
容災演練流程
- 《依賴治理、灰度發布、故障演練,阿里電商故障演練系統的設計與實戰經驗》
- 常見故障畫像
- 案例:預案有效性、預案有效性、故障復現、架構容災測試、參數調優、參數調優、故障突襲、聯合演練。
平滑啟動
- 平滑重啟應用思路 1.端流量(如vip層)、2. flush 數據(如果有)、3, 重啟應用
- 《JVM安全退出(如何優雅的關閉java服務)》 推薦推出方式:System.exit,Kill SIGTERM;不推薦 kill-9;用 Runtime.addShutdownHook 注冊鉤子。
- 《常見Java應用如何優雅關閉》 Java、Spring、Dubbo 優雅關閉方式。
數據庫擴展
讀寫分離模式
- 《Mysql主從方案的實現》
- 《搭建MySQL主從復制經典架構》
- 《Haproxy+多臺MySQL從服務器(Slave) 實現負載均衡》
- 《DRBD+Heartbeat+Mysql高可用讀寫分離架構》
- DRDB 進行磁盤復制,避免單點問題。
- 《MySQL Cluster 方式》
分片模式
- 《分庫分表需要考慮的問題及方案》
- 中間件: 輕量級:sharding-jdbc、TSharding;重量級:Atlas、MyCAT、Vitess等。
- 問題:事務、Join、遷移、擴容、ID、分頁等。
- 事務補償:對數據進行對帳檢查;基于日志進行比對;定期同標準數據來源進行同步等。
- 分庫策略:數值范圍;取模;日期等。
- 分庫數量:通常 MySQL 單庫 5千萬條、Oracle 單庫一億條需要分庫。
- 《MySql分表和表分區詳解》
- 分區:是MySQL內部機制,對客戶端透明,數據存儲在不同文件中,表面上看是同一個表。
- 分表:物理上創建不同的表、客戶端需要管理分表路由。
服務治理
服務注冊與發現
- 《永不失聯!如何實現微服務架構中的服務發現?》
- 客戶端服務發現模式:客戶端直接查詢注冊表,同時自己負責負載均衡。Eureka 采用這種方式。
- 服務器端服務發現模式:客戶端通過負載均衡查詢服務實例。
- 《SpringCloud服務注冊中心比較:Consul vs Zookeeper vs Etcd vs Eureka》
- CAP支持:Consul(CA)、zookeeper(cp)、etcd(cp) 、euerka(ap)
- 作者認為目前 Consul 對 Spring cloud 的支持比較好。
- 《基于Zookeeper的服務注冊與發現》
- 優點:API簡單、Pinterest,Airbnb 在用、多語言、通過watcher機制來實現配置PUSH,能快速響應配置變化。
服務路由控制
- 《分布式服務框架學習筆記4 服務路由》
- 原則:透明化路由
- 負載均衡策略:隨機、輪詢、服務調用延遲、一致性哈希、粘滯連接
- 本地路由有限策略:injvm(優先調用jvm內部的服務),innative(優先使用相同物理機的服務),原則上找距離最近的服務。
- 配置方式:統一注冊表;本地配置;動態下發。
分布式一致
CAP 與 BASE 理論
- 《從分布式一致性談到CAP理論、BASE理論》
- 一致性分類:強一致(立即一致);弱一致(可在單位時間內實現一致,比如秒級);最終一致(弱一致的一種,一定時間內最終一致)
- CAP:一致性、可用性、分區容錯性(網絡故障引起)
- BASE:Basically Available(基本可用)、Soft state(軟狀態)和Eventually consistent(最終一致性)
- BASE理論的核心思想是:即使無法做到強一致性,但每個應用都可以根據自身業務特點,采用適當的方式來使系統達到最終一致性。
分布式鎖
- 《分布式鎖的幾種實現方式》
- 基于數據庫的分布式鎖:優點:操作簡單、容易理解。缺點:存在單點問題、數據庫性能夠開銷較大、不可重入;
- 基于緩存的分布式鎖:優點:非阻塞、性能好。缺點:操作不好容易造成鎖無法釋放的情況。
- Zookeeper 分布式鎖:通過有序臨時節點實現鎖機制,自己對應的節點需要最小,則被認為是獲得了鎖。優點:集群可以透明解決單點問題,避免鎖不被釋放問題,同時鎖可以重入。缺點:性能不如緩存方式,吞吐量會隨著zk集群規模變大而下降。
- 《基于Zookeeper的分布式鎖》
- 清楚的原理描述 + Java 代碼示例。
- 《jedisLock—redis分布式鎖實現》
- 基于 setnx(set if ont exists),有則返回false,否則返回true。并支持過期時間。
- 《Memcached 和 Redis 分布式鎖方案》
- 利用 memcached 的 add(有別于set)操作,當key存在時,返回false。
分布式一致性算法
PAXOS
- 《分布式系列文章——Paxos算法原理與推導》
- 《Paxos-->Fast Paxos-->Zookeeper分析》
- 《【分布式】Zookeeper與Paxos》
Zab
- 《Zab:Zookeeper 中的分布式一致性協議介紹》
Raft
- 《Raft 為什么是更易理解的分布式一致性算法》
- 三種角色:Leader(領袖)、Follower(群眾)、Candidate(候選人)
- 通過隨機等待的方式發出投票,得票多的獲勝。
Gossip
兩階段提交、多階段提交
冪等
- 《分布式系統---冪等性設計》
- 冪等特性的作用:該資源具備冪等性,請求方無需擔心重復調用會產生錯誤。
- 常見保證冪等的手段:MVCC(類似于樂觀鎖)、去重表(唯一索引)、悲觀鎖、一次性token、序列號方式。
分布式一致方案
- 《分布式系統事務一致性解決方案》
- 《保證分布式系統數據一致性的6種方案》
分布式 Leader 節點選舉
- 《利用zookeeper實現分布式leader節點選舉》
TCC(Try/Confirm/Cancel) 柔性事務
- 《傳統事務與柔性事務》
- 基于BASE理論:基本可用、柔性狀態、最終一致。
- 解決方案:記錄日志+補償(正向補充或者回滾)、消息重試(要求程序要冪等);“無鎖設計”、采用樂觀鎖機制。
分布式文件系統
- 說說分布式文件存儲系統-基本架構 ?
- 《各種分布式文件系統的比較》 ?
- HDFS:大批量數據讀寫,用于高吞吐量的場景,不適合小文件。
- FastDFS:輕量級、適合小文件。
唯一ID 生成
全局唯一ID
- 《高并發分布式系統中生成全局唯一Id匯總》
- Twitter 方案(Snowflake 算法):41位時間戳+10位機器標識(比如IP,服務器名稱等)+12位序列號(本地計數器)
- Flicker 方案:MySQL自增ID + "REPLACE INTO XXX:SELECT LAST_INSERT_ID();"
- UUID:缺點,無序,字符串過長,占用空間,影響檢索性能。
- MongoDB 方案:利用 ObjectId。缺點:不能自增。
- 《TDDL 在分布式下的SEQUENCE原理》
- 在數據庫中創建 sequence 表,用于記錄,當前已被占用的id最大值。
- 每臺客戶端主機取一個id區間(比如 1000~2000)緩存在本地,并更新 sequence 表中的id最大值記錄。
- 客戶端主機之間取不同的id區間,用完再取,使用樂觀鎖機制控制并發。
一致性Hash算法
設計思想 & 開發模式
DDD(Domain-driven Design - 領域驅動設計)
- 《淺談我對DDD領域驅動設計的理解》
- 概念:DDD 主要對傳統軟件開發流程(分析-設計-編碼)中各階段的割裂問題而提出,避免由于一開始分析不明或在軟件開發過程中的信息流轉不一致而造成軟件無法交付(和需求方設想不一致)的問題。DDD 強調一切以領域(Domain)為中心,強調領域專家(Domain Expert)的作用,強調先定義好領域模型之后在進行開發,并且領域模型可以指導開發(所謂的驅動)。
- 過程:理解領域、拆分領域、細化領域,模型的準確性取決于模型的理解深度。
- 設計:DDD 中提出了建模工具,比如聚合、實體、值對象、工廠、倉儲、領域服務、領域事件來幫助領域建模。
- 《領域驅動設計的基礎知識總結》
- 領域(Doamin)本質上就是問題域,比如一個電商系統,一個論壇系統等。
- 界限上下文(Bounded Context):闡述子域之間的關系,可以簡單理解成一個子系統或組件模塊。
- 領域模型(Domain Model):DDD的核心是建立(用通用描述語言、工具—領域通用語言)正確的領域模型;反應業務需求的本質,包括實體和過程;其貫穿軟件分析、設計、開發 的整個過程;常用表達領域模型的方式:圖、代碼或文字;
- 領域通用語言:領域專家、開發設計人員都能立即的語言或工具。
- 經典分層架構:用戶界面/展示層、應用層、領域層、基礎設施層,是四層架構模式。
- 使用的模式:
- 關聯盡量少,盡量單項,盡量降低整體復雜度。
- 實體(Entity):領域中的唯一標示,一個實體的屬性盡量少,少則清晰。
- 值對象(Value Object):沒有唯一標識,且屬性值不可變,小二簡單的對象,比如Date。
- 領域服務(Domain Service): 協調多個領域對象,只有方法沒有狀態(不存數據);可以分為應用層服務,領域層服務、基礎層服務。
- 聚合及聚合根(Aggregate,Aggregate Root):聚合定義了一組具有內聚關系的相關對象的集合;聚合根是對聚合引用的唯一元素;當修改一個聚合時,必須在事務級別;大部分領域模型中,有70%的聚合通常只有一個實體,30%只有2~3個實體;如果一個聚合只有一個實體,那么這個實體就是聚合根;如果有多個實體,那么我們可以思考聚合內哪個對象有獨立存在的意義并且可以和外部直接進行交互;
- 工廠(Factory):類似于設計模式中的工廠模式。
- 倉儲(Repository):持久化到DB,管理對象,且只對聚合設計倉儲。
- 《領域驅動設計(DDD)實現之路》
- 聚合:比如一輛汽車(Car)包含了引擎(Engine)、車輪(Wheel)和油箱(Tank)等組件,缺一不可。
- 《領域驅動設計系列(2)淺析VO、DTO、DO、PO的概念、區別和用處》
命令查詢職責分離(CQRS)
CQRS — Command Query Responsibility Seperation
- 《領域驅動設計系列 (六):CQRS》
- 核心思想:讀寫分離(查詢和更新在不同的方法中),不同的流程只是不同的設計方式,CQ代碼分離,分布式環境中會有明顯體現(有冗余數據的情況下),目的是為了高性能。
- 《DDD CQRS架構和傳統架構的優缺點比較》
- 最終一致的設計理念;依賴于高可用消息中間件。
- 《CQRS架構簡介》
- 一個實現 CQRS 的抽象案例。
- 《深度長文:我對CQRS/EventSourcing架構的思考》
- CQRS 模式分析 + 12306 搶票案例
貧血,充血模型
- 《貧血,充血模型的解釋以及一些經驗》
- 失血模型:老子和兒子分別定義,相互不知道,二者實體定義中完全沒有業務邏輯,通過外部Service進行關聯。
- 貧血模型:老子知道兒子,兒子也知道老子;部分業務邏輯放到實體中;優點:各層單項依賴,結構清楚,易于維護;缺點:不符合OO思想,相比于充血模式,Service層較為厚重;
- 充血模型:和貧血模型類似,區別在于如何劃分業務邏輯。優點:Service層比較薄,只充當Facade的角色,不和DAO打交道、復合OO思想;缺點:非單項依賴,DO和DAO之間雙向依賴、和Service層的邏輯劃分容易造成混亂。
- 腫脹模式:是一種極端情況,取消Service層、全部業務邏輯放在DO中;優點:符合OO思想、簡化了分層;缺點:暴露信息過多、很多非DO邏輯也會強行并入DO。這種模式應該避免。
- 作者主張使用貧血模式。
Actor 模式
TODO
響應式編程
Reactor
TODO
RxJava
TODO
Vert.x
TODO
DODAF2.0
- 《DODAF2.0方法論》
- 《DODAF2.0之能力視角如何落地》
Serverless
無需過多關系服務器的服務架構理念。
- 《什么是Serverless無服務器架構?》
- Serverless 不代表出去服務器,而是去除對服務器運行狀態的關心。
- Serverless 代表一思維方式的轉變,從“構建一套服務在一臺服務器上,對對個事件進行響應轉變為構建一個為服務器,來響應一個事件”。
- Serverless 不代表某個具體的框架。
- 《如何理解Serverless?》
- 依賴于 Baas ((Mobile) Backend as a Service) 和 Faas (Functions as a service)
Service Mesh
- 《什么是Service Mesh?》
- 《初識 Service Mesh》
項目管理
架構評審
- 《架構設計之如何評審架構設計說明書》
- 《人人都是架構師:非功能性需求》
重構
代碼規范
代碼 Review
制度還是制度! 另外,每個公司需要根據自己的需求和目標制定自己的 check list
- 《為什么你做不好 Code Review?》
- 代碼 review 做的好,在于制度建設。
- 《從零開始Code Review》
- 《Code Review Checklist》
- 《Java Code Review Checklist》
- 《如何用 gitlab 做 code review》
RUP
看板管理
SCRUM
SCRUM - 爭球
- 3個角色:Product Owner(PO) 產品負責人;Scrum Master(SM),推動Scrum執行;Team 開發團隊。
- 3個工件:Product Backlog 產品TODOLIST,含優先級;Sprint Backlog 功能開發 TODO LIST;燃盡圖;
- 五個價值觀:專注、勇氣、公開、承諾、尊重。
- 《敏捷項目管理流程-Scrum框架最全總結!》
- 《敏捷其實很簡單3---敏捷方法之scrum》
敏捷開發
TODO
極限編程(XP)
XP - eXtreme Programming
- 《主流敏捷開發方法:極限編程XP》
- 是一種指導開發人員的方法論。
- 4大價值:
- 溝通:鼓勵口頭溝通,提高效率。
- 簡單:夠用就好。
- 反饋:及時反饋、通知相關人。
- 勇氣:提倡擁抱變化,敢于重構。
- 5個原則:快速反饋、簡單性假設、逐步修改、提倡更改(小步快跑)、優質工作(保證質量的前提下保證小步快跑)。
- 5個工作:階段性沖刺;沖刺計劃會議;每日站立會議;沖刺后review;回顧會議。
結對編程
邊寫碼,邊review。能夠增強代碼質量、減少bug。
PDCA 循環質量管理
P——PLAN 策劃,D——DO 實施,C——CHECK 檢查,A——ACT 改進
FMEA管理模式
TODO
通用業務術語
TODO
技術趨勢
TODO