【系统设计】系统设计面试相关课题的速成“葵花宝典”!

2013-09-10T13:11:33+08:00 | 28分钟阅读 | 更新于 2013-09-10T13:11:33+08:00

Macro Zhao

【系统设计】系统设计面试相关课题的速成“葵花宝典”!

@TOC

推荐超级课程:

这是一门关于系统设计面试概念的完全速成讲解,这些概念是您在面试系统设计师工作前需要了解的。 系统设计面试与编码无关,人们不想看到您编写实际代码,而是想看到您如何将整个系统组合在一起, 这正是我们将在本教程中涵盖的内容,我们将讨论所有您设计大规模分布式系统之前需要了解的概念。

计算机架构(磁盘存储、内存、缓存、CPU)

要了解个人计算机的高级架构,在计算机上不同部件如何共同执行我们的代码,计算机通过分层系统运行,每一层针对不同任务进行优化。

计算机只能理解二进制的0和1,这些被表示为比特,一位比特是计算中最小的数据单位, 可以是0或1,一个字节包含8个比特,用于表示单个字符比如一个数字。从这里扩展,我们有千字节,兆字节,吉字节和太字节来存储这些数据,我们有计算机磁盘存储来存储这些数据,其中保存主要数据,它可以是HDD或SSD类型。磁盘存储是非易失性的,它在没有电源的情况下保持数据,这意味着如果您关闭或重新启动计算机,数据仍将存在,它包含应用程序和所有用户文件,就容量而言,典型的磁盘范围从数百GB到多个TB,而SSD更昂贵,但提供比HDD快得多的数据检索速度比如,SSD可能每秒有500到3500兆字节,而HDD可能提供80到160兆字节每秒,磁盘之后的下一个即时访问点是RAM或随机访问内存(RAM),RAM用作主要的活动数据持有者,并且它保存当前正在使用或正在处理的数据结构,变量和应用程序数据。

当程序运行时,其变量,中间结果计算,运行时堆栈等存储在RAM中,因为它允许快速读写访问,这是一种易失性内存,这意味着它需要电源来保留其内容,重启计算机后可能数据不会被保存,就容量而言RAM在消费设备中为几GB,而高端服务器可能为几百GB,在读写速度上通常超过每秒5000兆字节,比甚至最快的SSD 硬盘速度都要快,但有时候即使是这种速度也不够,这就引出了缓存,缓存比RAM更小,通常以兆字节为单位,但与RAM相比,缓存内存的访问时间更快,L1缓存,CPU首先检查L1缓存中的数据,如果没有找到,它会检查L2和L3缓存,最后检查RAM缓存的目的是减少访问数据的平均时间,这就是我们在这里存储频繁使用的数据以优化CPU性能CPU是计算机的大脑,当您运行代码时,CPU处理在程序中定义的操作,在可以运行我们的代码之前,需要首先编译成像Java,C++,Python或其他语言一样的机器代码编译器执行此转换,一旦代码编译成机器代码,CPU可以执行它,可以从我们的RAM磁盘和缓存数据读取和写入数据。

最后主板,它是将所有组件连接在一起的组件,它提供路径允许数据在这些组件之间流动,现在让我们看一下生产应用程序体系结构(CI/CD、负载均衡器、日志记录和监控)

应用程序体系结构(CI/CD、负载均衡器、日志记录和监控)

生产就绪的应用程序架构我们的第一个关键领域是CI/CD流水线持续集成和持续部署,这确保我们的代码从代码库通过一系列测试和流水线检查直接到生产服务器,而无需任何手动干预,它配置为使用平台如Jenkins或GitHub actions自动化我们的部署过程,一旦我们的应用程序在生产中,它必须处理大量用户请求,这是由我们的负载均衡器和反向代理器管理如nginx,他们确保用户请求均匀分布在多个服务器上,维持平滑的用户体验,即使在流量激增期间我们的服务器还需要存储数据,为此我们还有一个不在在同一生产服务器上运行的外部存储服务器,而是通过网络连接,我们的服务器也可能与其他服务器通信,并且可以有许多此类服务,而不仅仅一个,以确保所有事情顺畅运行,我们有日志记录和监控系统保持对每个微交互的警觉,存储日志和分析数据是标准实践,将日志存储在外部服务上通常在我们的主要生产中心区之外,关于后端工具像pm2可用于日志记录和监控,前端平台像Sentry可用于实时捕捉和报告错误

