跳到主要内容

Feed 流系统

Feed 流就是信息流,市面上主流的有三种。

第一种是最简单的,由平台自己或职业人员产生内容,用户可以按时间顺序查看到统一类内容的信息流。常见于官网内容、专业媒体或精选内容等产品。比如知乎日报、虎嗅等,该类产品可以使用 CMS 系统实现。

第二种是推荐类,也就是由推荐引擎将用户感兴趣的内容推荐给用户浏览,典型的就是今日头条、抖音等。该类产品需要标签系统,智能内容系统,计算引擎,推荐引擎等配合,清林云未来不久将会推出该类应用。

第三种就是订阅类信息流,也就是根据用户的关注、订阅、好友关系等,浏览相关内容,最有代表的就是微博,朋友圈,B 站这些。我们将在下面实现一个该类型的自定义应用。

我们用一个基础的 Feed 系统来展示清林云自定义应用能力。基础版本能满足大部分基础需求,但是每家组织的 Feed 流系统需求都不相同,所以你也可以在这个基础上再自行添加更多高级的个性化功能。

需求#

我们需要一个订阅类 Feed 流系统,可以实现基于关注关系的内容订阅。

所以该系统需要有一个订阅关系,能够关注其他用户,当被关注的用户发布动态后,关注的用户就可以在自己的信息流中查看到该动态内容。

基本上这是一个社交、信息类产品的必备功能。基于该 Feed 流,可以实现类似微博、朋友圈的功能,提高用户使用度。

功能分析#

在技术上,订阅类 Feed 流系统还分为三类:

一、推模型(多写)#

也就是当一个用户发布动态后,后端将先查询所有关注他的用户,然后将该动态的数据插入到所有关注用户的信息流中。

比如说,当你有 2000 个微信好友时,每当你发一条朋友圈,微信后端将会先查询你的所有好友,然后分别给这 2000 人的朋友圈动态中插入你发布的内容。

该模型的优势是逻辑简单,用户刷新朋友圈内容时性能好,占用查询资源小。

但缺点是发布时不好瞬间写入太多数据,比如当你有 100 万个好友时,那么发一条朋友圈将会在后端瞬间写 100 万条数据,这就给后端的压力太大,很难实现。这也是为什么微信只允许有 5000 个好友能查看朋友圈的原因之一。

二、拉模型(多读)#

上面的情况当然不能适用于微博、B 站这种账号有大量粉丝的产品,所以就会使用拉模型。

就是当用户打开产品时,将会先查询用户的关注列表,然后根据上次查询数据的时间,查询所有关注了的用户新发布的内容,然后将这些内容存到自己的信息流中再去浏览。

所以使用该模型时,比如有一个大 V 有 1000 万粉丝,当他发布一条动态时,仅仅是一个简单的新增一条数据。而当其他用户打开产品或者是刷新动态时,才会查询到该内容并写入自己的信息流中,同时在线并刷新的粉丝当然不会太多,所以就实现了大量粉丝情况下的 Feed 流。

该模型的缺点就是略微复杂,然后用户查询的资源消耗多,这也就是为什么 B 站限制最多只能关注 2000 人的原因之一。

三、推拉结合模型(读写结合)#

上面两种方法都有优点和缺点,所以就又出现了推拉结合模型。

当一个用户的粉丝量小于 5000(假设值)时,发布内容时将使用推模型,超过时使用拉模型。

浏览用户打开产品后,查询关注列表中的大 V,读取他们的最新内容存入自己的信息流,而那些小 V 的内容则早就在发布时已经存在自己的信息流中了。

该模型唯一缺点就是实现起来较为复杂。

本应用#

清林云以前实现过很多类似系统,所以就直接简化了很多复杂的部分,然后这里我们将实现一个非常简洁的可推可拉可推拉结合模型的 Feed 流。

动态项 FeedItem 的 ID 我们将使用时间戳随机值,也就保证了数据都是按时间排序,这样好查询,插入用户信息流时也比较容易,保证是唯一的。

然后推模型使用pushFeed API,拉模型使用pullFeed API,你可以在使用该应用时自行判断用哪一个,也可以结合使用。

比如说,当你的产品用户关系较小,使用推模型,那么当用户发布内容即createFeedItem时则同时调用pushFeed将该动态同步给所有粉丝或好友。

当你的产品用户关系为大 V 型,那么使用拉模型,每当用户打开或刷新时就调用pullFeed API 把最新内容存入自己的 Feed 中,然后使用getManyFeed查看即可。

当你想要两者结合时,那么就在发布内容时判断一下是否小 V 去推,并且在pullFeed时调用参数中加入isStartrue

数据库结构#

Feed 动态#

Feed 是“我的动态”,即不管是推模型还是拉模型,最终所有关注的人发的动态都会归于此处,这样有更好的查询性能。

feed

FeedItem 动态项#

动态项就是具体的动态,简单的动态数据可以通过 content data 这两个字段来实现内容,复杂的也可以通过 contentId 链接额外的应用查看相关数据。

这里 feedId 的值将在 API 中采用时间戳随机值,在保证了 Feed 流都是按时间排序时也保证了严格的唯一性。

feedItem

Follow 关注者#

当我们关注某用户后,需要该表来记录我们的所有关注数据,另外被关注的用户也可以查询谁在关注他,所以这里我们使用 C2 引擎。

follow

UserData 动态数据#

最后一个用户的 Feed 系统数据表来记录一些数值,这样就在查询某些常用的数值时不需要去查询所有相关数据再计算,这样有更好的性能,也更方便。

userData

API#

createFeedItem#

创建 Feed 项,同时也会在自己的 Feed 中插入一条进去,并更新动态数。

createFeedItem

updateFeedItem#

更新该内容。

updateFeedItem

deleteFeedItem#

删除 Feed 项,更新动态数。

deleteFeedItem

getManyFeedItem#

查询“我”发布的动态

getManyFeedItem

pushFeed#

推模型,将会把该项写入到最多前 2000 个粉丝的 Feed 流中。

pushFeed

pullFeed#

拉模型,将会查询最多前 2000 个关注的用户,然后将lastPullTime之后的新内容写入自己的 Feed 流中。

注意这里可以控制是否拉大 V,当你仅仅使用拉模型时,关注关系那边新建的时候就统一为false,这里同样传入false即可。当你使用推拉结合时,这里调用参数传入true,则只会查到关注时为大 V 的用户。

pullFeed

pullFeed2

getManyFeed#

查询信息流。

getManyFeed

deleteFeed#

从信息流中移除某动态。

deleteFeed

createFollow#

新增关注。

createFollow

deleteFollow#

取消关注。

deleteFollower#

移除粉丝。

deleteFollow

getManyFollow#

我的关注。

getManyFollow

getManyFollower#

关注我的。

getManyFollower

updateUserData#

更新用户 Feed 数据。

updateUserData

getUserData#

查询用户 Feed 数据。

getUserData

界面#

该应用暂无开源项目示例,后续将更新开源一个实际使用中的项目代码,敬请期待。