智能硬件服务器后端方案设计

    前言
    世界上有没有最好的后端架构方案?
    下图是一张较完善的智能硬件产品整体方案架构图,但实际上, 市场上绝大多数的智能硬件产品架构都不会这么去搭,最主要的原因是,太费钱了。
    智能硬件服务器后端方案设计 - 图1
    在为真正产品去做后端设计时,我们一般建议根据具体业务节点,进行合理的产品架构设计,避免过早优化,避免过度工程化。
    那如何去设计一套后端方案呢?

    一、分析业务需求&评估业务
    根据产品需求文档、市场、商业分析相关文档,评估公司产品开发生命周期以及每个大节点,智能硬件产品与互联网产品,在进行后端设计时的分析方向是不一样的,传统互联网产品关注的是用户端的请求并发和数据。智能硬件产品更关注的是设备端的连接、安全、数据派送。所以对于设备来说,一般可以分为启动阶段、3w+设备阶段、10w+设备阶段,当然了,2B、2C不同场景不同的设备差异会比较大,主要可以总结为产品启动期、产品稳定器、产品爆发期三个阶段的后端方案设计。

    二、确定后端架构
    2.1 整体方案设计
    2.1.1 项目启动时
    项目启动时,此阶段的主要目标是快速验证,利用现有的轮子,现成的架构,快速验证产品功能和业务的可行性,此阶段的方案设计,主要考虑以下两点:
    1、最小投入
    一台服务器可以做的事情,那就把应用、数据库、缓存相关的资源都放到同一台服务器上,尽可能用最少的资源(硬件、运维、开发)快速验证。
    2、可伸缩、易扩展
    另外,在设计数据库表格、API接口时应该考虑好后续扩展的准备,避免后续花大量时间重构数据库和API接口。
    智能硬件服务器后端方案设计 - 图2

    2.1.2 3w+设备量时
    当产品已经运营一段时间,功能层面较为完善,此时设备开始大量投放市场,对于常见的物联网设备来说,3w台的设备一般是一个临界点,这个阶段后,原来的服务器开始出现性能瓶颈,此时,应该加快进入后端架构优化,智能硬件设备由于业务场景的特殊性,主要瓶颈还是在存储端,此时主要着重以下几点设计。
    1、应用服务和数据服务分离
    随着业务的发展和用户量的增加,一台服务器就无法再满足需求了。大量用户访问导致访问速度越来越慢,而逐渐增加的数据也会导致存储空间不足。这时需要将应用和数据分离,分别将存放到不同的服务器:应用服务器、文件服务器和数据库服务器。这样不仅提高了单台机器的负载能力,也提高了容灾能力。
    2、使用缓存改善网站性能
    随着用户再增加,数据库压力太大导致整站访问效率下降,用户体验受到影响。
    一个网站往往 80% 的业务访问集中在 20% 的数据上。那么将这一小部分频繁读取的数据先提前缓存在内存中,而不是每次都去数据库读取。这样就可以减少数据库的访问压力,从而提高整个网站的访问速度。
    缓存分为本地缓存和分布式缓存服务器,前者更快但容量有限,后者理论上容量可以无限伸缩。
    3、使用集群改善并发处理能力
    使用缓存后,数据访问压力得到了缓解.但是单一应用服务器能够处理的请求连接有限,在网站访问高峰期,应用服务器就成了整个网站的效率瓶颈。因此使用负载均衡处理器势在必然。通过负载均衡调度服务器,可将来自浏览器的访问请求分发到应用的集群中的任何一台服务器上。使用服务器集群也有个好处,应用程序更新可以做到用户无感知。
    4、数据库读写分离
    当用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。虽然前面使用缓存能满足查询的需求,但是大部分数据操作还是需要通过数据库来完成。而目前主流的数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库的数据更新同步到另一台服务器上。网站利用数据库这一功能实现数据库读写分离,从而改善数据库负载压力。
    智能硬件服务器后端方案设计 - 图3
    2.1.3 10w+设备量时
    当设备量铺设10w+后,意味着设备即将进入爆发期,此时应从全局视角分析服务器性能瓶颈、安全评估、全局监控、备份容灾相关指标。
    1、反向代理和CDN加速
    随着产品名气越多越大,用户规模越来越大,业务也随着继续壮大。为了满足不同地区的用户快速访问网站的需求,需要提高网站的访问速度。主要手段有使用 CDN 和反向代理。
    同时 Ajax 技术的出现,应用会将数据(内容和图片)和页面框架(指 HTML 文件以及其中的标签)。页面框架内容存放到 CDN 服务器上,数据存放到数据库服务器上。当用户使用浏览器访问网站,会显示页面框架,然后页面框架发起 HTTP 请求加载数据。
    而反向代理是部署在网站的中心机房,当用户请求到达中心机房后,首先访问的反向代理,如果反向代理缓存着用户请求的资源,则直接返回给用户。
    2、使用分布式文件系统和分布式数据库系统
    任何强大的单一服务器都满足不了大型网站持续增长的业务需求。
    分布式数据库时网站数据库拆分的最后手段,只用在单表数据规模非常大的时候才使用。不到不得已时,网站更常用的数据库拆分手段是业务拆分,将不同业务的数据部署在不同的物理服务器上
    3、使用NoSQL和搜索引擎
    随着网站业务越来越复杂,对数据存储和检索的需求也越来越复杂。网站需要采用一些非关系数据库技术如 NoSQL 数据库和非数据库查询技术如搜索引擎。而常见的 NoSQL 数据库有 Mongodb、HBase等。
    4、业务拆分
    大型网站为了应对日益复杂的业务场景,通过使用分而治之的手段将真个网站业务拆分成不同的产品线。如大型购物交易网站都会将首页、商铺、订单、买家、卖家等拆分成不同的产品线,分归不同的业务团队负责。
    5、分布式服务
    随着业务拆分越来越小,存储系统越来越庞大,应用系统的整体复杂度呈指数级增加,部署维护越来越困难。
    既然每一个应用系统都需要执行许多相同的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。由这些可复用的业务连接数据库,提供共用业务服务,而应用系统只需要管理用户界面,通过分布式服务调用共用业务服务完成具体业务操作。
    智能硬件服务器后端方案设计 - 图4

    2.2 数据库设计

    数据库设计的基本原则:
    把具有同一个主题的数据存储在一个数据表中,“一表一用”。
    尽量消除冗余,提高访问数据库的速度。
    一般要求数据库设计达到第三范式,多对多,最大限度消除了数据冗余、修改异常、插入异常、删除异常,基本满足关系规范化的要求。
    关系数据库中,各个数据表之间关系只能为一对一和一对多的关系。对于多对多的关系必须转换为一对多的关系来处理。
    设计数据表结构时,应考虑表结构的动态适应性。
    数据库设计的主要步骤:
    需求分析:了解用户的数据需求、处理需求、安全性及完整性要求;
    概念设计:通过数据抽象,设计系统概念模型,一般为E-R模型;
    逻辑结构设计:设计系统的模式和外模式,对于关系模型主要是基本表和视图;
    物理结构设计:设计数据的存储结构和存取方法,如索引的设计;
    系统实施:组织数据入库、编制应用程序、试运行;
    运行维护:系统投入运行,长期的维护工作。

    非关系型数据库与关系型数据库各自的优势
    非关系型数据库的优势:
    1. 性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
    2. 可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
    关系型数据库的优势:
    1. 复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
    2. 事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。
    2.2.1 关系型数据库选型

    数据库 优点 缺点 使用场景
    MySQL
    数据库
    1.使用C和C++编写,并使用了多种编译器进行测试,保证源代码的可移植性;
    2.支持AIX、FreeBSD、HP-UX、Linux、Mac OS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris、Windows等多种操作系统;
    3.为多种编程语言提供了API。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等;
    4.支持多线程,充分利用CPU资源;
    5.价格便宜:Mysql是开源的,所以不需要支付额外的费用;
    6.MySQL使用标准的SQL数据语言形式;
    7.Mysql对PHP有很好的支持,PHP是目前最流行的Web开发语言。
    1.比较难学;
    2.MySQL也缺乏一些存储程序的功能;
    3.使用缺省的ip端口,但是有时候这些ip也会被一些黑客闯入;
    4.使用myisam配置,如果你不慎损坏数据库,结果可能会导致所有的数据丢失。
    广泛地应用在Internet上的中小型网站中
    LAMP(Linux+Apache+Mysql+Php)
    mysql的优势在于免费,如果业务系统数据库不是极其庞大,可用mysql
    Oracle数据库 1.能在所有主流平台上运行(包括 windows)。完全支持所有的工业标准。采用完全开放策略。可以使客户选择最适合的解决方案。对开发商全力支持;
    2.安全性方面,性能最高;
    3.采用标准的SQL结构化查询语言;
    4.具有丰富的开发工具,覆盖开发周期的各阶段;
    5.支持大型数据库,数据类型支持数字、字符、大至2GB的二进制数据,为数据库的面向对象存储提供数据支持;
    6.具有字符界面和图形界面,易于开发;
    7.具有数据透明、网络透明,支持异种网络、异构数据库系统。并行处理采用动态数据分片技术;
    8.支持客户机/服务器体系结构及混合的体系结构(集中式、分布式、客户机/服务器);
    9.数据安全保护措施:没有读锁,采取快照SNAP方式完全消除了分布读写冲突。自动检测死锁和冲突并解决。数据安全级别为C2级(最高级);
    10.在中国的销售份额占50%以上,市场份额高
    1.管理维护麻烦一些;
    2.数据库崩溃后恢复很麻烦,因为他把很多东西放在内存里;
    3.数据库连接要慢些,最好用连接池;
    4.大对象不好用,vchar2字段太短,不够用;
    5.管理员的工作烦,且经验非常重要;
    6.对硬件的要求很高;
    7.价格昂贵。
    大部分企事业单位都用oracle,在电信行业占用最大的份额。
    SQL Server数据库 1.安全性和可用性高;
    2.超快的性能;
    3.企业安全性;
    4.快速的数据发现
    5.方便易用;
    6.高效的数据压缩功能;
    7.集成的开发环境。
    1.开放性。只能运行在微软的windows平台,没有丝毫的开放性可言;
    2.可伸缩性,并行性。并行实施和共存模型并不成熟,很难处理日益增多的用户数和数据卷,伸缩性有限;
    3.性能稳定性。SQLServer当用户连接多时性能会变的很差,并且不够稳定;
    4.使用风险。SQLServer完全重写的代码,经历了长期的测试,不断延迟,许多功能需时间来证明。并不十分兼容早期产品。使用需要冒一定风险;
    5.客户端支持及应用模式,只支持C/S模式;
    6.安全性。Oracle的安全认证获得最高认证级别的ISO标准认证,而SQL Server并没有获得什么安全认证。
    主机操作系统为window,主要用于web网站的建设,承载中小型web后台数据。在租赁的虚拟主机中一般会预安装SQL Server作为数据库软件。
    PostgreSQL 1.PostgreSQL 的稳定性极强, Innodb 等引擎在崩溃、断电之类的灾难场景下抗打击能力有了长足进步。
    2.PG 性能高速度快。任何系统都有它的性能极限,在高并发读写,负载逼近极限下,PG的性能指标仍可以维持双曲线甚至对数曲线,到顶峰之后不再下降。
    3.PG 多年来在 GIS 领域处于优势地位,因为它有丰富的几何类型,实际上不止几何类型,PG有大量字典、数组、bitmap 等数据类型。
    4.PG 的“无锁定”特性非常突出,甚至包括 vacuum 这样的整理数据空间的操作,这个和PGSQL的MVCC实现有关系。PostgreSQL 是唯一支持事务、子查询、多版本并行控制系统、数据完整性检查等特性的唯一的一种自由软件的数据库管理系统
    5.PG对数据量大的文本以及SQL处理较快,可以使用函数和条件索引,这使得PG数据库的调优非常灵活。
    1.关于mvcc 的多版本控制。会生成很多个版本。定期要清理
    2.pg的分布式集群。bug很多实用需要谨慎
    3.pg数据库的并发性问题:pg采用抢占资源的方式,如果有一个大的SQL在跑,可能就会阻塞其他的进程,不管其他的进程是小SQL还是大SQL。好在pg有个优先级设置,还能变通一下。
    4.pg的数据库扩容问题:扩容花费的时间很长。
    5.pg的segment和mirror同步问题:某个实例有问题,如果是在线恢复,特别慢。 如果把所有的应用停掉则速度还算可以。
    OLAP数据库,适用于电信、金融的分析
    SQLlite 1.源代码不受版权限制,真正的自由,开源和免费.
    2.无服务器,不需要一个单独的服务器进程或者操作的系统
    3.一个SQLite 数据库是存储在一个单一的跨平台的磁盘文件
    4.零配置,因为其本身就是一个文件,不需要安装或管理,轻松携带
    5.不需要任何外部的依赖,所有的操作等功能全部都在自身集成.
    6.轻量级,SQLite本身是C写的,体积很小,经常被集成到各种应用程序中.
    1.缺乏用户管理和安全功能
    2.只能本地嵌入,无法被远程的客户端访问,需要上层应用来处理这些事情;
    3.不适合大数据
    4.适合单线程访问,对多线程高并发的场景不适用;
    5.各种数据库高级特性它都不支持,比如管理工具、分析工具、维护等等;
    小型网站、嵌入式设备、数据库教学、本地应用程序
    DB2数据库 1.能在所有主流平台上运行(包括windows)。最适于海量数据;
    2.具有很好的并行性。DB2把数据库管理扩充到了并行的、多节点的环境;
    3.获得最高认证级别的ISO标准认证;
    4.客户端支持及应用模式;
    5.跨平台,多层结构,支持ODBC,JDBC等客户;
    6.操作简单,同时提供GUI和命令行,在windowsNT和unix下操作相同。
    1.在巨型企业得到广泛的应用,向下兼容性好。风险小。 性能较高适用于数据仓库和在线事务处理。DB2 超大型数据库,与ORACLE类似 ,数据仓库和数据挖掘相当的不错,特别是集群技术可以使DB2的可扩性能达到极致。

    2.2.2 非关系型数据库选型

    数据库 优点 缺点 使用场景
    Redis 1、Redis不仅仅只支持简单的K-V形式的数据存储,还支持list、set、hash、zset等等集合类数据的存储;
    2、Redis支持实时的数据备份,即使宕机,也可以把数据恢复过来;
    3、Redis支持数据的持久化,可以存放在内存memory中的数据直接保存在磁盘上;
    数据库容量受到物理内存的限制,因此不便对海量数据进行高性能读写,适用场景局限在数据量较小的高性能操作和运算上; 查找最新的回复、排行问题、缓存、删除过期数据
    MemCache 1、稳定。
    2、配置简单
    3、速度快
    4、分布式扩展
    1.不能持久化存储
    2.存储数据有限制:1M 【大于1M,认为就行分割】(内存碎片)
    3.mm存储数据只能key-value
    4.集群数据没有复制和同步机制 【崩溃不会影响程序,会从数据库中取数据】
    5.内存回收不能及时 LRU(算法):未使用内存》过期内存》最近最少使用内存 这是惰性删除
    分布式应用、数据库前段缓存、服务器间数据共享
    MongoDB数据库 1、文档结构的存储方式,能够更便捷的获取数据
    2、内置GridFS,支持大容量的存储
    3、内置Sharding,分片简单
    4、海量数据下,性能优越
    5、支持自动故障恢复(复制集)
    1.不支持事务操作
    2.占用空间过大
    3.MongoDB没有如MySQL那样成熟的维护工具
    4.无法进行关联表查询,不适用于关系多的数据
    5.复杂聚合操作通过mapreduce创建,速度慢
    6.模式自由, 自由灵活的文件存储格式带来的数据错误
    各种应用服务的日志存储、敏捷开发、地理位置信息存储、json存储

    2.3 接口设计
    兵马未动,粮草先行。在一款产品的各个版本迭代中,兵马的启动指的是真正开始敲代码的时候,粮草先行则是指前期的需求,交互,UI等评审准备阶段。虽然很多时候一个api接口的业务,数据逻辑是后端提供的,但真正使用这个接口的是客户端,一个前端功能的实现流程与逻辑,有时候只有客户端的RD才清楚,从某种意义来说,客户端算是接口的需求方。
    所以建议在前期接口设计和评审时,客户端的RD应该更多的思考和参与,什么时机调什么接口?每个接口需要哪些字段?数据含义怎么给?只有这些都考虑清楚,且达成一致并产出接口文档后,当项目真正启动时,根据接口协议进行开发,才能尽量避免各种不确定因素对项目整体进度的影响。

    2.3.1 关于接口文档
    接口设计必须提供接口文档
    无论项目团队的大小,在遇到接口问题的时候单纯的从代码出发,而不是从接口文档出发,对于整个项目团队的维护简直就是耍流氓。
    文档也应纳入版本控制
    使用markdown,wiki 做文本类型的文档,使用svn,git等做为版本工具 可以很清晰的看到接口文档的改动人和改动时间,同样是方便维护工作。
    文档类型选择markdown,wiki等
    使用文本类型的文档(比如markdown, wiki等格式),一则方便比较版本间改动,二则可以生成html, word, pdf等多种美观格式。我见过有好多团队是使用word来写文档的,由于是二进制格式,不利于版本比较,也不专业。
    2.3.2 接口安全
    当我们面对很多外部接口的时候,我们需要考虑数据的安全性。为什么要考虑安全性:
    包含用户数据
    包含交易数据
    以及甚至你不想让用户自己知道的数据
    所以分为请求参数和响应参数:
    请求参数中包含用户隐私的字段参数,如:登陆接口的密码字段,需要进行加密传输,避免被代理捕捉请求后获取明文密码。
    响应参数中包含用户隐私的字段数据,需要加号。如:手机号,身份证,用户邮箱,支付账号,邮寄地址等。
    客户端和服务器通过约定的算法,对传递的参数值进行签名匹配,防止参数在请求过程中被抓取篡改
    *保护接口的方式最基本的是SSL/TLS,然后呢:

    对称加密的方式
    非对称加密的方式
    动态秘钥

    2.3.3 接口的一些原则
    一个页面尽量只有一个拉取接口
    原先一个页面要通过多个请求获取多种类型数据的情况,最好能通过一个接口全部获取得到。又如:在调用B接口前需要A接口的前置数据的情况,可以让后端支持下,在调用A接口时直接返回B接口的数据,减少类似这种的连续请求。
    打破第一条规则,当请求需要缓存并且有需要及时更新的情况
    为了更好的打开速度,对于不经常变化的数据,往往需要做数据缓存以及请求缓存。但有些信息,比如预约时间,又需要做到及时,则应该分多个请求。
    如果返回数据中某个字段的数据没有,返回该字段比不返回该字段要好。
    JSON格式的好处在于灵活性,但没有校验机制。所以定义协议时规定了有哪些字段,最好这些字段都返回。我的意思是比如返回一个列表,大多数场景是返回一个数组,但如果没有数据,返回一个空数组比不返回该字段要好。当然前端也有必要做自己的容错考虑。
    比较常见的返回数据的格式:

    2.3.4 瘦客户端
    客户端尽量只负责展示逻辑,不处理业务逻辑
    例如:客户端有个TextView,后端只给个status字段,status=1时,展示文案1;status=2时,展示文案2;这样设计的缺点是,如果以后要修改status=3时,展示文案1,那么这个status判断逻辑时写死在客户端,就没办法支持这种修改,且这种设计限定死了TextView只能展示2种文案。推荐方案是后端直接将TextView需要展示的文案下发,这样不管是status的判断,还是文案的展示,后期都是可变的。
    客户端不处理金额的计算
    例如:外卖APP,用户在下单的时候,需要选择收货地址,支付类型,优惠券等,任何一个选项的修改,都可能影响用户最后需要支付的金额。所以这里比较常见的接口设计是在每次选择完回到订单支付页面后,再发送一次请求,后端根据当前选项重新计算金额。金额永远是一款产品最重要,最敏感的信息,如果交由客户端计算,万一出错,即使少1分,都是毁灭性的,所以,关于金额,展示就好。
    客户端少处理请求参数的校验与约束提示
    例如:修改密码功能,密码规则”6-12字母,数字,下划线”,有3种做法:
    在发送请求前,客户端校验密码规则,如果不符合,则不发送请求。优点:规则不满足时,可以减少不必要的请求。缺点:客户端写死校验逻辑,密码规则变化时,客户端需要发版。
    客户端只判断null,和最短位数限制,其他校验规则交由后端处理。优点:灵活性最好。缺点:后端压力大,校验请求多。
    后端在通用配置的接口返回正则表达式,客户端获取后进行正则校验。优点:具有一定灵活性。缺点:开发,调试成本较高。(推荐:即使出问题,也可以清除配置,回退到第2个方案)

    2.4 服务器选型
    2.4.1 服务器要运行什么应用
    Web服务器对硬件要求不高,一般的硬件配置即可满足需求,如果后期Web服务访问量上升,只需要新增同等配置的服务器,通过负载均衡进行集群,即可实现Web服务的性能扩展。
    数据服务器对硬件要求最高,主要特征是CPU要足够快、内存足够大,磁盘IO足够快和稳定。比如:MySQL、Oracle服务器要求CPU配置一定要好,磁盘最好使用SSD系列。
    而Redis服务器主要是内存型应用,所以要求内存一定要足够大,并且可扩展,但对磁盘和CPU要求就没那么高。
    应用服务器的典型特征是承担了计算和功能实现。对CPU的配置有一定的要求。对于可靠性问题,如果你只有一台服务器的话,那么这台服务器必须足够可靠,磁盘做成RAID1阵列是必不可少的。
    还有一些公用的服务器,例如:邮件服务器、DNS服务器、域控服务器。对稳定性要求较高,因此一般会推荐有至少两台进行主、备部署。对硬件来说,没有特殊的需求,所以一般的硬件即可。
    2.4.2 业务系统要支持多少用户
    多少用户会同时在线
    每天同时在线访问最高峰值
    数据量多大
    网络带宽占用多少
    2.4.3 要用多大空间存储数据,需要怎样的硬盘存储
    通过数据类别、数据增速规划1-3年内数据量大小,然后乘以1.5左右的系数;
    磁盘有SATA、SAS和SSD三种类型,SATA、SAS属于机械硬盘,转速低,读写速度慢,但是价格便宜,磁盘容量大。SSD硬盘属于固态硬盘,优点是读写速度快,缺点是价格昂贵,一般采用RAID技术。
    2.4.4 需要多大的内存
    相比于CPU,内存(RAM)是影响性能的关键因素,很多业务系统CPU利用率一般在10%-50%之间。
    Web前端服务器,如apache、nginx,主要处理静态请求,不需要太大的内存,一天几十万的访问量,4GB内存足够了。
    后台应用服务器,如Tomcat、Resin、WebLogic、Websphere、jboss等,配置内存在16GB-32GB即可。
    内存型业务系统,如redis、Squid、Varnish、Memcached等,需要配置尽可能高的内存。

    2.5 踩坑经历
    一定要分离生产、研发、预发布环境。
    避免过早优化,避免过度工程化。
    采用成熟的技术:刚开发的或开源的技术往往存在很多隐藏的bug,出了问题没有商业支持可能会是一个灾难;
    资源隔离设计:应避免单一业务占用全部资源;
    回滚设计:确保系统可以向前兼容,在系统升级时应能有办法回滚版本;
    禁用设计:应该提供控制具体功能是否可用的配置,在系统出现故障时能够快速下线功能;
    监控设计:在设计阶段就要考虑监控的手段;
    N+1设计:系统中的每个组件都应做到没有单点故障;
    多活数据中心设计:若系统需要极高的高可用,应考虑在多地实施数据中心进行多活,至少在一个机房断电的情况下系统依然可用;

    三、参考资料
    3.1 行业方案架构
    阿里云行业方案架构
    https://www.aliyun.com/solution/iot/community?spm=5176.13110641.J_8058803260.850.2c8225e2UsMn5g
    腾讯云行业方案架构
    https://cloud.tencent.com/solution/x-insight
    电商类架构参考
    https://www.cnblogs.com/wintersun/p/6683957.html
    3.2、接口设计参考
    https://www.cnblogs.com/zhouguowei/p/5264775.html
    https://blog.csdn.net/u014315849/article/details/78567399
    https://blog.csdn.net/lingshaoxia/article/details/21097839?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
    3.3 数据存储设计参考
    数据库设计
    https://blog.csdn.net/caoxiaohong1005/article/details/78133912?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control
    https://www.cnblogs.com/javalyy/p/10895393.html
    缓存设计
    https://www.cnblogs.com/findbetterme/p/11289445.html
    https://blog.csdn.net/jiangzhaobao/article/details/113102743
    数据存储对比
    https://www.cnblogs.com/caiyongliang/p/13719347.html
    3.4 后端技术框架介绍
    https://www.jianshu.com/p/b025b03b3783
    3.5 均衡负载&反向代理相关介绍
    https://www.cnblogs.com/sharpest/p/10965510.html
    SLB(服务器负载均衡):在多个提供相同服务的服务器的情况下,负载均衡设备存在虚拟服务地址,当大量客户端从外部访问虚拟服务IP地址时,负载均衡设备将这些报文请求根据负载均衡算法,将流量均衡的分配给后台服务器以平衡各个服务器的负载压力,避免在还有服务器压力较小情况下其他服务达到性能临界点出现运行缓慢甚至宕机情况,从而提高服务效率和质量,因此对客户端而言,RS(real server 实际服务器)的IP地址即是负载均衡设备VIP(虚拟服务地址IP)地址,真正的RS服务器IP地址对于客户端是不可见的。
    反向代理是实现负载均衡的一种方法。
    先谈反向代理。用户在请求时,先把请求发送给代理的服务器,然后由代理服务器根据算法去请求真实的服务器,最后返回给用户。这种做法,其一是提高了安全性;其二是通过多台的real server分担了用户的请求,实现了负载均衡。
    再谈负载均衡。负载均衡的出现,是通过横向的扩展,尽可能地降低单台服务器的压力。常见WEB层面的负载均衡的方案有硬件F5、Nginx代理、LVS、各个云商的负载均衡服务(如AWS的ELB服务)等。负载均衡后面连的一般是实际提供服务的服务器,如通过ELB服务,可以做到流量的均匀分担,从而减少单机服务器的压力。
    由于增加了负载均衡这层,所以单纯地使用某个方案还是要考虑单点的问题。负责由于负载均衡这个服务器未能承受住压力,宕机了,服务也是不可用的。所以Nginx、LVS尽量配置多台代理,可以故障转移和故障报警,从而及时去处理代理层服务器的问题。ELB是亚马逊提供的服务,它本身的实现底层就有数百甚至上千的机器,所以把它想象成一个代理集群就好。