当事情不按计划进行时,意味着我们的日志系统检测到请求失败或异常,首先它会激活我们的警报服务,然后将推送通知发送给用户在日志系统检测到错误的请求或异常之后,首先会出现我们的警报服务,然后会向用户发送推送通知,以便让用户了解,从一般的某事崩溃到具体的支付失败

有效的沟通使用户不被留在黑暗中,培养信任和可靠性,现代实践是将这些警报直接集成到常用的平台中,比如Slack,想象一个专门的Slack频道,当问题出现时,警报会立即弹出,这使开发人员几乎可以即刻采取行动,解决根本原因,之后开发人员需要首先调试问题首先必须确定问题,我们之前提到的日志是我们的第一通电话,开发人员会浏览这些日志,寻找可能指向问题来源的模式或异常,之后它需要在安全环境中复制此问题安全环境的黄金规则是永远不要在生产环境中调试,而是开发人员在分期或测试环境中重新创建此问题,这可以确保用户不会受到调试过程的影响,然后开发人员使用工具观看运行数据应用程序并开始调试,一旦bug修复,会发布热修补,这是一种快速临时修复,旨在使事物再次运行,这就像一个补丁,在实现更持久的解决方案之前,这就像具体用例的最佳解决方案,这意味着制定关于我们可以承受何种妥协的明智决定。

系统SLA

系统的一个重要指标是可用性,这是系统的运行性能和可靠性的度量。

当我们谈及可用性时,实质上我们在问的是我们的系统在用户需要时是否正常运行,这通常以百分比的方式衡量,目标是达到"黄金59可用性",比如我们运行一个关键服务,具有99.9%的可用性,这意味着每年可以有大约8.76小时的宕机时间,但是如果我们加入两个NES,我们仅仅是在谈论每年大约5分钟的宕机时间,这是一个巨大的差异,尤其适用于每秒都重要的服务。我们经常以正常运行时间和宕机时间来衡量它,这里就涉及到服务水平目标和服务水平协议。SLO就像为我们的系统性能和可用性设定目标,例如,我们可能会设置一个SLO,规定我们的网络服务应该在99.9%的时间内在300毫秒内响应请求。另一方面,SLA就类似于我们与用户或客户之间的正式合同,它们定义了我们承诺提供的最低服务水平,所以如果我们的SLA保证了99.99%的可用性,而我们低于这个水平,我们可能需要向客户提供退款或其他补偿。将弹性融入我们的系统意味着对意外情况有所准备,这可能意味着实施冗余系统,确保总是有备用系统可以在出现故障时接管,或者可能意味着设计我们的系统以优雅地退化,即使某些功能不可用,核心功能仍然完好。为了衡量这一方面,我们使用可靠性、容错性和冗余度。可靠性意味着确保我们的系统正确而一贯地工作,容错性是指为发生意外情况做好准备,我们的系统如何处理意外故障或攻击,冗余度是指备份,确保如果系统的一部分失效,另一部分可以顶替上去。我们还需要衡量我们系统的速度,为此我们有吞吐量和延迟。吞吐量衡量我们的系统在一定时间内可以处理多少数据,我们有服务器吞吐量,单位是每秒请求量,这个指标提供了服务器可以处理多少客户端请求的指示,更高的RPS值通常表示更好的性能和处理更多并发用户的能力,我们有数据库吞吐量,单位是每秒查询次数,这量化了数据库在一秒内可以处理的查询数量,和服务器吞吐量类似,更高的QPS值通常代表更好的性能,我们还有数据吞吐量,单位是每秒字节数,反映了一定时间内通过网络传输或系统处理的数据量,另一方面,延迟衡量处理单个请求需要多长时间,即请求获得响应的时间,针对一个优化,通常可能会牺牲另一个,例如批处理操作可以增加吞吐量,但也可能增加延迟,设计一个多功能系统可能会导致许多问题,从性能瓶颈到安全漏洞,与可以轻松重构代码不同,重新设计系统可能是一项艰巨的任务,因此投资时间和资源来确保设计从一开始就是正确的,并建立一个坚实基础来支撑未来功能和用户增长是至关重要的,接下来是网络(TCP、UDP、DNS、IP地址和IP头)

网络设计

