小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

基于Redis的Notification設(shè)計(jì)

 KILLKISS 2015-04-16

需求:

這個(gè)功能開(kāi)發(fā)的直接需求是為了提醒操作員即使處理庫(kù)位補(bǔ)貨, 在用戶操作分揀波次操作以后, 會(huì)出現(xiàn)有庫(kù)位庫(kù)存為負(fù)數(shù), 這種情況下需要有消息通知機(jī)制通知相關(guān)人員對(duì)相應(yīng)庫(kù)位進(jìn)行補(bǔ)貨處理;

1. 通知實(shí)體: 被通知的用戶實(shí)體可能是具體到某些登錄用戶, 也可能是某些Role 下的用戶
2. 通知狀態(tài): 消息窗口會(huì)采用浮動(dòng)窗口告知用戶有N條記錄未讀, 以及未讀消息摘要; 消息在被用戶閱讀之前是未讀狀態(tài), 讀取以后會(huì)改變狀態(tài)為已讀狀態(tài); 消息窗口不會(huì)通知用戶已讀消息。
3. 消息定制: 應(yīng)該提供能力供實(shí)施部門(mén)方便的定制一些業(yè)務(wù)規(guī)則, 來(lái)添加簡(jiǎn)單的新的消息類型和新的消息產(chǎn)生機(jī)制, 比如實(shí)施部門(mén)可以配置定時(shí)任務(wù)掃描DB中的業(yè)務(wù)表, 根據(jù)規(guī)則發(fā)現(xiàn)異常數(shù)據(jù), 并把相關(guān)信息以消息形式發(fā)送給WMS 客戶端;

設(shè)計(jì):

總體設(shè)計(jì)

客戶端如何獲取消息:

  主流的方式無(wú)法長(zhǎng)連接推送和客戶端輪詢的拉取的方式, 為了簡(jiǎn)化Server 和客戶端的開(kāi)發(fā)復(fù)雜度, 我們選擇了客戶端輪詢的方式, 這樣可以直接沿用我們WMS 中已有的WebService 接口的方式來(lái)暴露消息;

存儲(chǔ):

 消息體:

   考慮到通知消息屬于非核心業(yè)務(wù), 并且對(duì)輪詢的方式會(huì)產(chǎn)生大量的請(qǐng)求, 所以我們不打算使用DB 做消息的存儲(chǔ), 以減少大量低優(yōu)先級(jí)的db 訪問(wèn)來(lái)拖累DB 性能和穩(wěn)定性;所以我們采用redis 來(lái)存儲(chǔ)每個(gè)訂閱者訂閱的消息;

 消息訂閱定義:

  要實(shí)現(xiàn)消息訂閱的可配置, 需要對(duì)消息類型, 倉(cāng)庫(kù), 訂閱者進(jìn)行關(guān)聯(lián), 這些信息存儲(chǔ)在DB中, 在系統(tǒng)啟動(dòng)的時(shí)候會(huì)把這些信息Load 到redis 中, 后續(xù)的界面操作針對(duì)這個(gè)數(shù)據(jù)的增刪改會(huì)同步修改redis 中的緩存數(shù)據(jù);

數(shù)據(jù)格式:

1. 客戶端訪問(wèn)App Server的接口是以xml 格式的方式進(jìn)行對(duì)接;

2. Server 內(nèi)部存儲(chǔ)在Redis 中的數(shù)據(jù)以protobuf 的格式進(jìn)行序列化和反序列化;具體在實(shí)現(xiàn)上使用Protostuff 生成protobuf runntime schema 對(duì)java 對(duì)象notification 進(jìn)行序列化反序列化

數(shù)據(jù)結(jié)構(gòu)

1. DB

 消息訂閱定義:

  已有表添加數(shù)據(jù):

  GV_SYS_CODECLASS 中添加 code = 'SUBSCRIBE_TYP',  CNCATEGROYNAME = '訂閱類別的記錄'

  GV_SYS_CODEINFO 中添加 code = 'REP_NOTICE', CNCATEGROYNAME  =  '補(bǔ)貨通知', codeclass_id = #1 中的ID  的記錄

  創(chuàng)建新表 GV_SUBSCRIBER

