如果你是一个半路入门的前端工程师,只会使用javascript
写一些页面, 有一天听闻了node.js 可以开发后端,于是兴致勃勃的去用node.js搞后端。
但是你只懂得前端的知识点,面对后端的各中高大上的知识点,比如说数据库,冷备份等,陷入了恐惧和气馁。
我也是这样。
这种情况下,我们需要学习不单单是node, 而是整个后端的海洋。因此我希望这个《写给node开发者看的后端知识图谱》可以帮助到你。
在这个系列里面,不会介绍任何有关node的知识点,如果你想探讨node相关,请移步我的《成为自信的node.js开发者》系列。
有任何问题和建议,都可以联系我,我会虚心改正滴~
后端服务的架构模式
我们在和后端同学打交道的过程中,经常会听到各种各样高大上的术语,这就需要我们对后端的架构有一个大概的了解。
后端技术在发展的过程中,很多网站提出了自己的解决方案,这些解决方案被不同的网站反复使用,从而就形成了大型网站架构模式。
分层
分层是横向的划分。大型网站,后端系统分为 应用层,服务层,数据层。
应用层: 处理具体的业务逻辑
服务层: 提供一些服务化的接口,比如说发券,发红包
数据层: 比如说数据库,缓存,文件等。
分层结构的挑战
分层结构必须要划分合理
禁止跨层次调用(比如说,应用层直接调用数据层)
禁止逆向调用(比如说,数据层调用服务层)
三层结构可以部署在同一台机器上,也可以部署在不同的服务器上。
分割
分割是对纵向的划分。大型网站有很多功能,比如说,搜索,购物车,推荐。这些小应用可以分割为不同的模块,交给不同的团队来维护。
分割可以把不同的业务放在不同的机器上,比如说,交易等对性能要求比较高的模块可以放在更高性能的机器上,而评论等模块则可以视情况降级。
分布式
分布式意味着,把不同的后端服务部署在不同的服务器上。
分布式遇到的挑战
分布式不同的机器之间,通过网络调用,性能会有影响
服务器越多,宕机的可能性越高
保持数据一致性比较困难
集群
集群是,把不同的服务器部署相同的设备。不同的服务器之间会负载均衡。
因为服务器集群有更多的服务器提供相同的服务,所以并发性更高,当访问量飙升时,只需要加机器就可以了。
当某台机器发生故障时,只需要负载均衡,或者失效转移都会把流量打到其他服务器上,使得用户仍可以正常访问。
缓存
缓存是改善性能的第一手段。在后端的世界中,缓存几乎无处不在。
缓存主要包括下面:
1、CDN
CDN, 内容分发网络(content delivery network), 由遍布全国的高性能加速节点构成。当您的用户向您的某一业务内容发起请求时,请求会被调度至最接近用户的服务节点.
CDN 出现的原因
-
用户与业务服务器地域间物理距离较远,传输延时较高且不稳定;
-
请求需要运营商之间进行互联转发。
-
业务服务器网络带宽、处理能力有限,当接收到海量用户请求时,会导致响应速度降低、可用性降低。
CDN 请求的全流程
-
假设发起一个请求为
http://www.test.com/1.jpg
,需要会先向Local DNS
发起域名解析请求。 -
当local DNS 解析
www.test.com
时,发现该域名已经配置了CNAME 指向www.test.com.cdn.dnsv1.com
, 解析请求会发送至 腾讯云,会为请求分配最佳节点 IP -
Local DNS 获取 Tencent DNS 返回的解析 IP
-
用户获取解析 IP
-
用户向获取的 IP 发起对资源 1.jpg 的访问请求
-
若该 IP 对应的节点缓存有 1.jpg,则会将数据直接返回给用户(10),此时请求结束。若该节点未缓存 1.jpg,则节点会向业务源站发起对 1.jpg 的请求(6、7、8),获取资源后,结合用户自定义配置的缓存策略,将资源缓存至节点(9),并返回给用户(10),此时请求结束。
2、 反向代理
反向代理部署在服务器之前,如果发现有缓存的静态资源,则直接返回静态资源,无需访问服务器。
3、分布式缓存
现在大型网站中,缓存往往非常巨大,一个机器承受不住,所以除了本地缓存,还有分布式缓存,将缓存存放在一个专门的集群中,应用程序通过网络访问缓存数据。
异步
作为一个前端,我们肯定对异步不陌生。异步是典型的生产消费模式,两者不直接调用,而是通过消息来交流。
异步带来很多好处:
提高系统可用性
消费方出现了堆积,不影响生产方的逻辑。
比如说,之前,我们的用户支付和发券是写在一起的,很多时候,用户支付成功了,但是发券因为商家配置的券有问题,导致发券失败,从而返回给用户支付失败。后来改成,【发券逻辑】去订阅【支付成功】的消息,【发券逻辑】失败,不会影响用户支付成功。
复制代码
加快了网站的响应速度。
生产方处理完逻辑,只需要发出消息,就直接返回响应。
复制代码
削平峰值
网站有高负载的时候,也有低谷的时候。使用消息队列,将突然增加的访问请求数据放入消息队列中,等待消费者服务器依次处理,压力就会小很多。
复制代码
后端服务的核心要素
高性能
性能是很重要的一个方面,从前端到后端,每一个环节上都可以有优化。
对于前端方面,性能优化可以浏览我的博客《前端性能探究》。
对于后端方面,可以使用本地缓存或者分布式缓存,可以组建集群,可以使用多线程,可以改善内存管理,可以对数据库增加索引、缓存等等。
上述方法,不用着急,下文会深入讲到。
可用性
我们追求服务高可用性,说白了就是后端服务不宕机。
保持运行环境的高可用,主要方法是,把我们的应用部署在多个服务器上,数据库备份在多个服务器上。当某一个机器宕机了,只需要把请求切换到其他服务器上即可。
上述有一点要求,应用服务器上不能存储会话信息。
对于开发环境的高可用,需要引入自动化发布,自动化测试,灰度发布等手段,减少把bug引入到线上的可能性
伸缩性
所谓的伸缩性,就是往集群里面新增加一台机器是否方便。
对于应用服务器集群,只要服务器上不保存数据,所有的服务器都是对等的。
对于缓存服务器集群,新加入的机器会让缓存路由失效,从而导致缓存失效,大量的请求打到数据库上,从而导致网站崩溃。所以要改善路由算法。
对于关系型数据库,虽然可以数据复制,主从热备,但是很难做到大规模集群的可伸缩,因此关系数据库通过路由分区等手段。
对于NoSql数据库,天生就是为伸缩性而生,则支持度比较好。
拓展性
所谓的拓展性,就是,能够快速新增一个新的业务线,而不会对现有的业务有很深的耦合,其他的业务线不会进行牵连或改动。
主要手段有两点: 事件驱动架构和分布式服务
事件驱动架构,主要是通过消息队列来实现的,将消息产生和消息处理解耦开。比如说,我们新增一个618临时营销活动,当用户下单成功后,给用户发放某种卡片。我们不是改动用户下单的代码,而是监听用户下单的消息队列。
分布式服务,是通过将业务代码和可复用的服务抽离开来。比如说,公司里面有A,B,C三个业务线,都需要对用户发放店铺券,就可以提供java的服务化接口,我们node 的业务通过 dubbo 来调用。
安全性
安全性保护网站不受恶意攻击。
小结
恭喜你,看到了这里。上面的性能
, 高可用
, 伸缩性
, 拓展性
, 安全性
是对接下来内容的提纲挈领。如果你有任何的疑问,请放心大胆的跳过去,我会在后面的文章细细介绍。