让我们谈谈网络基础知识,当我们谈网络基础知识时,实质上我们在探讨计算机如何相互通信,这种通信的核心是IP地址,每个网络中的设备都有一个唯一的标识符,IP V4地址是32位的,允许大约40亿个唯一地址,但随着设备数量的增加,我们正在转向IP V6,它使用128位地址,显着增加了可用唯一地址的数量,当两台计算机在网络上通信时,它们发送和接收数据包,每个数据包都包含一个IP头部,其中包含发送者和接收者的IP地址等基本信息,确保数据到达正确的目的地,这个过程受Internet协议的管理,它是一组定义数据如何发送和接收的规则,除了IP层,我们还有应用层,其中存储了特定于应用程序协议的数据,数据包中的数据格式按照特定的应用程序协议数据进行格式化,例如HTTP用于Web浏览,以便接收设备可以正确解释数据,一旦我们了解了IP地址和数据包的基础知识,我们就可以进入传输层,这时TCP和UDP出现,TCP在传输层运行,确保可靠通信,它类似于一个快递员,不仅确保您的包裹到达,还检查是否有任何遗漏,因此每个数据包还包括一个TCP头部,其中包含端口号和控制流等必要信息,用于管理连接和数据流,TCP以其可靠性而闻名,确保数据包的完整正确交付,它通过顺序号等功能实现,以跟踪数据包的顺序和通过所谓的握手过程建立稳定的连接,而UDP比TCP更快,但不如TCP可靠,它在发送数据之前不建立连接,也不保证数据包的交付或顺序,但这使UDP在对实时性通信更快,例如视频通话或直播流时更受欢迎,速度是至关重要的,而一些数据损失是可以接受的,为了将所有这些概念联系在一起,让我们来谈谈DNS域名系统,DNS就像互联网的电话簿,将人类友好的域名解析成IP地址,当您在浏览器中键入URL时,浏览器发送DNS查询以找到相应的IP地址,从而建立与服务器的连接并检索网页,DNS的运行由IEN监督,协调全球IP地址空间和域名系统,域名注册商如Namechip或GoldEd经ICANN认可可以向公众出售域名,DNS使用不同类型的记录,如A记录,将域名映射到其对应的IP地址,确保您的请求到达正确的服务器,或AAAA记录,将域名映射到IP V6地址,最后让我们谈谈支持所有这些通信的网络基础设施,网络上的设备具有公共或私有IP地址,公共IP地址在互联网上是唯一的,而私有IP地址在本地网络中是唯一的,IP地址可以永久分配给设备,也可以是动态的随时间变化,动态IP地址通常用于家庭互联网连接,设备在本地区域网络中直接通信,为了保护这些网络,我们使用防火墙来监控和控制进出网络的流量,在设备内部,特定进程或服务通过端口进行识别,当与IP地址结合时产生一个对网络服务的唯一标识符,一些端口用于特定的协议,如80用于HTTP或22用于SSH,现在让我们覆盖所有基本的应用层协议(HTTP、WebSockets、WebRTC、MQTT等)

应用层协议中最常见的协议是HTTP,它代表着超文本传输协议,构建在TCP/IP之上,它是一个请求响应协议,但可以将其想象为一次没有记忆的对话,每次互动都是独立的,没有过去的记忆,这意味着服务器不必在请求之间存储任何上下文,相反,每个请求都包含了所有必要的信息,注意到头部包含了诸如URL和方法的细节,而正文携带了请求或响应的内容,每个响应还包括状态代码,用于提供关于客户端请求在服务器上的结果的反馈,例如200系列是成功代码,表示请求已成功接收和处理,300系列是重定向代码,表示需要用户代理进一步采取行动以完成请求,400系列是客户端错误代码,用于请求包含恶劣语法或无法实现,500系列是服务器错误代码,表示服务器发生故障,我们还有每个请求的方法,最常见的方法是get、post、put、patch和delete,get用于获取数据,post通常用于在服务器上创建数据,put和patch用于更新记录,delete用于从数据库中删除记录,HTTP是一种单向连接,但对于实时更新,我们使用WebSocket,提供了一个双向通信通道,通过单个长连接允许服务器向客户端实时推送更新,这对需要不断更新数据的应用程序非常重要,无需重复的HTTP请求响应周期,通常用于聊天应用、现场体育更新或股票市场信息流,关于电子邮件相关的协议,SMTP是互联网上的电子邮件传输标准,它是发送邮件消息之间的协议,大多数电子邮件客户端使用SMTP发送邮件,IMAP或POP3用于检索邮件,IMAP用于从服务器检索电子邮件,允许客户端访问和操作邮件,这对需要从多个设备访问电子邮件的用户来说是理想的,POP3用于从服务器下载电子邮件到本地客户端,通常用于在单个设备上管理电子邮件,继续讨论文件传输和管理协议,传统的文件传输协议是FTP,通常用于网站维护和大数据传输,用于客户端和服务器之间的文件传输,有助于将文件上传到服务器或备份文件,我们还有SSH或安全外壳,用于在未加密网络上安全地操作网络服务,常用于远程登录到远程计算机并执行命令或传输文件,还有实时通信协议如WebRTC,它可以实现浏览器到浏览器的语音通话、视频聊天和文件共享,无需内部或外部插件,这对像视频会议和直播流这样需要的不间断更新的应用程序非常关键,还有MQTT,它是一种轻量级的消息传输协议,适用于处理处理能力有限的设备和需要低带宽的场景,例如物联网设备,AMQP是用于消息中间件的协议,为企业级消息通信提供了稳健性和安全性,例如,在RabbitMQ等工具中使用,最后让我们谈谈RPC,这是一种允许一台计算机上的程序在服务器或另一台计算机上执行代码的协议,它是一种调用函数的方法,就像是一个本地调用一样在远程机器上执行函数,隐藏了网络通信的细节,使开发人员可以轻松地与远程函数交互,就像它们是与应用程序本地通信一样,许多应用层协议使用RPC机制执行其操作,例如,在Web服务中,HTTP请求可能会导致后台进行RPC调用,处理数据或代表客户端执行操作,或SMTP服务器可能会内部使用RPC调用处理电子邮件消息或与数据库交互,当然还有许多其他应用层协议,但在这里介绍的协议是最常用和对Web开发至关重要的。在这一部分,让我们讨论API设计。

