基于间隔推送全量更新数据状态的设计方法
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
假如有個(gè)直播間,在數(shù)據(jù)有更新的時(shí)候,能及時(shí)反映在客戶端上。通信方式來說,有兩種:
1、拉取模式。
2、推送+拉取模式(或者純推送)
?
拉取模式,技術(shù)簡單。但輪詢間隔設(shè)置比較難;如果設(shè)置得太大,數(shù)據(jù)更新不及時(shí);如果設(shè)置得太小,那么服務(wù)端可能會多余很多無用請求(數(shù)據(jù)本來并無更新)。
推送模式,可以在數(shù)據(jù)有更新的情況下,才選擇通知客戶端。但如果在同一秒內(nèi),數(shù)據(jù)更新得太頻繁,可能會造成推送風(fēng)暴。
這時(shí)候做一個(gè)簡單優(yōu)化,如果距離上一次推送不超過一秒,當(dāng)前數(shù)據(jù)更新不推送。那么也會有個(gè)問題,最后更新的數(shù)據(jù),可能在很長一段時(shí)間內(nèi)都更新不到客戶端。
下面介紹一個(gè)設(shè)計(jì)方法,如下是一個(gè)時(shí)間軸:
0? ? 0.2? ? ? ? ? ? ? ? ? ? ? ? ?1? ? ?1.3? ? ? ? ? ? ? ? ? ? ? ? 2? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 4
|------------------------|------------------------|------------------------|------------------------|
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0? ? 0.2? ? ? ? ? ? ? ? ? ? ? ? ?1? ? ? 1.3? ? ? ? ? ? ?
采用ThreadPoolExecutor來處理時(shí)間軸上面0/0.2/1/1.3的請求Task,而BlockingQueue則采用DelayedQueue來實(shí)現(xiàn),進(jìn)入線程池的任務(wù)的Task都實(shí)現(xiàn)Delayd接口并且設(shè)置延遲1秒。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)那么Task真正執(zhí)行的時(shí)間點(diǎn)就如時(shí)間軸下面的數(shù)字。而由于設(shè)置了規(guī)則,距離上次推送間隔小于1秒的時(shí)候,不再繼續(xù)推送。所以 紅色的數(shù)字 0 和 1 表示會執(zhí)行推送,而 藍(lán)色的數(shù)字 0.2 和 1.3 就不會推送。那么反饋到客戶端層面,當(dāng)?紅色的數(shù)字 0 執(zhí)行推送,會把當(dāng)時(shí) 綠色的0/0.2/1狀態(tài)推送給客戶端(因?yàn)槭侨扛?#xff0c;所以只需要查詢當(dāng)前最新數(shù)據(jù));而當(dāng) 紅色的數(shù)字 1 執(zhí)行推送,會把當(dāng)時(shí) 綠色的1.3狀態(tài)推送給客戶端。那么這個(gè)過程中,最晚的更新數(shù)據(jù)也不會超過1秒的延遲到達(dá)客戶端。同時(shí),只發(fā)生了兩次推送。
上面的任務(wù)執(zhí)行過程中,涉及到上一次推送的時(shí)間變量的比較。那么這個(gè)時(shí)間變量存儲在哪里呢?
簡單的單進(jìn)程,當(dāng)然是在進(jìn)程內(nèi)定義一個(gè)變量就完事了。
假如是多進(jìn)程,那么為了最大化優(yōu)化性能邏輯,我們可以分別設(shè)置本地變量緩存以及全局的redis變量緩存。方法有很多,下面只介紹一種同步方式:
當(dāng)進(jìn)程內(nèi)的任務(wù)執(zhí)行,先對比本地變量;如果系統(tǒng)時(shí)間減去本地變量小于一秒,那么不繼續(xù)執(zhí)行任務(wù);如果系統(tǒng)時(shí)間減去本地變量大于一秒,那么通過redis的get獲取到上一次推送的時(shí)間戳;如果系統(tǒng)時(shí)間減去該全局時(shí)間戳小于一秒,那么不繼續(xù)執(zhí)行任務(wù)并更新本地緩存,如果系統(tǒng)時(shí)間減去該全局時(shí)間戳大于一秒,通過redis的getset(value是系統(tǒng)時(shí)間)返回的全局時(shí)間戳,這時(shí)的時(shí)間戳如果還大于1秒那么就推送并且更新本地緩存為當(dāng)前系統(tǒng)時(shí)間,否則不繼續(xù)執(zhí)行(其它進(jìn)程執(zhí)行了推送)。
?
轉(zhuǎn)載于:https://my.oschina.net/u/223522/blog/1560038
總結(jié)
以上是生活随笔為你收集整理的基于间隔推送全量更新数据状态的设计方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 枚举windows进程
- 下一篇: 关于WIN10下NVIDIA安装驱动后没