第二版
要注意的
应用场景
用户添加订阅源
用户向订阅源获取消息
客户端整理消息。
用户点开消息
用户阅读消息
标记已读
API
addSource(url)
getUpdate(sourceUrl, lastPulledTime, maxReturn)
getUpdateNumberOnly(sourceUrl, lastPulledTime,
getFullContent(newsURL)
Data Model / Schema
Subscription table
sourceId, sourceURL, lastPolledTime, lastNumberedTime, unpulledMessage
News Table
sourceId, newsId, newsURL, preview, readOrNot, timeStamp
这两个数据库和我们常见的理解的不一样都是在手机上的。当然也可以是在网上。有一个很不一样的是由于是新闻, 过段时间这个消息就直接expire了,没必要一直存着吧(我的猜测不一定对,需要和面试官确认),
Working Solution
用户subscribe, 用户打开app后,系统查询sourceURL, 并主动向各个source 询问某个timestamp之后的消息。 各个信息源返回之后,存入local的数据库。客户端整理后按时间先后顺序显示。用户点进去之后,会主动或手动pull消息的html并显示在服务器上,并把消息标记为已读。
本地的数据库要以timestamp建2ndary index, primary index是newsId.
因为是以timestamp从后往前排序,经常要查询,所以要经常这么干。
把所有消息标记为已读, 就是遍历数据库,一个个改一下。由于数据都在本地,所以数据量不会很大。
翻页就是Select * from newTable order by timeStamp desc offset 20 Rows Fecth next 20 Rows only.
显示新的消息
如果Rss发推送, 则通过real time service收集推送显示出来。
如果RSS不发推送,则每10分钟向各个source pull一次问一下上次之后出现了多少新的消息,服务器只需要返回有多少数字就可以了。用户选择收新消息的时候再要完整的新消息preview。
Scale
Scale个毛呀,这是单机版的。。
网页版的可以按user id sharding. 定期删删数据就好了,新闻,一周以前的新闻就不要留了。
Push Model
如果rss可以push的话,subscribe的时候汇报一下用户的device token,有消息的时候就push一下。如果订阅者特别多的话,那就不要push了,让用户定期来pull。
第一版
Scenario:
用户登录推送新鲜事(要能区分 哪些是新的,哪些是旧的)
用户阅读post
设计多牛的系统:
有多少用户,每个用户订阅多少channel,每次读多少
Service
Get update service
Sort and order service
Storage service
Push vs Pull model
用push model的话可能太慢了,fan out太慢了。因为一个channel很多人订阅,这些channel都是明星用户。
Storage
需要什么 table
user table: user id, name, info,
post table: post id, channel id, timeStamp, title, preview, URL
channel table: channel id, address
subscription table: channel id, user id, subscription date, last read date
user - post table: user id, post id, readOrNot
post id can use timeStamp
Scale
Sharding:
user table, subscription table, user -- post table 都 按user id shard,
channel table, post table 按 channel id sharding,
如果停止订阅
从post table里, filter by channel id吧
网友评论