API设计

通过从基础开始并逐步发展到定义出色的API的最佳实践,作为IT系统设计师,让我们考虑一个像Shopify这样的电子商务平台的API,如果您对此不熟悉,Shopify是一个著名的电子商务平台,允许企业在其上建立在线商店。在API设计中,我们关注定义输入,比如卖家提供的新产品的产品详细信息,以及查询API产品时返回的信息如何暴露给用户界面。CR代表创建、读取、更新和删除,这是任何数据驱动应用程序的基本操作。例如,要添加一个新产品,我们需要向/API SL产品发送post请求,产品详细信息在请求体中发送。要检索这些产品,我们需要向/i/产品发送get请求。对于更新,我们使用put或patch请求到/product/该产品的ID,删除与更新类似,再次/product/产品的ID。类似地,我们可能还有另一个向/product/产品的ID发送get请求来获取单个产品。另一部分是决定要使用的通信协议,如HTTP、Websockets或其他协议,以及数据传输机制,可以是Json、XML或协议缓冲区。这通常用于restful APIs,但我们也有GraphQL和gRPC范式,因此APIs有不同的范式,每个都有自己的协议和标准。最常见的是rest,代表表述状态转移,它是无状态的,这意味着从客户端到服务器的每个请求都必须包含理解和完成请求所需的所有信息,它使用标准的HTTP方法get post put和delete,并且可以被不同的客户端、浏览器或移动应用轻松消费。然而,restful API的缺点是它可能导致数据获取或数据获取不足,因为可能需要更多的端点来访问特定数据,通常restful APIs使用Json进行数据交换。另一方面,GraphQL APIs允许客户端请求他们需要的确切数据,避免过度获取和不足获取数据,它具有强类型的查询,但复杂的查询可能会影响服务器性能,所有请求都被发送作为post请求,graph API通常以HTTP状态代码响应,即使在错误情况下,响应体中也有错误详细信息。gRPC代表Google远程过程调用,它建立在提供高级功能的HTTP 2上,如复用和服务器推送,它使用协议缓冲区的方式序列化结构化数据,因此在带宽和资源方面足够,尤其适用于微服务,然而,与Json相比,它 less可读,并且需要http2支持才能运行,在电子商务环境中,您可能有用户到订单或订单到产品之间的关系,您需要设计端点以反映这些关系,例如,为了获取特定用户的订单,您需要查询get/用户SL用户id/orders。常见的查询还包括限制和偏移用于分页或开始和结束日期用于筛选某个日期范围内的产品,这使用户或客户端能够检索特定的数据集而不会使系统不堪重负。一个良好设计的get请求应该是IDMponasent,意味着多次调用它不会改变结果,并且始终返回相同的结果,get请求永远不应该修改数据,它们仅用于检索,如果需要更新或创建数据,您需要做put或post请求,当修改端点时,保持向后兼容性非常重要,这意味着我们需要确保更改不会破坏现有客户端,一种常见做法是引入新版本,例如第二版本产品,以便第一版本API仍然可以为旧客户端提供服务,第二版本API应为当前客户端提供服务,这是restful APIs的情况。在graphql APIs的情况下,添加新字段如V2字段而不移除旧字段有助于发展API而不破坏现有客户端,另一个最佳做法是设置速率限制,这可以防止API遭受DDoS攻击,用于控制用户在某个时间段内可以发出的请求数量,防止单个用户向您的单个API发送过多请求。另一个常见做法是设置CORS设置,这代表跨源资源共享,通过CORS设置,您可以控制哪些域可以访问您的API,防止不必要的跨站点交互。

