eventbus源碼解析
A. 如何開發Android應用框架
在Android開發中能夠知道和使用一些好用的第三方支持,省去自己的很多時間,下面涉及到的多為經過歷史興衰與檢驗的,江山代有人才出一代更比一代強,有些已經被更新更好用的所取代,但也很多地方仍可圈可點不乏參考,有些依然經典,整理出來請君一參.歡迎大家的指正,補充與交流.
1、AndBase框架
項目地址: https://code.jd.com/zhaoqp2010_m/andbase
1.andbase中包含了大量的開發常用手段。
如網路下載,多線程與線程池的管理,資料庫ORM,圖片緩存管理,圖片文件下載上傳,Http請求工具,常用工具類(字元串,日期,文件處理,圖片處理工具類等),能夠使您的應用在團隊開發中減少冗餘代碼,很大的提高了代碼的維護性與開發高效性,能很好的規避由於開發疏忽而導致常犯的錯誤。
2.andbase封裝了大量的常用控制項。
如list分頁,下拉刷新,圖片輪播,表格,多線程下載器,側邊欄,圖片上傳,輪子選擇,圖表,Tab滑動,日歷選擇器等。
3.強大的AbActivity,您沒有理由不繼承它。
繼承它你能夠獲得一個簡單強大可設置的操作欄,以及一系列的簡單調用,如彈出框,提示框,進度框,副操作欄等。
4.提供效率較高圖片緩存管理策略,使內存大幅度節省,利用率提高,效率提高。
程序中要管理大量的圖片資源,andbase提供簡單的方法,幾步完成下載與顯示,並支持縮放,裁剪,緩存功能。
5.封裝了大量常見工具類。
包括日期,字元,文件,圖片等各種處理函數, 多而全。
6.用andbase大量減少handler的使用,而採用回調函數,代碼更整潔。
handler會產生大量代碼,並且不好維護,andbase對handler進行了封裝。
7.簡單輕量支持註解自動建表的ORM框架(支持一/多對多的關聯操作)。
寫sql,建表,工作量大,andbase提供更傻瓜非同步增刪改查工具類。
8.非同步請求http框架,網路請求標准化,支持文件上傳下載,get,post,進度顯示。
包含了非同步與http請求的工具類,實用。
2、XUtil框架
項目地址:https://github.com/wyouflf/xUtils
主要有四大模塊:
(1) 資料庫模塊:Android中的orm框架,一行代碼就可以進行增刪改查;
支持事務,默認關閉;
可通過註解自定義表名,列名,外鍵,唯一性約束,NOT NULL約束,CHECK約束等(需要混淆的時候請註解表名和列名);
支持綁定外鍵,保存實體時外鍵關聯實體自動保存或更新;
自動載入外鍵關聯實體,支持延時載入;
支持鏈式表達查詢,更直觀的查詢語義,參考下面的介紹或sample中的例子。
(2) 註解模塊:android中的ioc框架,完全註解方式就可以進行UI,資源和事件綁定;
新的事件綁定方式,使用混淆工具混淆後仍可正常工作;
目前支持常用的20種事件綁定,參見ViewCommonEventListener類和包com.lidroid.xutils.view.annotation.event。
(3) 網路模塊:支持同步,非同步方式的請求;
支持大文件上傳,上傳大文件不會oom;
支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT請求;
下載支持301/302重定向,支持設置是否根據Content-Disposition重命名下載的文件;
返迴文本內容的請求(默認只啟用了GET請求)支持緩存,可設置默認過期時間和針對當前請求的過期時間。
(4) 圖片緩存模塊:載入bitmap的時候無需考慮bitmap載入過程中出現的oom和android容器快速滑動時候出現的圖片錯位等現象;
支持載入網路圖片和本地圖片;
內存管理使用lru演算法,更好的管理bitmap內存;
可配置線程載入線程數量,緩存大小,緩存路徑,載入顯示動畫等...
3、ThinkAndroid框架
項目地址:https://github.com/white-cat/ThinkAndroid
主要有以下模塊:
(1) MVC模塊:實現視圖與模型的分離。
(2) ioc模塊:android中的ioc模塊,完全註解方式就可以進行UI綁定、res中的資源的讀取、以及對象的初始化。
(3) 資料庫模塊:android中的orm框架,使用了線程池對sqlite進行操作。
(4) http模塊:通過httpclient進行封裝http數據請求,支持非同步及同步方式載入。
(5) 緩存模塊:通過簡單的配置及設計可以很好的實現緩存,對緩存可以隨意的配置
(6) 圖片緩存模塊:imageview載入圖片的時候無需考慮圖片載入過程中出現的oom和android容器快速滑動時候出現的圖片錯位等現象。
(7) 配置器模塊:可以對簡易的實現配對配置的操作,目前配置文件可以支持Preference、Properties對配置進行存取。
(8) 日誌列印模塊:可以較快的輕易的是實現日誌列印,支持日誌列印的擴展,目前支持對sdcard寫入本地列印、以及控制台列印
(9) 下載器模塊:可以簡單的實現多線程下載、後台下載、斷點續傳、對下載進行控制、如開始、暫停、刪除等等。
(10) 網路狀態檢測模塊:當網路狀態改變時,對其進行檢
4、LoonAndroid
項目地址:https://github.com/gdpancheng/LoonAndroid
主要有以下模塊:
(1) 自動注入框架(只需要繼承框架內的application既可)
(2) 圖片載入框架(多重緩存,自動回收,最大限度保證內存的安全性)
(3) 網路請求模塊(繼承了基本上現在所有的http請求)
(4) eventbus(集成一個開源的框架)
(5) 驗證框架(集成開源框架)
(6) json解析(支持解析成集合或者對象)
(7) 資料庫(不知道是哪位寫的 忘記了)
(8) 多線程斷點下載(自動判斷是否支持多線程,判斷是否是重定向)
(9) 自動更新模塊
(10) 一系列工具類
5、volley
項目地址 :https://github.com/smanikandan14/Volley-demo
(1) JSON,圖像等的非同步下載;
(2) 網路請求的排序(scheling)
(3) 網路請求的優先順序處理
(4) 緩存
(5) 多級別取消請求
(6) 和Activity和生命周期的聯動(Activity結束時同時取消所有網路請求)
6、android-async-http
項目地址:https://github.com/loopj/android-async-http
文檔介紹:http://loopj.com/android-async-http/
(1) 在匿名回調中處理請求結果
(2) 在UI線程外進行http請求
(3) 文件斷點上傳
(4) 智能重試
(5) 默認gzip壓縮
(6) 支持解析成Json格式
(7) 可將Cookies持久化到SharedPreferences
7、Afinal框架
項目地址:https://github.com/yangfuhai/afinal
主要有四大模塊:
(1) 資料庫模塊:android中的orm框架,使用了線程池對sqlite進行操作。
(2) 註解模塊:android中的ioc框架,完全註解方式就可以進行UI綁定和事件綁定。無需findViewById和setClickListener等。
(3) 網路模塊:通過httpclient進行封裝http數據請求,支持ajax方式載入,支持下載、上傳文件功能。
(4) 圖片緩存模塊:通過FinalBitmap,imageview載入bitmap的時候無需考慮bitmap載入過程中出現的oom和android容器快速滑動時候出現的圖片錯位等現象。
FinalBitmap可以配置線程載入線程數量,緩存大小,緩存路徑,載入顯示動畫等。FinalBitmap的內存管理使用lru演算法,
沒有使用弱引用(android2.3以後google已經不建議使用弱引用,android2.3後強行回收軟引用和弱引用,詳情查看android官方文檔),
更好的管理bitmap內存。FinalBitmap可以自定義下載器,用來擴展其他協議顯示網路圖片,比如ftp等。同時可以自定義bitmap顯示器,
在imageview顯示圖片的時候播放動畫等(默認是漸變動畫顯示)。
總結框架結構,
ImageLoader框架(第8大框架)
UniversalImageLoader是用於載入圖片的一個開源項目,在其項目介紹中是這么寫的,
支持多線程圖片載入
提供豐富的細節配置,比如線程池大小,HTPP請求項,內存和磁碟緩存,圖片顯示時的參數配置等等;
提供雙緩存
支持載入過程的監聽;
提供圖片的個性化顯示配置介面;
Widget支持(這個,個人覺得沒必要寫進來,不過尊重原文)
其他類似的項目也有很多,但這個作為github上著名的開源項目被廣泛使用。第三方的包雖然好用省力,可以有效避免重復造輪子,但是卻隱藏了一些開發上的細節,如果不關注其內部實現,那麼將不利於開發人員掌握核心技術,當然也談不上更好的使用它,計劃分析項目的集成使用和低層實現。
開源框架android-async-http(第9大框架)
官網:https://github.com/loopj/android-async-http
Android-async-http開源框架可以是我們輕松的獲取網路數據或者向伺服器發送數據,使用起來也簡單,詳細請看官網:
到官網下載zip包,解壓,裡面有完整的代碼和各種版本的jar包和demo,源碼在library裡面,jar包在releases裡面。項目更新速度很快,老版本的回調是一個普通類,最新版是一個介面。
KJFrameForAndroid框架(第10大框架)
參考:http://www.codeceo.com/article/android-orm-kjframeforandroid.html
KJFrameForAndroid是一款基於Android的ORM和 IOC應用開發框架,封裝了很多Android開發中常用的功能,包括Android中對Bitmap的操作類庫。KJFrameForAndroid的設計非常精簡,利用KJFrameForAndroid,我們可以用最少的代碼完成很多豐富的Android功能應用,為Android開發者節省許多不必要的開發時間。
KJFrameForAndroid總共分為五大模塊:UILibrary,UtilsLibrary,HttpLibrary,BitmapLibrary,DBLibrary。
Android-async-http開源框架可以是我們輕松的獲取網路數據或者向伺服器發送數據,使用起來也簡單,詳細請看官網:
到官網下載zip包,解壓,裡面有完整的代碼和各種版本的jar包和demo,源碼在library裡面,jar包在releases裡面。項目更新速度很快,老版本的回調是一個普通類,最新版是一個介面。
B. Android又涼了那帶你看下Android開發前景如何
不管在任何行業,任何崗位,初級技術人才總是供大於求,都是不好找工作的,Android開發只是其中之一.
同樣,不管任何行業、崗位,技術過硬的也都是非常吃香的!
說到底,是Android涼了嗎?其實只是你涼了!
技術不過硬,就算轉去Java、大數據、人工智慧,還是會問出類似的問題:
身邊有很多同學都會問到:
我覺得吧,首先拋開其他因素,就拿人雲亦雲來說,在當下這個互聯網時代,很多技術一下子就火起來了,這個時候匹配的崗位需求肯定也多了,難道每次都想著換方向,轉崗?
顯然這個是不對的,這些火熱的技術肯定會慢慢趨於正常,那麼你又回到了原點。如果還是思路不變,那麼就會永遠的原地踏步。
轉行,就是拋棄自己現有的基礎,重新開始! 身邊也有不少Android開發的小夥伴轉行Java,但是他們對於目前的市場還是過於樂觀,Java市場競爭不大嗎?從0開始的你,甚至連應屆生都比不過……
就當前的手機使用人群佔比來說,Android是榜首這個毫無疑問,伴隨著5G時代的來臨,而iPhone目前還沒有一款真正意義上的5G手機,那麼Android會迎來一波熱潮。
用Android手機的人多,那麼肯定對於Android手機里APP的需求就會多。APP需求多了,那麼開發崗位的需求也多。對比以往來說,沒啥差別,甚至還有可能會更好。
就Android目前廣州的平均薪資是13000元+/月
薪酬范圍還是可以的,而且提升空間也不小,初略統計,普遍一個月2w到3w在有一定工作經驗裡面來說是比較合理的。
作為身處開發類崗位的大家或者還在糾結方向的大家,我覺得還是找准方向,深耕。技術有一點深度了,然後工作經驗也有了,那麼我相信距離穩定的高薪也就不遠了。
因為就目前形勢來說,對於企業,初級開發都比較好招,但是中級或以上的就比較難了,有很多公司在這上面花了很多時間,找簡歷,獵頭,主動聯系等等,最終也是無功而返。
這其實也就變相說明了,行業內中高端人才的稀缺。想要高薪,必先埋頭鑽研,自身達到一定高度,薪酬自然跟著上去。
換個角度,當你技術有一定深度的時候,對於一些其他技術,或多或少都會有所涉及的。這個時候技術的廣度也有了,大家還會覺得薪資會低嗎?
那麼,接下來我就帶著大家一起來看看,一線大廠的Android開發者都需要掌握哪些技能知識點呢?
參考下圖《 對標「騰訊65W"年薪Android高級工程師成長曲線 》:
一、JAVA 知識點匯總
1.1 JVM
1.2 static
1.3 final
1.4 String、StringBuffer、StringBuilder
1.5 異常處理
1.6 內部類
1.7 多態
1.8 抽象和介面
1.9 集合框架
1.10 反射
1.11 單例
1.12 線程
1.13 volatile
1.14 synchronized
1.15 Lock
1.16 引用類型
二、Android 知識點匯總
2.1 Activity
2.3 Service
2.4 BroadcastReceiver
2.5 ContentProvider
2.6 數據存儲
2.7 View
2.8 進程
2.9 Parcelable 介面
2.10 IPC
2.11 Window / WindowManager
2.12 Bitmap
2.13 屏幕適配
2.14 Context
2.15 SharedPreferences
2.16 消息機制
2.17 線程非同步
2.18 RecyclerView 優化
2.19 Webview
[圖片上傳失敗...(image-5ef002-1598925573832)]
三、Android 擴展知識點
3.1 ART
3.2 Apk 包體優化
3.3 Hook
3.4 Proguard
3.5 架構
3.6 Jetpack
3.7 NDK 開發
3.8 計算機網路基礎
3.9 類載入器
四、Android 開源庫源碼分析
4.1 LeakCanary
4.2 EventBus
五、設計模式匯總
5.1 設計模式分類
5.2 面向對象六大原則
5.3 工廠模式
5.4 單例模式
5.5 建造者模式
5.6 原型模式
5.7 適配器模式
5.8 觀察者模式
5.9 代理模式
5.10 責任鏈模式
5.11 策略模式
5.12 備忘錄模式
六、Gradle 知識點匯總
6.1 依賴項配置
七、常見面試演算法題匯總
7.1 排序
7.2 二叉樹
7.3 鏈表
7.4 棧 / 隊列
7.6 哈希表
7.7 堆 / 優先隊列
7.8 二叉搜索樹
7.9 數組 / 雙指針
7.10 貪心
7.11 字元串處理
7.12 動態規劃
7.13 矩陣
C. android開發框架有哪些
主要總結了7個好用的android 開發框架推薦給你:
一、 Afinal
Afinal是一個Android的ioc,orm框架,內置了四大模塊功能:,FinalBitmap,FinalDb,FinalHttp。通過,我們可以通過註解的方式進行綁定ui和事件。通過finalBitmap,我們可以方便的載入bitmap圖片,而無需考慮oom等問題。通過finalDB模塊,我們一行代碼就可以對android的sqlite資料庫進行增刪改查。通過FinalHttp模塊,我們可以以ajax形式請求http數據。
功能:
一個android的ioc,orm框架,內置了四大模塊功能:,FinalBitmap,FinalDb,FinalHttp。通過,我們可以通過註解的方式進行綁定ui和事件。通過finalBitmap,我們可以方便的載入bitmap圖片,而無需考慮oom等問題。通過finalDB模塊,我們一行代碼就可以對android的sqlite資料庫進行增刪改查。通過FinalHttp模塊,我們可遲戚以以ajax形式請求http數據。
優點:功能比較全面,文檔完善,代碼效率比較高。
缺點:沒有項目demo,框架的時間比較久,代碼冗餘比較多(這也是無可避免的),文檔比較老跟不上代碼更新進度。
二、 xUtils
xUtils:可以說是Afinal的升級版。
xUtils 包含了簡旦陪很多實用的android工具。
xUtils 支持大文件上傳,更全面的http請求協議支持(10種謂詞),擁有更加靈活的ORM,更多的事件註解支持且不受混淆影響...
xUitls 最低兼容android 2.2 (api level 8)
三、
是一個免費的開源的、簡易的、遵循Apache2開源協議發布的Android開發框架,其開發宗旨是簡單、快速的進行Android應用程序的開發,包含Android
mvc、簡易sqlite orm、ioc模塊、封裝Android
httpclitent的http模塊,具有快速構建文件緩存功能,無需考慮緩存文件的格式,都可以非常輕松的實現緩存,它還基於文件緩存模塊實現了圖片緩存功能,在android中載入的圖片的時候,對oom的問題,和對載入圖片錯位的問題都輕易解決。他還包括了一個手機開發中經常應用的實用工具類,如日誌管理,配置文件管理,android下載器模塊,網路切換檢測等等工具
四、 LoonAndroid
如果你想看ui方面的東西,這里沒有,想要看牛逼的效果這里也沒有。這只是純實現功能的框架,它的目標是節省代碼量,降低耦合,讓代碼層次看起來更清晰。整個框架一部分是網上的,一部分是我改的,為了適應我的編碼習慣,還有一部分像orm完全是網上的組件。在此感謝那些朋友們。
整個框架式的初衷是為了偷懶,之前都是一個功能一個jar,做項目的時候拉進去,這樣對於我來說依然還是比較麻煩。最後就導致我把所有的jar做成了一個工具集合包。
有很多框架都含有這個工具集合里的功能,這些不一定都好用,因為這是根據我個人使用喜歡來實現的,如果你們有自己的想法,可以自己把架包解壓了以後,源碼拉出來改動下。
目前很多框架都用到了註解,除了沒有入侵我們應用的代碼以外,其他的基本上都有,要麼是必須繼承框架裡面的activity,要麼是必須在activity的oncreat裡面調用某個方法。
整個框架式不同於,Roboguice等ioc框架,這是一個類似spring的實現方式。在整應用的生命周期中找到切入點,然後對activity的生命周期進行攔截,然後插入自己的功能。
五、
又叫KJLibrary,是一個android的orm 和 ioc
框架。同時封裝了android中的Bitmap與Http操作的框架,使其更加簡單易用;
的設計思想是通過封裝Android原生SDK中復雜的復雜操作而達到簡化Android應用級開發,最終實現快速而又安全的開發APP。我們提倡用最少的代碼,完成最多的操作,用最高的效率,完成最復雜的功能。
功能:
一個android的orm 和 ioc 框架。同時封裝了android中的Bitmap與Http操作的框架,使其更加簡單易用;
開發框架的設計思想是通過封攔蠢裝Android原生SDK中復雜的復雜操作而達到簡化Android應用級開發,最終實現快速而又安全的開發APP。總共分為五大模塊:UILibrary,HttpLibrary,DBLibrary。
六、 dhroid
dhroid 是基於android 平台,
極速開發框架,其核心設計目標是開發迅速、代碼量少、學習簡單、功能強大、輕量級、易擴展.使你更快,更好的開發商業級別應用
功能:
1.Ioc容器: (用過spring的都知道)視圖注入,對象注入,介面注入,解決類依賴關系
2.Eventbus: android平台事件匯流排框架,獨創延時事件,事件管理輕松
3.Dhnet: 網路http請求的解決方案,使用簡單,減少代碼,自帶多種網路訪問緩存策略
4.adapter模塊: 數據綁定輕松,不用寫多餘的adapter,天生網路支持(一行代碼搞定載入,刷新問題)
5.DhDb: android中sqlite的最輕量orm框架(增刪改查輕松搞定)
6.Perference: android自帶Perference 升級版,讓你的Perference更強大,更方便
工具集合 JSONUtil(安全處理json),ViewUtil(數據綁定更快) (非同步任務工具)...
七、
SmartAndroid是一套給
Android開發者使用的應用程序開發框架和工具包。它提供一套豐富的標准庫以及簡單的介面和邏輯結構,其目的是使開發人員更快速地進行項目開發。使用
SmartAndroid可以減少代碼的編寫量,並將你的精力投入到項目的創造性開發上。
功能:
SmartAndroid 擁有全范圍的類庫,可以完成大多數通常需要的APP開發任務,包括:非同步網路操作相關所有功能、強大的圖片處理操作、輕量級ORM資料庫Sqlite庫、zip操作、動畫特效、Html等解析採集、事件匯流排EventBus/Otto、Gson(Json)、AQuery、主流所有UI控制項(例如:ActionbarSherlock,SlidingMenu,BottomView,Actionbar,DragListView等10多種UI庫)等。
D. 京東hotkey源碼解析
京東hotkey是一個經過京東大促驗證的hotkey防禦中間件,大概原理是通過上報key訪問數到統計伺服器集群,統計伺服器集群將hotkey通知到客戶端,讓hotkey能緩存到本地內存中,做到毫秒級的Scale-Out。處理方式有點像美團cat實時收集數據進行統計,只不過美團cat沒有反向通知邏輯而已。非常貼亂豎近工作實踐,值得一看。
首先看一下緩存入口Cache的get方法,JdHotKeyStore.getValue是獲取hotkey的方法,並且會進行訪問嘩薯大次數的統計上報,如果獲取到hotkey不為空,則直接返回,否則從redis獲取並調用JdHotKeyStore.smartSet判斷是否有hotkey,有則設置值,最後返回。
JdHotKeyStore.getValue會先調用inRule校驗此key是否有對應規則,如果沒有對應規則則不處理,然後調用getValueSimple從本地內存中獲取hotkey的存儲對象ValueModel,如果沒有獲取到,則調用HotKeyPusher.push開始計數;如果獲取到,會調用isNearExpire判斷是否快過期了,如果是也計數,然後取出ValueModel里的value是否有設置對應值,有才返回。最後調用KeyHandlerFactory.getCounter().collect進行對應規則的計數。下面來一步步分析此流程。
inRule會去KeyRule緩存中獲取對應的規則,經過層層調用會到KeyRuleHolder的findByKey方法,然後繼續調用其findRule方法選擇對應的KeyRule,如果沒有KeyRule就直接返回了,否則會拿到它的ration(hotkey緩存時間),拿到對應ration的本地緩存。實際上這里為了方法的通用性,用了get來代替contain的判斷。
findRule的邏輯比較特別,作者已經留下了注釋,優先全匹配->prefix匹配-> * 通配,這樣做是為了更精確選擇對應的規則。比如配置了sku_的前綴規則,但是茅台sku的流量突升,需要針對茅台sku的本地緩存再長一點時間讓系統平穩渡過高峰期,那就配置一個sku_moutai_sku_id的全匹配規則,這樣不會干擾到其他sku的緩存規則。
那麼KEY_RULES的規則是怎麼來的呢?這就要說到etcd了,其實可以把etcd當做zookeeper,也有對配置crud,然後通知客戶端的功能。這里是做了定時拉取+監聽變化的雙重保證,這里跟攜程apollo的處理非常像:不要把雞蛋放在一個籃子,兜底功能真的很重要。每5秒定時從etcd拉取規則,開啟監聽器有變化就去etcd拉取規則。fetchRuleFromEtcd從ectd的rule_path獲取rules,然後轉化成ruleList繼續調用notifyRuleChange進行本地處理。
notifyRuleChange會往EventBus發送KeyRuleInfoChangeEvent的通知,進而進入KeyRuleHolder的putRules方法,這里可以看到維護了KEY_RULES和RULE_CACHE_MAP。
回到原有流程,getValueSimple方法的鏈路比較長,主要是通過key的規則,獲取到對應的ration,然後從對應ration的本地緩存中獲取ValueModel。
接下來是HotKeyPusher.push,如果是remove則在etcd創建一個節點然後再刪除,達到集群刪除的效果。如果是探測並且key在規則內,則調用KeyHandlerFactory.getCollector().collect進行統計。
KeyHandlerFactory.getCollector().collect方法交替使用兩個map,對count進行累加,這樣清理map的時候就不需要停頓了,交替使用是避免停頓的有效方手納式。
接回上文,還有一個 KeyHandlerFactory.getCounter().collect收集的是規則的訪問次數,也是取到對應的規則,然後對規則的訪問總數、熱次數進行累加。
兩個指標的收集已經分析完畢,那怎麼發送到worker呢?來到PushSchelerStarter,這里會啟動對兩個指標的定時線程池,分別會定時調用NettyKeyPusher的send和sendCount方法。
NettyKeyPusher的send和sendCount方法都是為統計數據選擇對應的worker然後進行請求,chooseChannel就是根據key哈希到其中一個worker上,然後發送請求即可。
最後當worker統計到hotkey時,client需要接收worker推送過來的hotkey進行存儲,可以看到NettyClientHandler會向EventBus發送ReceiveNewKeyEvent事件,ReceiveNewKeyListener收到此事件後將調用receiveNewKeyListener.newKey,將hotkey放到本地緩存,client端的處理流程就結束了。
由上文可知,client與worker的交互只有推送統計數據到worker,worker接收處理,最後推送hotkey到client。因此worker端只需要分析兩個部分:統計數據匯總、推送hotkey。
首先看到HotKey的處理邏輯是在HotKeyFilter中,首先會對totalReceiveKeyCount進行累加,然後調用publishMsg,如果統計信息超時1秒或者在白名單中就不處理,否則繼續調用keyProcer.push。
keyProcer.push將未過時的統計信息丟進queue中。
worker端會開啟指定數量的KeyConsumer,不斷消費queue中的統計數據。根據統計數據的類型調用KeyListener的removeKey和newKey。
KeyListener的removeKey和newKey方法對Cache中的滑動窗口SlidingWindow進行刪除或者累加,刪除或者達到一定訪問數就會推送到根據appname選出所有client進行推送。
京東的hotkey處理是通過計數來動態判斷是否為hotkey,然後緩存再本地內存中,做到毫秒級的scale out。那還有沒有其他解決方案?下面是我的觀點:
1.如果面對一些緩存key很少的場景,比如活動頁信息(同時進行的活動頁不可能超過1000),完全就可以直接將緩存放在本地內存中,到了刷新時間就從redis拉取最新緩存即可,不需要動態計算hotkey。也就是常見的多級緩存。
2.同樣是動態判斷hotkey,但會將hotkey遷移到專門的、更多節點、更高性能的hotkey redis集群中,集群中每個節點都有同一個hotkey緩存,這樣就可以做到請求的分散,避免流量都流向同一個redis節點,判斷是hotkey就去hotkey集群中取,不需要存在本地內存中了,維護起來會比較簡單。