`
一江春水邀明月
  • 浏览: 79102 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

基于Redis的Notification设计

 
阅读更多

需求:

这个功能开发的直接需求是为了提醒操作员即使处理库位补货, 在用户操作分拣波次操作以后, 会出现有库位库存为负数, 这种情况下需要有消息通知机制通知相关人员对相应库位进行补货处理;

1. 通知实体: 被通知的用户实体可能是具体到某些登录用户, 也可能是某些Role 下的用户
2. 通知状态: 消息窗口会采用浮动窗口告知用户有N条记录未读, 以及未读消息摘要; 消息在被用户阅读之前是未读状态, 读取以后会改变状态为已读状态; 消息窗口不会通知用户已读消息。
3. 消息定制: 应该提供能力供实施部门方便的定制一些业务规则, 来添加简单的新的消息类型和新的消息产生机制, 比如实施部门可以配置定时任务扫描DB中的业务表, 根据规则发现异常数据, 并把相关信息以消息形式发送给WMS 客户端;

设计:

总体设计

客户端如何获取消息:

  主流的方式无法长连接推送和客户端轮询的拉取的方式, 为了简化Server 和客户端的开发复杂度, 我们选择了客户端轮询的方式, 这样可以直接沿用我们WMS 中已有的WebService 接口的方式来暴露消息;

存储:

 消息体:

   考虑到通知消息属于非核心业务, 并且对轮询的方式会产生大量的请求, 所以我们不打算使用DB 做消息的存储, 以减少大量低优先级的db 访问来拖累DB 性能和稳定性;所以我们采用redis 来存储每个订阅者订阅的消息;

 消息订阅定义:

  要实现消息订阅的可配置, 需要对消息类型, 仓库, 订阅者进行关联, 这些信息存储在DB中, 在系统启动的时候会把这些信息Load 到redis 中, 后续的界面操作针对这个数据的增删改会同步修改redis 中的缓存数据;

数据格式:

1. 客户端访问App Server的接口是以xml 格式的方式进行对接;

2. Server 内部存储在Redis 中的数据以protobuf 的格式进行序列化和反序列化;具体在实现上使用Protostuff 生成protobuf runntime schema 对java 对象notification 进行序列化反序列化

数据结构

1. DB

 消息订阅定义:

  已有表添加数据:

  GV_SYS_CODECLASS 中添加 code = 'SUBSCRIBE_TYP',  CNCATEGROYNAME = '订阅类别的记录'

  GV_SYS_CODEINFO 中添加 code = 'REP_NOTICE', CNCATEGROYNAME  =  '补货通知', codeclass_id = #1 中的ID  的记录

  创建新表 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 中存储的

 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 存储 Subscriber 集合, 这个集合的目的是为了能够取到当前系统中所有subscriber, 然后可以遍历 WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID 键值列表, 删除每个键值所对应的有序集合中的过期通知; WMS_SUBSCRIBER_TYPE _$messageTypeId_$whID 键值对存储的是从表GV_SUBSCRIBER 中加载的订阅者集合, 每种类型的通知在每个仓库中的订阅者(User 或Role)

其中WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID 往Ordered Set 中新增element 的时候以该notification 当前产生的时间戳为排序字段;

接口

1.通知消息产生:

通知消息产生的业务方需要知道当前消息的通知类别ID 和需要发送的逻辑仓库ID

 测试用例中的模拟代码如下:

 Notification notice = new Notification();
 notice.setId(UUID.randomUUID().toString());
 notice.setTitle("消息标题" + dateformat.format(new Date()));
 notice.setBody("消息体");
 notice.setCreateTime(System.currentTimeMillis());  //必须是当前时间戳
 notice.setExpireTime(60*30);
 notice.setWhId(119240L);
 notice.setMessageTypeId(124719L);

nManager.addNotice(notice);

NotificationManager 会从redis 缓存中获取 WMS_SUBSCRIBER_TYPE _$messageTypeId_$whID所对应的所有Subscriber,然后会针对每一个Subscriber 调用redis 接口

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

2. 前端消息获取:

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

 客户端程序需要维护 whid, lastFetchTimeStamp 信息在本地, 每次请求把这个时间戳信息发送给服务器端,

客户端行为的伪代码就是

lastFetchTimeStamp = get($whid);

$newTimeStamp = 新的时间戳;


if($lastFetchTimeStamp& ==null ) $lastFetchTimeStamp = 默认的当前时间- 3天

call Server

展示新消息

set ($whid, 返回Notification 对象列表中创建时间最大的时间戳 )

服务器端的行为会把Notification在给定时间戳之后的 Ordered set 中的元素返回给客户端

 

过期消息删除

过期消息删除使用定时任务, 根据给定TTL, 即时出当前时间减去TTL 的时间得到超时时间点, 在这个时间点之后的Notification 都应该被删除;

 

maxScore = nowTimeStamp - TTL ;

shardedJedis.zremrangeByScore(WMS_SUBSCRIBERED_MESSAGES_$subscriberId_$whID, 0D, maxScore);
 

 

 

 

分享到:
评论
1 楼 一江春水邀明月 2013-01-17  
tumblr也是选择类似的设计做消息通知 http://www.w3ccollege.org/redis/staircar-tumblr-of-redis-cluster-control-layer.html

不过他的方案是按Range 删除, 我的方案是按照超时按Score 删除。

相关推荐

    nagios监控redis控件

    1. **check_redis.php**:这是一个基于PHP编写的Nagios插件,用于与Redis服务器通信并收集状态数据。它通常会发送特定的Redis命令(如INFO、CLIENT LIST等)来获取服务器的统计信息,然后根据预设的阈值判断是否发出...

    Redis 中文文档.pdf

    Redis 的集群规范提供了 Redis 集群的设计、安装、管理等方面的详细信息,帮助开发者快速理解和使用 Redis 集群。 本文档为 Redis 的中文文档,全面介绍了 Redis 的各个方面,帮助开发者快速理解和使用 Redis。

    Redis 中文文档-01061629.pdf

    Redis 是一种开源的、基于内存的数据存储系统,可以用作数据库、缓存和消息队列等。以下是 Redis 中文文档的详细知识点: 键空间通知(Key Space Notification) 键空间通知使得客户端可以通过订阅频道或模式,来...

    Redis 中文文档

    以上是基于给定的Redis中文文档的部分内容提取出的关键知识点。Redis以其出色的性能、丰富的数据类型和灵活的部署方式,在众多应用场景中发挥着重要作用。掌握Redis的基本原理和常用命令对于开发高效稳定的应用至关...

    javaAtTurnToTech:基于Redis、Jedis、多线程和APNSPShy构建的推送通知队列系统后端框架

    JavaAtTurnToTech 是一个专为构建推送通知队列系统后端框架而设计的项目,它结合了Redis作为数据缓存、Jedis作为Redis客户端、多线程技术以提高处理能力,以及APNS(Apple Push Notification Service)和Pushy库用于...

    深入浅出Redis-redis哨兵集群.docx

    - **通知(Notification)**:当检测到某个实例故障时,Sentinel会发送警告给管理员或者相关的应用程序。 - **故障转移(Failover)**:当主服务器故障时,Sentinel会触发故障转移,将一个从服务器提升为主服务器...

    sonic-sairedis:到SONiC项目中使用的Redis数据库的SAI对象接口

    SAI Redis提供了一个基于redis数据库的SAI redis服务。 它包含两个主要组件,1)一个将SAI对象放入redis数据库的SAI库,2)一个将SAI对象放入ASIC的同步对象。 入门 安装 在安装之前,添加密钥和软件包源: sudo ...

    android push notification XPMM源码

    这些接口通常基于HTTP/HTTPS,使用RESTful设计原则,可能使用JWT进行身份验证。 2. 消息构建:服务端根据业务需求构造推送消息,包括标题、内容、附加数据等,并确保兼容不同的推送服务(如FCM、APNs等)。 3. ...

    springboot基于Java的民宿管理系统论文-java-文档-springboot基于Java的民宿管理系统

    ### Spring Boot 基于 Java 的民宿管理系统设计与实现 #### 一、系统概述与背景 随着信息技术的迅速发展,各类管理系统不断涌现,为不同领域提供了便利高效的解决方案。本研究聚焦于民宿行业的信息化管理需求,...

    NotificationBundle:实时通知,支持多推送器(websocket,redis),PubSub

    Gos Notification是一个Symfony2软件包,旨在将实时通知系统引入您的应用程序体系结构。 允许使用多个推送程序,例如websocket或redis。 通知系统基于pubsub体系结构。 它是如何工作的 截屏 更多文档即将发布

    即时通讯系统设计的文档 包括一个毕业论文

    7. **推送服务**:为了实现实时通知,IM系统通常会集成第三方推送服务,如Google的Firebase Cloud Messaging (FCM) 或Apple的Push Notification Service (APNs),以确保即使在应用程序后台运行时也能及时收到消息。...

    消息系统设计V1.11

    与iOS的APNs(Apple Push Notification service)或Android的FCM(Firebase Cloud Messaging)等平台的推送服务进行交互,为移动应用用户提供即时消息。设计时需考虑不同操作系统的需求,优化电池和网络使用。 4. ...

    毕业设计 IM 聊天

    - **TCP/IP协议**:IM系统通常基于TCP/IP协议栈,因为它提供可靠的数据传输,确保消息不丢失、不重复。 - **Socket编程**:用于建立客户端与服务器之间的连接,发送和接收数据。在Python中,可以使用socket库来...

    okky-notification

    总之,"okky-notification"是一个基于Java构建的、使用MongoDB存储的、提供REST接口的通知服务。虽然目前依赖于客户端轮询,但通过引入实时通信技术、优化数据库设计和提升服务架构,可以进一步提升其性能和用户体验...

    高仿陌陌源码最新版开源啦

    4. **推送通知**:为了提高用户体验,应用需要实现推送通知,这通常通过第三方推送服务如Firebase Cloud Messaging (FCM) 或Apple Push Notification service (APNs) 实现。 5. **前端界面设计**:高仿陌陌的源码会...

    阿里26款Java开源项目(附源码).docx

    6. **apns4j**:这是一个Java实现的Apple Push Notification Service客户端,帮助企业实现在iOS设备上的消息推送。 7. **TDDL**:TDDL是一个分布式数据层,提供主备切换、读写分离和动态数据库配置等功能,简化了...

    chatcord-源码.rar

    3. **后端架构**:Chatcord的后端可能基于Node.js、Python的Django或Flask,或者Java的Spring Boot等,负责处理用户的请求、存储和检索数据。 4. **数据库设计**:源码可能涉及到MySQL、PostgreSQL或MongoDB等...

    即时通信程序(类似QQ)

    数据库的选择和设计直接影响到系统的性能和扩展性,常见的选择有MySQL、MongoDB、Redis等。 8. **用户体验优化**: 实时性是即时通信软件的关键特性,因此,优化网络延迟、减少消息延迟至关重要。此外,UI/UX设计...

    ChatDemo

    4. **数据库设计**:为了存储用户信息、聊天记录和其他元数据,ChatDemo可能使用了关系型数据库(如MySQL、PostgreSQL)或非关系型数据库(如MongoDB、Redis)。数据库设计应考虑到性能、扩展性和数据安全性。 5. *...

    全套源码-即时通信系统(Java实现)

    5. **推送服务**:对于离线消息的处理,即时通信系统通常会引入消息推送服务,如Google的Firebase Cloud Messaging (FCM) 或Apple的Push Notification Service (APNS)。Java库如GcmNetworkManager和...

Global site tag (gtag.js) - Google Analytics