缓存和CDN设计

现在想象一家公司正在芬兰的谷歌云数据中心中托管一个网站,对于在欧洲的用户加载可能需要大约100毫秒,但对于墨西哥的用户可能需要3到5秒。

幸运的是,有策略可以最小化远程用户的请求延迟,这些策略被称为缓存和内容交付网络,这两个概念是现代网站开发和系统设计中的重要概念。缓存是一种用于提高系统性能和效率的技术,它涉及在临时存储中存储某些数据的副本,以便将来对该数据的请求可以更快地提供服务。缓存可以存储在四个常见的地方,第一个是浏览器缓存,在这里我们在用户的本地计算机上存储网站资源,所以当用户重新访问站点时,浏览器可以从本地缓存中加载站点,而不是再次从服务器获取所有内容。用户可以通过调整浏览器设置来禁用缓存,在大多数浏览器中,开发者可以通过开发者工具禁用缓存,例如在Chrome中,我们在开发者工具的网络选项卡中有一个禁用缓存选项,缓存存储在由浏览器管理的客户端硬盘上的目录中,浏览器缓存将HTML、CSS和JS捆绑文件存储在用户的本地计算机上,通常在一个专用的缓存目录中由浏览器管理。我们使用缓存控制头来告诉浏览器该内容应该被缓存多长时间,例如,在这里,缓存控制被设置为7200秒,相当于2小时,当请求的数据在缓存中找到时,我们称之为缓存命中,另一方面,我们有缓存未命中,这发生在请求的数据不在缓存中时,需要从原始来源获取,并且缓存比率是从缓存中服务的请求与所有请求进行对比的百分比,较高的比率表示更有效的缓存,你可以检查缓存是否命中或未命中的header,例如在这种情况下,它显示未命中,所以缓存未命中,在缓存被发现的情况下,我们将会有命中,此外还有服务器缓存,该缓存涉及将经常访问的数据存储在服务器端,减少执行昂贵操作的需要,比如数据库查询,服务器端缓存存储在服务器上或在一个单独的缓存服务器上,或者在内存中,例如Redis,或者在硬盘上,通常服务器在查询数据库之前从数据缓存中查找数据,如果数据在缓存中,直接返回,否则服务器查询数据库,如果数据不在缓存中,服务器从数据库中检索它返回给用户,然后存储在缓存中以备将来请求,这是直接写入缓存的WR缓存情况,在这种情况下数据直接写入永久存储,绕过缓存,在写入性能不那么关键时使用,也有write through cache,数据同时写入缓存和永久存储,确保数据一致性,但可能比写入缓存慢一些,还有write back cache,数据首先写入缓存,然后在稍后的时间写入永久存储,这可以提高写入性能,但有丢失数据的风险,如果服务器崩溃,当缓存满了我们需要释放一些空间再次使用缓存,为此,我们有淘汰政策,这些政策是确定缓存满时要从中移除哪些项目的规则,常见的政策包括删除最近最少使用的条目或先进先出,我们首先移除最先添加的条目或删除最不经常使用的条目,数据库缓存是另一个至关重要的方面,它指的是缓存数据库查询结果以提高基于数据库的应用程序的性能,通常在数据库系统本身内进行,或者在外部缓存层上,如Radis或M cache,当发出查询时,我们首先检查缓存,以查看是否存储了该查询的结果,如果是,则返回缓存的数据,避免对数据库执行查询,但如果在缓存中找不到数据,那么查询将针对数据库执行,结果将存储在缓存中以备将来请求,这对于读取密集型应用程序是有益处的,一些查询经常被执行,我们使用与服务器端缓存相同的淘汰政策,另一种缓存类型是CDN,它们是一个分布在地理上的服务器网络,通常用于提供静态内容,如JavaScript、HTML、CSS或图像和视频文件,它们从原始服务器缓存内容并将其交付给最近的CDN服务器的用户,当用户请求像图片或网站这样的文件时,请求被重定向到最近的CDN服务器,如果CDN服务器有缓存内容,它将将其提供给用户,否则它将从原始服务器获取内容缓存,然后转发给用户,这是基于池的CDN类型,当用户首次请求时,CDN自动从原始服务器中拉取内容,这适用于具有大量经常更新的静态内容的网站,因为CDN自动保持内容最新,所以需要较少的主动管理,另一种类型是推送型CDN,这是您将内容上传到原始服务器,然后它将这些文件分发到CDN,当有大文件不经常更新但需要快速分发时,这非常有用,但需要更多的主动管理以确定CDN上存储了哪些内容,我们再次使用缓存控制头来告诉浏览器要缓存CDN上的内容多长时间,CDN通常用于传送静态资产,如图像、CSS文件、JavaScript捆绑包或视频内容,如果您需要确保用户的高可用性和性能,这将非常有用,它还可以减少对原始服务器的负荷,但在某些情况下仍然需要访问原始服务器,例如在提供经常变化的动态内容或处理需要实时处理的任务时,以及应用程序需要在CDN中无法执行复杂的服务器端逻辑的情况下,我们从CDN获得的一些好处是通过从距用户更近的位置提供内容来降低延迟,CDN显著降低延迟,还增加了高可用性和可伸缩性,CDN可以处理高流量负载,并且对硬件故障具有弹性,另外,它还提高了安全性,因为许多CDN提供安全功能,如防护和流量加密,另外缓存的好处也包括降低延迟,因为我们有快速的数据检索,因为数据是从附近的缓存中获取的,而不是从远程服务器获取,通过减少对主要数据源的请求次数降低服务器负载,总体更快的加载时间会带来更好的用户体验,现在让我们谈谈代理服务器。

