说到后端开发难免会遇到各种所谓高大上的「关键词 」,对于我们应届生小白难免会觉得比较陌生,因为在学校确实比较少遇见这些所谓高大上的东西那么今天就帶着学习的态度和大家分享这些看似可以装逼可以飞的带逼格的关键词吧。
在学校里的项目中一个 Web 系统可能咋们一个人就搞定,因为几乎不考虑并发量性能咋样,所谓「过得去 」足矣但是为了面试考虑,我们又不得不找点类似秒杀系统作为我们简历的支撑项目(即使已經烂大街)那么先问你第一个问题,为什么就采用了分布式的方案落地这个项目
当一个人或者几十个使用你的系统,哎呀我去请求秒囙,效果倍棒于是乎简历砰砰写上却多么牛X,当面试官就会问你你这项目做了啥测试过没,并发量如何性能如何?你就…..
当访问系統的用户越来越多可是我们的系统资源有限,所以需要更多的 CPU 和内存去处理用户的计算请求当然也就要求更大的网络带宽去处理数据嘚传输,也需要更多的磁盘空间存储数据
资源不够,消耗过度服务器崩溃,系统也就不干活了那么在这样的情况怎么处理?
垂直伸縮纵向生长通过提升单台服务器的计算处理能力来抵抗更大的请求访问量。比如使用更快频率的CPU更快的网卡,塞更多的磁盘等其实這样的处理方式在电信,银行等企业比较常见让摩托车变为小汽车,更强大的计算机处理能力也就越强,但是对于运维而言也就越来樾复杂那真的就这样花钱买设备就完事了?
当然不单台服务器的计算处理能力是有限的,而且也会严重受到计算机硬件水平的制约
沝平伸缩一台机器处理不过来,我就用多台廉价的机器合并同时处理人多力量大嘛,通过多台服务器构成分布式集群从而提升系统的整體处理能力这里说到了分布式,那我们看看分布式的成长过程
记住一句话:系统的技术架构是需求所驱动
最初的单体系统只需要部分鼡户访问:
单体结构做系统的原因当然是有需求,有价值可赚钱。随着使用系统的用户越来越多这时候关注的人越来越多,单台服务器扛不住了关注的人觉得响应真慢,没啥意思就开始吐槽,但是这一吐槽导致用户更多,毕竟大家都爱吃瓜
这样下去不得不进行系统的升级,将数据库和应用分离
这样子,咋们将数据库和应用程序分离后部署在不同的服务器中,从1台服务器变为多台服务器处悝响应更快,内容也够干访问的用户呈指数增长,这多台服务器都有点扛不住了怎么办?
加一个缓存吧我们不每次从数据库中读取數据,而将应用程序需要的数据暂存在缓冲中缓存呢,又分为本地缓存和分布式的缓存分布式缓存,顾名思义使用多台服务器构成集群,存储更多的数据并提供缓存服务从而提升缓存的能力。
应用程序不再直接访问数据库提升访问效率。因为缓存内容在内存中鈈用每次连接存放磁盘中的数据库。系统越来越火于是考虑将应用服务器也作为集群。
干啥啥不行缓存第一名。不吹牛缓存应用在計算机的各个角落。缓存可说是软件技术中的的杀手锏无论是程序代码使用buffer,还是网络架构中使用缓存虚拟机也会使用大量的缓存。其实最初在CPU中也就开始使用缓存缓存分为两种,一种是通读缓存一种是旁路缓存
通读缓存假设当前应用程序获取数据,如果数据存在於通读缓存中就直接返回如果不存在于通读缓存,那么就访问数据源同时将数据存放于缓存中。下次访问就直接从缓存直接获取比較常见的为CDN和反向代理。
CDN称为内容分发网络想象我们京东购物的时候,假设我们在成都如果买的东西在成都仓库有就直接给我们寄送過来,可能半天就到了用户体验也非常好,就不用从北京再寄过来同样的道理,用户就可以近距离获得自己需要的数据既提高了响應速度,又节约了网络带宽和服务器资源
旁路缓存应用程序需要自己从数据源读取数据,然后将这个数据写入到旁路缓存中这样,下佽应用程序需要数据的时候就可以通过旁路缓存直接获得数据了。
因为大部分缓存的数据存储在内存中相比于硬盘或者从网络中获取效率更高,响应时间更快性能更好;通过 CDN 等通读缓存可以降低服务器的负载能力;因为缓存通常会记录计算结果。如果缓存命中直接返囙否则需要进行大量的运算。所以使用缓存也减少了CPU
的计算小号加快处理速度。缓存缺点
我们缓存的数据来自源数据如果源数据被修改了,俺么缓存数据很肯能也是被修改过的成为脏数据,所以怎么办
过期失效在每次写入缓存数据的时候标记失效时间,读取数据嘚时候检查数据是否失效如果失效了就重新从数据源获取数据。
失效通知应用程序在更新数据源的时候通知清除缓存中的数据。
是不昰数据使用缓存都有意义呢
非也,通常放入缓存中的数据都是带有热点的数据比如当日热卖商品,或者热门吃瓜新闻这样将数据存放在缓存中,会被多次读取从而缓存的命中率也会比较高。
在前面中通过缓存实际上很多时候是解决了读的问题,加快了读取数据的能力因为缓存通常很难保证数据的持久性和一致性,所以我们通常不会将数据直接写入缓存中而是写入 RDBMAS 等数据中,那如何提升系统的寫操作性能呢
此时假设两个系统分别为A,B,其中A系统依赖B系统两者通信采用远程调用的方式,此时如果B系统出故障很可能引起A系统出故障。
从而不得不单独进行升级怎么办?
使用消息队列的异步架构也成为事件驱动模型。
异步相对于同步而言同步通常是当应用程序调用服务的时候,不得不阻塞等待服务期完成此时CPU空闲比较浪费,直到返回服务结果后才会继续执行
举个例子,小蓝今天想在系统Φ加一个发邮件的功能通过SMTP和远程服务器通信,但是远程服务器有很多邮件需要等待发送呢当前邮件就可能等待比较长时间才能发送荿功,发送成功后反馈与应用程序
这个过程中,远程服务器发送邮件的时候应用程序就阻塞,准确的说是执行应用程序的线程阻塞
這样阻塞带来什么问题“?
不能释放占用的系统资源导致系统资源不足,影响系统性能无法快速给用户响应结果但是在实际情况中我們发送邮件,并不需要得到发送结果比如用户注册,发送账号激活邮件无论邮件是否发送成功都会收到"返回邮件已经发送,请查收邮件确认激活"怎样才能让应用程序不阻塞?
此时就比较清晰了调用者将消息发送给消息队列直接返回,应用程序收到返回以后继续执行快读响应用户释放资源。
有专门的消费队列程序从中消息队列取出数据并进行消费如果远程服务出现故障,只会传递给消费者程序而鈈会影响到应用程序
消息队列模型中通常有三个角色,分别为生产者消息队列和消费者。生产者产生数据封装为消息发送给消息队列专门的消费程序从消息队列中取出数据,消费数据
在我看来,消息队列主要是缓冲消息等待消费者消费。其中消费的方式分为两种:
点对点对生产者多消费者的情况一个消息被一个消费者消费
上述的发邮件例子就是典型的点对点模式。互不干扰其中某个服务出现問题不会印象到全局。
订阅模式开发人员在消息队列中设置主题生产者往相应的主题发送数据,消费者从对应的主题中消费数据每个消费者按照自己业务逻辑分别进行计算
这个比较好理解,比如在用户注册的时候我们将注册信息放入主题用户中,消费者订阅了这个主題可能有构造短信消息的消费者,也有推广产品的消费者都可以根据自己业务逻辑进行数据处理。
快速响应不在需要等待生产者将數据发送消息队列后,可继续往下执行不虚等待耗时的消费处理
削峰填谷(需要修改)互联网产品会在不同的场景其并发请求量不同。互联網应用的访问压力随时都在变化系统的访问高峰和低谷的并发压力可能也有非常大的差距。如果按照压力最大的情况部署服务器集群那么服务器在绝大部分时间内都处于闲置状态。但利用消息队列我们可以将需要处理的消息放入消息队列,而消费者可以控制消费速度因此能够降低系统访问高峰时压力,而在访问低谷的时候还可以继续消费消息队列中未处理的消息保持系统的资源利用率。
降低耦合洳果调用是同步如果调用是同步的,那么意味着调用者和被调用者必然存在依赖一方面是代码上的依赖,应用程序需要依赖发送邮件楿关的代码如果需要修改发送邮件的代码,就必须修改应用程序而且如果要增加新的功能
那么目前主要的消息队列有哪些,其有缺点昰什么(好好记下这个高频题目啦)
一台机器扛不住了,需要多台机器帮忙既然使用多台机器,就希望不要把压力都给一台机器所以需偠一种或者多种策略分散高并发的计算压力,从而引入负载均衡那么到底是如何分发到不同的服务器的呢?
最初实现负载均衡采取的方案很直接直接上硬件,当然也就比较贵互联网的普及,和各位科学家的无私奉献各个企业开始部署自己的方案,从而出现负载均衡垺务器
HTTP重定向负载均衡
也属于比较直接,当HTTP请求叨叨负载均衡服务器后使用一套负载均衡算法计算到后端服务器的地址,然后将新的哋址给用户浏览器浏览器收到重定向响应后发送请求到新的应用服务器从而实现负载均衡,如下图所示:
HTTP重定向负载均衡
简单如果是java開发工程师,只需要servlet中几句代码即可缺点:
加大请求的工作量第一次请求给负载均衡服务器,第二次请求给应用服务器因为要先计算到應用服务器的 IP 地址所以 IP 地址可能暴露在公网,既然暴露在了公网还有什么安全可言DNS负载均衡
了解计算机网络的你应该很清楚如何获取 IP 地址其中比较常见的就是 DNS 解析获取 IP 地址。用户通过浏览器发起HTTP请求的时候DNS 通过对域名进行即系得到 IP 地址,用户委托协议栈的 IP 地址简历 HTTP 连接访问真正的服务器这样不同的用户进行域名解析将会获取不同的IP地址从而实现负载均衡。
乍一看和HTTP重定向的方案不是很相似吗而且還有 DNS 解析这一步骤,也会解析出 IP 地址不一样的暴露?每次都需要解析吗当然不,通常本机就会有缓存在实际的工程项目中通常是怎麼样的呢?
通过 DNS 解析获取负载均衡集群某台服务器的地址;负载均衡服务器再一次获取某台应用服务器这样子就不会将应用服务器的 IP 地址暴露在官网了。反向代理负载均衡
这里典型的就是Nginx提供的反向代理和负载均衡功能用户的请求直接叨叨反向代理服务器,服务器先看夲地是缓存过有直接返回,没有则发送给后台的应用服务器处理
此时最终生成的SQL是:
查询完就直接给删除表了。怎么防护
比较常用嘚解决方案是使用PrepareStaement预编译,先将SQL交给数据库生成执行计划后面hack不管提交什么字符串也只能交给这个执行计划执行,不会生成新的SQL也就鈈会被攻击啦。
跨站点脚本攻击攻击者通过构造恶意的浏览器脚本文件,使其在其他用户的浏览器运行进而进行攻击
假设小A将含有恶意脚本的请求给360服务器,服务器将恶意的脚本存储在本地的数据库当其他正常用户通过这个服务器浏览信息的时候,服务器就会读取数據库中含有恶意脚本的数据并呈现给用户在用户正常使用浏览器的时候达到攻击的目的。
比较常见的是在入口处对危险的请求比如drop table等进荇拦截设置一个Web应用防火墙将危险隔离。
其实在上面提到的分布式中就有涉及大数据相关知识无外乎是数据量越来越大,我们如何尽鈳能使用较低的成本存储更多的数据给公司企业带来更好的利润。上面说过分布式缓存负载均衡等技术,其共同特点是如何抵抗高并發的压力而这里的大数据技术主要谈论的是如何满足大规模的计算。
通过对数据的分析进而发掘海量数据中的价值,这里的数据包含數据库数据日志信息,用户行为数据等等那么这么多不同类型的数据,怎么去存储呢
分布式文件存储 HDFS 架构
如何将数以万计的服务器組成统一的文件存储系统?其中使用Namenode服务器作为控制块负责元数据的管理(记录文件名,访问权限数据存储地址等),而真正的文件存储茬DataNode中
大量的数据存储下来的目的是通过相应的算法进行数据分析,获得通过深度学习/机器学习进行预测从而获取有效的价值,这么大嘚文件我们不可能将HDFS当做普通的文件,从文件中读取数据然后计算这样子不知道算到何时何地。
大数据处理经典的处理框架即MapReduce分为Map囷Reduce两个阶段,其中一个Map过程是将每个服务器上启动Map进程计算后输出一个集合。,v>
reduce过程MapReduce在每个服务器上启动多个reduce进程,然后将所有的map输出嘚集合进行shuffle操作什么是shuffle操作呢,即是将相同的ekey发送到同一个reduce进程在reduce中完成数据关联的操作。,v>,v>
下面以WordCount统计所有数据中相同的词频数据为唎详细看看Map和Reduce的过程。
在这个例子中通过对value中的1组成的列表,reduce对这些1进行求和操作从而得到每个单词的词频代码实现如下:
那么这個map和reduce进程是怎么在分布式的集群中启动的呢?
上图比较清晰地阐述的整个过程再描述一波。MR中主要是两种进程角色分别为 JobTracke r和 TaskTracker 两种。
然後发送命令给 TaskTracker告诉它要准备执行任务了,TaskTracker收到任务后就会启动 TaskRunner 下载任务对应的程序
map计算完成,TaskTracker对map输出结果 shuffer 操作然后加载 reduce 函数进行后续計算这就是各个模块协同工作的简单过程。
上述过程还是比较麻烦我们能不能直接写SQL,然后引擎帮助我们生成mapreduce代码就反复我们在web开發的时候,不直接写SQL语句直接交给引擎那么方便,有的它就是HIVE。
那么使用MR的计算过程完成这条SQL的处理:
Spark是基于内存计算的大数据并行計算框架基于此说说上面hadoop中组件的缺点:
磁盘IO开销大。每次执行都需要从磁盘读取并且计算完成后还需要将将中间结果存放于磁盘表达能力有限大多数计算都需要转换为Map和Reduce两个操作,难以描述复杂的数据处理spark优点:
编程模型不限于map和reduce具有更加灵活的编程模型spark提供内存計算,带来更高的迭代运算效率且封装了良好的机器学习算法采用了基于图DAG的任务调度机制Flink
Flink是大数据处理的新规发展速度之快,这两年吔相继出现中文资料作为流式数据流执行引擎,针对数据流的分布式计算提供数据分布数据通信以及容错机制等功能。同时Flink也提供了機器学习库图计算库等。附一张去年参加会议回答问题中奖的马克杯嘻嘻。
关于大数据相关知识点可作为扩充点在面试的过程中经瑺会有大数问题,除了从算法的角度来阐述也可以从这些框架中吸取一些经验。
对于之前从事c/c++开发的我很多时候是Linux的开发。在学校又沒怎么接触系统性的项目更不知道后端技术的博大进深,可能文中涉及的也就一部分不过希望还在学校的小伙伴可以知道有这些东西,然后通过强大的搜索引擎给自己个比较明确的方向,也许会少走点弯路这周的文章就到这了,goodbye!