7.2 内容存储设计本节讲解如何进行内容存储设计。
7.2.1 内容数据的存储正如在7.1节中抛出的第一个问题,内容的表现形式可能是短文字、长文字、图片、音频、视频等,也可能是这些表现形式的组合,我们应该怎样合理地存储内容?
相信有很多读者在学习数据库系统课程设计时都做过类似于博客系统的课程设计项目!这就是一种典型的内容发布系统。不妨回忆一下,当年懵懂的我们是怎么设计数据存储的呢?当年的做法基本上都是很直白地把这些数据作为关系型数据库如MySQL的数据表中的一行来存储的,我们很有可能设计了表7-1所示的数据表。
可以看到,博文数据(博文标题、博文内容主体)和博文的元信息(博文唯一ID、 创作者的用户ID、博文创建时间)被共同存储到数据表的一行中,仅需读取数据表中的一行数据就能完成对博文的读取。但这样的设计仅适合学生级别的项目,并没有真正的工业级内容发布系统的使用价值,其原因如下。
关系型数据库只支持存储文章这种字符串类型的文本,并不支持存储图片、音频、视频这些文件数据,除非我们一意孤行,将文件数据也粗暴地当作文本存储到关系型数据库中。
即使是纯字符串类型的长文本存储,采用关系型数据 ...
在正式开始本章的学习之前,让我们先花一点儿时间来了解本章的学习路径与内容组织结构。
7.1节介绍内容发布系统的设计背景,即我们为什么要设计内容发布系统,针对这个系统需要考虑哪些业务与技术问题。
7.2节分析与设计内容数据的存储方式,并进行存储选型。
7.3节讨论内容审核主题,包括内容审核的必要性、内容审核的时机策略、如何审核内容,以及审核中心的对外交互流程。
7.4节重点围绕内容的生命周期管理展开,具体介绍内容的创建设计、内容的修改设计、内容审核结果处理与版本控制设计,以及内容的删除与下架设计。
7.5节讨论内容分发主题,设计一个从发布到大众可见的内容分发流程。
7.6节介绍内容展示设计,同时考虑了高性能与高并发请求的问题。
7.7节对前几节的设计进行知识汇总与复习,展示了内容发布系统的完整架构视图。
本章关键词:存储选型、版本控制、内容分发、内容审核、读多写少。
7.1 内容发布系统的设计背景以用户活跃度为出发点的互联网产品都有一个共性:任何用户都可以自由地以各种形式创作一段内容来表达自己的观点,并将该内容曝光到各种频道,与其他用户进行内容互动和讨论。如图7-1所示,用户创建的内 ...
6.2 海量推送系统设计在6.1节中我们对推送系统涉及的关键技术做了基本介绍,本节将介绍推送系统的整体架构设计。
6.2.1 整体架构设计推送系统的整体架构如图6-3所示,其中:
Nginx作为客户端设备与推送系统交互的代理,负责客户端建立连接的负载均衡与消息的最终下发;
每个pusher节点都负责与不同的客户端建立长连接,是消息的核心推送者;
ZooKeeper/etcd负责Nginx请求pusher集群时的服务发现,为Nginx转发连接请求时给出当前可用的pusher节点列表,进而帮助客户端连接到合适的pusher节点;
Redis集群负责保存用户设备与pusher节点的关联关系(如果采用Round-Robin等无数据规则的路由算法);
Push-gateway作为下行消息到pusher集群的代理网关,负责后端应用服务与推送系统之间的交互,包括按照单点消息、多点消息以及全局消息的方式进行消息的路由转发,是后端应用服务与推送系统之间的唯一代理;
消息队列负责消息的异步发送。
6.2.2 长连接的建立过程在客户端与推送系统之间建立长连接的过程如下所述,如图 ...
“推送”指的是把消息主动地实时推到客户端的行为。在互联网早期发展阶段,推送更多地属于即时通信(IM)领域范畴,但是随着移动互联网的普及,大量用户会维持很长时间的在线状态,于是对消息的实时触达能力有了广泛的需求。不仅仅在即时通信领域,几乎所有当代的互联网应用都对推送有大量的场景需求。例如:
社交互动类应用会实时通知与你相关的新互动(关注/私聊/回复/点赞 )、你关注的人发布了新内容、在直播间内谁给主播赠送了礼物;
电商类应用会告诉你所收藏的商品刚刚降价了、你的订单已完成退款、你的物流已到达目的地、你观看的带货直播间有新商品“上车”;
新闻类应用会推送你感兴趣的新闻和实时热点新闻;
更为普遍的是,大量应用都有系统版本升级主动提醒、重要全服公告能力等。
如上种种,都是非常典型的推送场景。在如今这样一个大数据个性化推荐的时代,很多应用出于保持用户活跃度的目的,甚至会投你所好,推送你可能感兴趣的消息,比如图6-1所展示的那样。
消息推送的应用场景如此广泛,我们很有必要来讨论一下推送系统这个议题。我们希望设计一个通用的推送系统,支持各种业务方主动向在线用 ...
面试官:如何实现扫码登录功能?
扫码登录原理
扫码登录的原理
场景题:二维码扫码登录设计
很多互联网产品不仅提供了移动端应用,还提供了PC端应用或网页访问方式,比如爱奇艺、腾讯视频等视频类产品,以及淘宝、微信等国民级产品。这些兼顾PC端用户体验的产品一般都提供了扫码登录功能:如果用户已在移动端登录,那么在PC端可以通过在移动端应用内扫描二维码的方式完成一键登录。
手机扫码登录方式具有方便快捷、安全性高、密码管理成本低、用户体验好等优势,后面我们会讨论这个功能的技术实现。
5.7.1 二维码二维码是一种可以存储大量信息的矩阵条形码,最早是在1994年由一家日本公司发明的。随着移动互联网的发展,二维码得到了非常广泛的发展和应用。
二维码采用特殊的编码方式将数字信息编码成黑白相间的矩阵图案,且编码方式多种多样,例如QR码、Data Matrix码等。使用扫描仪设备或相机对二维码进行扫描,可以将二维码解码转换回数字信号。二维码种类繁多,这里我们仅需要知道一段数据可以被编码生成二维码图片,使用手机扫描二维码图片可以将其解码回原始数据即可。
5.7.2 扫码登录的场景介绍假设小A是Friendy产 ...
客户端与服务端之间的通信是基于HTTP的,而HTTP是无状态的,即客户端每次发出请求时都永远无法得知上一次请求的状态数据,任何请求之间都是相互隔离的。比如客户端发起一次用户登录请求,之后再发起请求时并不知晓用户已经登录,更不知道自己的请求来自哪个用户。
然而,请求是否是已登录用户发起的是一个强诉求,对于绝大多数的写数据请求(如关注某人、发文章、发评论、转账等)来说,服务端都必须要求从请求中能识别出发起的用户,不然服务端根本不知道这些请求应该为谁执行;对于读数据请求也应该有类似的诉求。因此,所有的客户端请求都应该携带某些数据,以便服务端能够判断请求的发起者是否已登录,以及对应的用户ID。
这个问题似乎很容易解决:用户登录后,客户端把返回的用户ID保存起来,然后每次发起请求时都将用户ID强制作为参数之一传递即可。但是这种做法太过直白,任何稍有HTTP知识的人都可以把作为参数的用户ID随意修改后发送给服务端,使用户受到攻击。比如某个黑客通过本地网络抓包工具得知查询用户账户余额的HTTP path是api.friendy.com/wallet/get?user_id=xxx,他将任意用户ID作 ...
OAuth2.0 协议原理
第三方登录指的是基于用户在第三方平台已有的账号和密码来快速完成乙方应用的注册与登录功能。这里的第三方平台一般是指已经拥有大量用户的知名平台,比如微信、微博、支付宝、QQ等。第三方登录具有如下优势。
快速登录:用户无须花费时间记忆和输入账号、密码,通过第三方平台的账号授权即可完成身份验证。
账号安全:第三方登录可以帮助用户保护账号在乙方应用中的安全,比如防止账号被盗等。
提升用户体验:第三方登录允许不同的网站或应用共享同一条登录信息,让用户可以更便捷地使用各种应用。例如,微信用户可以使用微信登录大众点评、拼多多、腾讯视频、小红书等应用。
用户数据分析:第三方登录平台可以帮助乙方应用有效地跟踪用户,并对用户数据进行智能分析和挖掘,为用户提供更具针对性和有价值的产品与服务。
5.5.1 OAuth2 标准目前市面上主流的第三方登录协议是OAuth2,它是一个开放的授权标准,允许用户授权乙方应用访问他们存储在第三方平台的信息,而不需要将第三方平台的用户名和密码提供给乙方应用。微信、微博、QQ等提供第三方登录的开放平台都遵循OAuth 2标准。
乙方应用必须 ...
大部分互联网应用都支持手机号登录和邮箱登录的功能,这不仅仅使登录方式多样化,更重要的是,使用手机和邮箱往往具有如下优势。
用户习惯:人们在日常生活中通常使用手机和邮箱进行通信,互联网用户更是习惯使用固定的手机号或邮箱地址作为登录凭证,而不是花费心思去记住自己的各种账号与密码。
数据唯一:一个手机号只会属于一个用户,不存在多个用户使用同一个手机号的情况。对于邮箱也是如此。使用手机和邮箱可以免去冗长的账号注册流程,降低用户使用门槛。
身份认证:使用手机和邮箱能对用户进行身份认证,确保用户身份合法。
数据安全:手机和邮箱通常与用户数据权限关联,当用户忘记密码时,使用它们可以有效缩短找回密码的流程,提高账号的安全性。
总之,提供手机号登录和邮箱登录功能的目的是方便用户快速、安全地登录,提升用户体验,降低用户使用门槛。
5.4.1 数据表设计为了支持以手机号、邮箱等类似方式登录的功能,在数据库中需要额外创建一个用户授权表User_auth,如表5-2所示。
User_auth表与User表是多对一的关系,且有两个索引。
auth_id索引:根据手机号或邮箱地址查询授权记录,找到对应的用 ...
无论是客户端与服务端之间通过网络传输密码,还是将密码保存到数据库中,都需要保证密码安全。
5.3.1 使用HTTPS通信首先我们来解决客户端发送注册、登录请求到服务端时,防止第三方抓包工具获取到密码的问题。客户端与服务端之间使用HTTPS通信。HTTPS是身披SSL外壳的HTTP,在HTTP通信链路中利用SSL/TLS建立全信道加密数据包,在请求传输过程中,第三方抓包工具看到的是密文,所以获取不到密码。
需要注意的是,使用HTTPS并不能彻底保证密码安全,因为HTTPS的加密、解密行为发生在HTTP层和TCP层之间,如图5-1所示。
这就意味着,虽然HTTPS在网络传输过程中可以保证数据是密文,但是数据包到达服务端后,一旦经过解密进入HTTP层,数据就会变为明文,这时如果攻击者入侵服务端并在网络层拦截数据,那么依然可以获取到密码。攻击者入侵客户端同样可以获取到密码,况且客户端被入侵的可能性远大于服务端被入侵的可能性。所以需要强调的是,HTTPS保证的是数据在传输过程中的安全性,而攻击者依然可以在客户端和服务端拦截数据得到明文密码。
5.3.2 非对称加密为了防止用户密码在客 ...
用户登录服务负责用户的注册与登录,这是一个看似非常简单、很容易设计的服务。在学习数据库的过程中,很多同学都做过数据库的各种管理系统课程设计,比如图书馆管理系统、学生成绩管理系统等,使用数据库作为数据存储系统,使用HTTP协议的HTML页面作为用户操作界面。无论哪个管理系统,必不可少的一个功能都是用户注册与登录。当时,大家实现这个功能的方式基本如下。
首先,在数据库中创建一个用户表User来记录用户账号、密码和用户状态等信息,如表5-1所示(注意:用户昵称、头像、个性签名等这里暂不列出,它们不是用户登录服务的重点)。
然后,开发用户注册页面和登录页面。页面元素如下。
账号文本框:用户在此输入账号。
密码文本框:用户在此输入密码。
验证码标签:用户打开页面时,网页随机生成一个验证码并展示。
验证码文本框:用户在此输入验证码。
注册按钮:用户点击后注册。
登录按钮:用户点击后登录。
用户注册的流程如下。
用户打开注册页面,并在上述三个文本框中依次输入待注册的账号(如abc)、密码(如123456)和验证码。
用户点击注册按钮,HTTP使用POST方式将用户填入的账号、密码提交到后台。 ...