代理服务器 (正向和反向)

在客户请求资源和服务器提供资源之间,代理服务器可以发挥各种作用,比如缓存资源以加快访问速度、匿名化请求和负载均衡在多个服务器之间。它基本上接收来自客户端的请求,将它们转发给相关的服务器,然后将服务器的响应返回给客户端。代理服务器有几种类型,每种类型都有不同的用途。以下是一些主要类型:第一种是前向代理,它位于客户端前面,用于向互联网上的其他服务器发送请求,通常用于在内部网络中控制互联网访问。下一种是反向代理,它位于一个或多个Web服务器的前面,拦截来自互联网的请求,用于负载均衡、加速网站以及作为安全层。另一种类型是开放代理,允许任何用户连接和利用代理服务器,通常用于匿名化网络浏览和绕过内容限制。我们还有透明代理类型,它们在不修改请求和资源的情况下传递它们,但对客户端可见,通常用于缓存和内容过滤。下一种类型是匿名代理,它可以被识别为代理服务器,但不会公开原始IP地址,用于匿名浏览。我们还有扭曲代理,它向目标服务器提供不正确的原始IP地址,类似于匿名代理,但目的是故意提供IP虚假信息。下一个广受欢迎的类型是高匿名代理或Elite代理,让检测代理使用变得非常困难,这些代理不发送X-Forwarded-For等标识头,确保最大程度的匿名性。前向和反向代理是最常用的代理服务器,前向代理充当客户端和服务器之间的中间层,当客户端发出请求时,首先发送到前向代理,前向代理然后评估请求,并根据其配置和规则决定是否允许请求、修改它或阻止它。前向代理的主要功能之一是在转发请求到目标服务器时隐藏客户端的IP地址,看起来好像请求是来自代理服务器本身的。让我们看看一些前向代理的例子用例, 比如Instagram代理,这是一种具体类型的前向代理,用于管理多个Instagram账户而不触发封禁或限制,营销人员和社交媒体经理使用Instagram代理看起来就像定位在不同地区或不同用户,让他们能够管理多个账户自动化任务或收集数据而不会被怀疑有可疑活动。Internet使用控制和监控代理是另一个例子,一些组织使用前向代理监控和控制员工的互联网使用,可以阻止访问不相关的网站,保护免受基于网络的威胁,还可以扫描传入内容中的病毒和恶意软件。经常访问的内容,通过前向代理也可以缓存流行的网站或内容,减少带宽使用量,加快网络内用户的访问速度。这在带宽昂贵或有限的网络中尤其有益,在匿名化网页访问方面,关注隐私的人们可以使用透明代理隐藏他们的IP地址和其他识别信息,使其难以追踪他们的网络浏览活动。另一方面,反向代理是一种类型的代理服务器,位于一个或多个Web服务器的前面,在请求到达服务器之前拦截客户端的请求,尽管前向代理隐藏客户端的身份,但反向代理实际上隐藏服务器的身份或隐藏其背后存在多个服务器的事实,客户端只与反向代理交互,可能不知道背后的服务器,它还会将客户端请求分发到多个服务器,平衡负载,确保没有单个服务器过载,它还可以压缩传入和传出的数据,缓存文件并管理SSL加密以减少负载时间和服务器负载一些常见的反向代理用例是负载均衡器,这些平衡流入的网络流量跨多个服务器,确保没有单个服务器得到太多负载,通过分发流量,我们防止任何单个服务器成为瓶颈,并确保维持最佳服务速度和可靠性CD也是一种反向代理,它们是一个服务器网络,根据用户的地理位置向用户传递网站的缓存静态内容,从原始服务器检索内容并缓存以使内容更接近用户实现更快的交付,另一个例子是Web应用程序防火墙,它们位于Web应用程序的前面,检查传入流量以阻止黑客入侵尝试并过滤出不需要的流量防火墙还可以保护应用程序免受常见的Web利用行为。另一个例子是SSL卸载或加速,一些反向代理处理SSL/TLS流量的加密和解密,把这个任务从Web服务器卸载出来以优化它们的性能。