CREATE TABLE GV_SUBSCRIBER
 ( "ID" NUMBER(19,0) NOT NULL ENABLE,
 //其他省略
 "WHID" NUMBER(19,0),
 "SUBSCRIBERID" VARCHAR2(255 CHAR),
 "SUBSCRIBERTYPE" VARCHAR2(255 CHAR),
 "MESSAGETYPE_ID" NUMBER(19,0),
  PRIMARY KEY ("ID")

 )

2. Redis

    Redis 中存儲(chǔ)的

 WMS_SUBSCRIBERS -->Set of subscriber

 WMS_SUBSCRIBER_TYPE _$messageTypeId_$whID --> Set of subscriber

 WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID --> Ordered set of notification

 以 “WMS_SUBSCRIBERS” 為key 存儲(chǔ) Subscriber 集合, 這個(gè)集合的目的是為了能夠取到當(dāng)前系統(tǒng)中所有subscriber, 然后可以遍歷 WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID 鍵值列表, 刪除每個(gè)鍵值所對(duì)應(yīng)的有序集合中的過(guò)期通知; WMS_SUBSCRIBER_TYPE _$messageTypeId_$whID 鍵值對(duì)存儲(chǔ)的是從表GV_SUBSCRIBER 中加載的訂閱者集合, 每種類型的通知在每個(gè)倉(cāng)庫(kù)中的訂閱者(User 或Role)

其中WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID 往Ordered Set 中新增element 的時(shí)候以該notification 當(dāng)前產(chǎn)生的時(shí)間戳為排序字段;

接口

1.通知消息產(chǎn)生:

通知消息產(chǎn)生的業(yè)務(wù)方需要知道當(dāng)前消息的通知類別ID 和需要發(fā)送的邏輯倉(cāng)庫(kù)ID

 測(cè)試用例中的模擬代碼如下:

 Notification notice = new Notification();
 notice.setId(UUID.randomUUID().toString());
 notice.setTitle("消息標(biāo)題" + dateformat.format(new Date()));
 notice.setBody("消息體");
 notice.setCreateTime(System.currentTimeMillis());  //必須是當(dāng)前時(shí)間戳
 notice.setExpireTime(60*30);
 notice.setWhId(119240L);
 notice.setMessageTypeId(124719L);

nManager.addNotice(notice);

NotificationManager 會(huì)從redis 緩存中獲取 WMS_SUBSCRIBER_TYPE _$messageTypeId_$whID所對(duì)應(yīng)的所有Subscriber,然后會(huì)針對(duì)每一個(gè)Subscriber 調(diào)用redis 接口

向有序集合   WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID --> Ordered set of notification 中添加Notfication

2. 前端消息獲取:

接口: PackNotificationVo listNotifications(
 ClientProperty clientProperty, Long whId, List<Long> subscriberIdList, Long lastFetchTimeStamp)

 客戶端程序需要維護(hù) whid, lastFetchTimeStamp 信息在本地, 每次請(qǐng)求把這個(gè)時(shí)間戳信息發(fā)送給服務(wù)器端,

客戶端行為的偽代碼就是

lastFetchTimeStamp = get($whid);

$newTimeStamp = 新的時(shí)間戳;


if($lastFetchTimeStamp& ==null ) $lastFetchTimeStamp = 默認(rèn)的當(dāng)前時(shí)間- 3天

call Server

展示新消息

set ($whid, 返回Notification 對(duì)象列表中創(chuàng)建時(shí)間最大的時(shí)間戳 )

服務(wù)器端的行為會(huì)把Notification在給定時(shí)間戳之后的 Ordered set 中的元素返回給客戶端

 

過(guò)期消息刪除

過(guò)期消息刪除使用定時(shí)任務(wù), 根據(jù)給定TTL, 即時(shí)出當(dāng)前時(shí)間減去TTL 的時(shí)間得到超時(shí)時(shí)間點(diǎn), 在這個(gè)時(shí)間點(diǎn)之后的Notification 都應(yīng)該被刪除;

 

Java代碼  收藏代碼
  1. maxScore = nowTimeStamp - TTL ;  
  2.   
  3. shardedJedis.zremrangeByScore(WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID, 0D, maxScore);  
  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多