web消息通知系统设计问题
一般网站上都会消息提醒通知,如一个用户给另一个用户发了一条站内信,那么就会在网站顶部的导航栏上就会有一个消息提醒的数字来提示您有新消息。
上面只是一个简单例子,在实际项目中可能就会有多种类型的提醒,如某个用户给你留言了,就显示提醒“新留言x条”或者“新回复y条”等等吧。
我打算设计成把所有类型的消息提醒统一的放到一张表(notice)里,并标记用户是否已处理了这条消息提醒,在网站的前台就可以只统计这一张表就行了,比如用户A给用户B发送了一条私信,就在notice表里插入一条新的未读消息提醒,用来提醒用户,当用户B查看完成私信后,再回到这张notice表标记为已处理或者直接删除。
但是大数据量或高并发的时候就会存在一个问题,当用户已经查看完了新收到的私信后,去notice表做标记处理时,可能由于种种原因其对应的“未读消息提醒”还没有写进去,这时候就出问题了,当用户去请求是否有“未读消息提醒”时,刚好又写进去了,然后就提示用户有“新消息”,但是实际上用户早已处理掉了,只不过就是“未读消息提醒”延时了。
如果说统计新消息提醒,去各个业务(如私信,留言)中单独统计,然后合并,再通知给用户,这样做的话,怎么称得上是“消息通知系统”呢?总觉得这样是不合理的
对于消息通知系统,我的notice表是否有存在的意义呢,大家是怎么设计的?
回复内容:
一般网站上都会消息提醒通知,如一个用户给另一个用户发了一条站内信,那么就会在网站顶部的导航栏上就会有一个消息提醒的数字来提示您有新消息。
上面只是一个简单例子,在实际项目中可能就会有多种类型的提醒,如某个用户给你留言了,就显示提醒“新留言x条”或者“新回复y条”等等吧。
我打算设计成把所有类型的消息提醒统一的放到一张表(notice)里,并标记用户是否已处理了这条消息提醒,在网站的前台就可以只统计这一张表就行了,比如用户A给用户B发送了一条私信,就在notice表里插入一条新的未读消息提醒,用来提醒用户,当用户B查看完成私信后,再回到这张notice表标记为已处理或者直接删除。
但是大数据量或高并发的时候就会存在一个问题,当用户已经查看完了新收到的私信后,去notice表做标记处理时,可能由于种种原因其对应的“未读消息提醒”还没有写进去,这时候就出问题了,当用户去请求是否有“未读消息提醒”时,刚好又写进去了,然后就提示用户有“新消息”,但是实际上用户早已处理掉了,只不过就是“未读消息提醒”延时了。
如果说统计新消息提醒,去各个业务(如私信,留言)中单独统计,然后合并,再通知给用户,这样做的话,怎么称得上是“消息通知系统”呢?总觉得这样是不合理的
对于消息通知系统,我的notice表是否有存在的意义呢,大家是怎么设计的?
关于消息系统的设计,肯定是需要一个数据表记录通知的,比如Notice表,至于这个通知可能有很多类型,就像你说的 私信和留言,这些在设计中都可以通过字段表示,这里分享下 Worktile 中 Notice的数据结构设计。
{ nid: { type: String, unique: true }, published: { type: Number, default: Date.now }, verb: { type: String }, template: { type: String }, is_read: { type: Number, index: true, default: 0 }, is_pending: { type: Number, index: true, default: 0 }, filter: { ftype: { type: String } }, sender: { type: Actor }, receiver : { type: String , index: true}, data: { entity: { type: Entity }, source: { type: Entity }, target: { type: Entity } } }
具体细节设计可以参考 activity 的一个标准
至于你说的消息高并发的问题其实是没有问题的,你标记完未读消息为已读后在切换页面,这是再读取未读消息前面的标记为已读应该早就处理完了。除非你系统高并发的程度已经达到系统瘫痪了,在没有遇到瓶颈的时候不需要过度优化,即使到达瓶颈也有解决方案的,你可以把所有未读的消息放到内存或者redis中来提高性能。
上面说的是数据结构方面的东西,一般web的消息都是实时更新的,意思就是:你没有刷新页面,此时来消息了,应该立即显示未读消息多少条。关于实时消息系统的做法要取决于你服务端用的什么语言。Node.js+socket.io
就很容易做到,我们的产品Worktile是采用erlang语言实现的
感觉就是系统有了瓶颈,需要一层消息缓存了,直接数据库读写消息效率偏低了,因为数据库在写的时候可读导致数据不一致,消息存在内存中楼上的redis或者memcache中,如果还是会出现写,读不一致的情况,应该横向拓展了吧!
相关文章:

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

要安全、徹底地卸載MySQL並清理所有殘留文件,需遵循以下步驟:1.停止MySQL服務;2.卸載MySQL軟件包;3.清理配置文件和數據目錄;4.驗證卸載是否徹底。

在MySQL中,添加字段使用ALTERTABLEtable_nameADDCOLUMNnew_columnVARCHAR(255)AFTERexisting_column,刪除字段使用ALTERTABLEtable_nameDROPCOLUMNcolumn_to_drop。添加字段時,需指定位置以優化查詢性能和數據結構;刪除字段前需確認操作不可逆;使用在線DDL、備份數據、測試環境和低負載時間段修改表結構是性能優化和最佳實踐。

MySQL批量插入数据的高效方法包括:1.使用INSERTINTO...VALUES语法,2.利用LOADDATAINFILE命令,3.使用事务处理,4.调整批量大小,5.禁用索引,6.使用INSERTIGNORE或INSERT...ONDUPLICATEKEYUPDATE,这些方法能显著提升数据库操作效率。

MySQL函數可用於數據處理和計算。 1.基本用法包括字符串處理、日期計算和數學運算。 2.高級用法涉及結合多個函數實現複雜操作。 3.性能優化需避免在WHERE子句中使用函數,並使用GROUPBY和臨時表。

2024年必備的Laravel擴展包包括:1.LaravelDebugbar,用於監控和調試代碼;2.LaravelTelescope,提供詳細的應用監控;3.LaravelHorizon,管理Redis隊列任務。這些擴展包能提升開發效率和應用性能。

在MySQL中配置字符集和排序規則的方法包括:1.設置服務器級別的字符集和排序規則:SETNAMES'utf8';SETCHARACTERSETutf8;SETCOLLATION_CONNECTION='utf8_general_ci';2.創建使用特定字符集和排序規則的數據庫:CREATEDATABASEexample_dbCHARACTERSETutf8COLLATEutf8_general_ci;3.創建表時指定字符集和排序規則:CREATETABLEexample_table(idINT

Composer是PHP的依賴管理工具,通過composer.json文件管理項目依賴。 1)解析composer.json獲取依賴信息;2)解析依賴關係形成依賴樹;3)從Packagist下載並安裝依賴到vendor目錄;4)生成composer.lock文件鎖定依賴版本,確保團隊一致性和項目可維護性。