负载均衡器设计

负载均衡器可能是代理服务器最流行的用例之一。它们将传入的流量分发到多台服务器上,以确保每台服务器都不承担过多的负载,有效地分散请求,从而增加应用程序的容量和可靠性。以下是一些常见的负载均衡策略和算法。第一个是“轮询”,是最简单的负载均衡形式,其中池中的每台服务器按顺序轮流接收请求。当到达最后一台服务器时,它会循环回到第一台。这种类型适用于具有类似规格且负载均匀可分配的服务器。下一个是“连接列表”算法,它将流量定向到活动连接最少的服务器。这对处理较长任务或服务器负载不均匀分布时很理想。接下来是“最短响应时间”算法,它使用响应时间最短且活动连接最少的服务器。这种有效性的目标是提供最快的响应请求。接下来是IP散列算法,根据客户端IP地址的哈希确定哪台服务器接收请求,这确保客户端始终连接到同一台服务器,并适用于在重要的应用程序中客户端需要与同一台服务器始终连接的情况。这些方法的变体也可以被采纳,我们来看一下加权算法。例如,在加权轮询或加权连接列表算法中,服务器被分配权重,通常基于其容量或性能指标,性能更强的服务器处理最多请求。当池中的服务器具有不同能力,如不同的CPU或不同的RAM时,这是有效的。我们还有地理算法,可以将请求定向到用户地理位置最近的服务器,或根据特定区域要求进行处理。这对于优先降低延迟的全球服务很有用。下一个常见算法是一致性散列,它使用哈希函数在各个节点之间分布数据。想象一个成环的哈希空间,每一端都环绕到开始,通常称为哈希环,节点和数据(如键或存储值)都会被散列到这个环上,以确保客户端每次连接到同一台服务器。负载均衡器的一个重要特性是对服务器的持续健康检查,以确保流量只会被定向到在线和响应良好的服务器。如果服务器故障,负载均衡器将停止向其发送流量,直到服务器恢复正常。负载均衡器可以采用不同形式,包括硬件、应用软件解决方案和基于云的服务。一些流行的硬件负载均衡器有广泛使用的高性能F5 Big-IP以及提供本地流量管理、全局服务器负载平衡和应用安全的Citrix(原NetScaler)。一些流行的软件负载均衡器有广受欢迎的开源软件负载均衡器和代理服务器AJ Proxy,以及通常用作Web服务器但同时也作为HTTP和其他网络协议的负载均衡器和反向代理的EnginX等。一些流行的基于云的负载均衡器有AWS的弹性负载平衡、微软Azure的负载平衡器或谷歌云的负载平衡器。甚至还有一些虚拟负载均衡器,如VMware的先进负载均衡器,它提供了一个软件定义的应用交付控制器,可在本地部署或云中部署。当负载均衡器故障时,会发生什么呢?当负载均衡器故障时,可能会影响整个应用程序或服务的可用性和性能。这基本上是一个单点故障,如果负载均衡器宕机,客户端将无法访问所有服务器。为避免或减少负载均衡器故障的影响,我们可以采用一些策略。首先是通过使用多个负载均衡器来实现冗余负载平衡,通常以成对方式使用。如果其中一个失败,另一个会接管,这种方法称为故障转移。接下来的策略是持续监控和健康检查负载均衡器本身,这可以确保及早发现任何问题,并在造成重大中断之前予以解决。我们还可以实施自动扩展和自我修复系统。一些现代基础设施会自动检测负载均衡器的故障,并替换为新实例,无需人工干预。在某些配置中,网络状况故障转移可以将流量从不再接受连接的IP地址(如故障的负载均衡器)重新路由到预先配置的备用IP(也就是新的负载均衡器)。

数据库设计

系统设计面试如果没有深入了解数据库就是不完整的,在接下来,我会带你了解数据库的基本要点,帮助你准备面试。我们将探讨数据库在系统设计中的作用、分片和复制技术以及关键的ACD属性。不同类型的数据库、垂直和水平扩展选项以及数据库性能技巧。我们有不同类型的数据库,每种都设计用于特定的任务和挑战,让我们来探索一下。

  1. 第一种类型是关系型数据库, 将关系型数据库视为一个组织有序的文件柜,所有文件都整齐地分类到不同的抽屉和文件夹中。一些流行的SQL数据库示例是PostgreSQL、MySQL和SQLite,所有的SQL数据库都使用表来存储数据,并使用SQL作为查询语言。它们非常适用于事务、复杂查询和完整性,关系型数据库也符合ACD属性,A代表原子性,意味着交易是全有或全无的,C代表一致性,意味着在交易之后,数据库应该处于一致的状态,I代表隔离性,意味着交易应该是独立的,D代表持久性,意味着一旦交易提交,数据将会存留。

  2. 我们还有NoSQL数据库, 它取消了一致性属性,想象一个NoSQL数据库就像是一个粘贴便签的头脑风暴板,你可以以任何形状或形式添加或删除便签,它很灵活。 流行的例子包括mongodb、Cassandra和Redis,还有不同类型的NoSQL数据库,例如键值对数据库、文档型数据库或基于图的数据库,NoSQL数据库是无模式的,意味着它们在表之间没有外键,用来将数据链接在一起,它们非常适用于非结构化数据,理想的可扩展性、快速迭代和简单查询。

  3. 还有内存数据库, 这就像拥有一个白板用于快速计算和临时素描,因为所有的东西都在内存中,所以速度很快。一些例子包括Redis和Mcache,它们具有快速的数据检索,主要用于缓存和会话存储。现在让我们看看如何扩展数据库,第一个选项是垂直扩展或横向扩展,在垂直扩展中,通过增强运行数据的单个服务器的能力来提高数据库的性能,这可能涉及增加CPU 力量,增加更多的RAM,添加更快或更多的磁盘存储,或升级网络,但对单台机器能够添加的资源有一个最大限制,所以非常有限。

  4. 下一项是水平扩展或横向扩展, 这涉及向现有资源池中添加更多的机器,而不是升级单个单元数据库,支持水平扩展的数据库将数据分布到一组机器的集群中,这可能涉及数据库分片或数据复制,第一个选项是数据库分片,这是将数据集的不同部分分布到多台服务器上,这意味着你将数据分割成更小的块,并分配到多台服务器上。

一些分片策略包括基于范围的分片,根据给定键的范围分布数据,基于目录的分片,利用查找服务将流量指向正确的数据库,我们还有地理分片,根据地理位置拆分数据库,下一个横向扩展选项是数据复制,这是在多台服务器上保留数据副本以获得高可用性,你有主从复制,其中你有一个主数据库和若干只读从数据库,或者你可以有主主应用程序,多个可以同时读写的数据库。

  1. 扩展你的数据库是一回事,但你也希望更快地访问它,所以让我们谈谈不同的性能技巧 可以帮助你更快地访问数据,最显而易见的就是缓存,缓存不仅仅适用于Web服务器,数据库缓存可以通过内存数据库如Redis来实现,你可以用它来缓存频繁的查询并提高性能 下一个技巧是索引,索引是提高数据库性能的另一种方式,为频繁访问的列创建索引将显著加快检索时间, 下一个技巧是查询优化,你也可以考虑优化查询以实现快速数据访问,包括最小化连接和使用SQL查询分析器或解释器来了解你的查询的性能, 在所有情况下,你都应记住CAP定理,它规定在设计系统时只能选择这三个中的两个:一致性、可用性和分区容忍性, 你应根据面试给出的要求,优先选择其中两个。

结束!

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee