当前位置: 首页 > news >正文

试着探索高并发下的系统架构面貌

前言

以前端入行编码,但是对后端架构也非常感兴趣。一直以来都觉得那些做到在洪水流量面前保持系统提供高可靠,高性能的服务的小哥哥们都很厉害。总想着去学习一番,因此大半年来不断学习后端相关的知识,试图去理解高并发架构的面貌。

当然,本文仅仅是试着探索而已,并没有相关实践的经历,也只能从理论的角度去推演,从现有可参考的资料中去堆砌一个在我看来合理的架构方案。限于作者水平有限,因此难免行文难免有误,亦或是对整个系统的理解上理想化了,欢迎各位指出不足。同时,本文不会详实的阐述提到的每个细节,因为本身自己对细节的把控也不到位,另外也是希望大家能够在本文的基础上自己去详细了解这些技术。

图片描述

核心技术点

在作者看来,本文偏向于考虑如何做到高并发和高可用,因此一些性能优化的点则可能不作为重点言及,一是因为性能优化点过于繁多,会造成篇幅过长,另外也是因为具体的细节作者也未经实践不敢在这里细究。因此,列出以下这些在作者看来最为重要的核心技术点。

  1. 智能DNS解析调度

  2. 负载均衡

  3. 消息服务

  4. CDN配合对象存储服务

  5. Redis缓存

  6. 分库分表

通过横向叠加机器解决并发突增问题,这是的架构设计的一项最基本要求。

技术详解

智能DNS解析调度

在所有用户的都是通过同一域名www.qq.com获取服务的情况下,想要将流量分散到多个负载均衡节点,必须要依赖DNS的解析。

DNS解析最简单的可以通过添加多条A记录将域名映射到多个IP地址来达到分流的目的。看到许多资料,往往只提到这个层面,然后抛出了问题:调度算法简单,往往是动态轮询,而部署的机器之间可能会存在性能差异或者当下健康状况不同,简单的轮询并不能满足实际需求。
因此,经过一番搜索,发现了dnspod这样的第三方DNS解析服务提供设置权重,这样一来就可以针对机器的状况不同进行不同的权重配比。通过配比权重,基本上,就可以完成DNS解析的负载均衡了。

但是作者一直好奇,这些第三方的DNS解析厂商如何工作,因此在查阅资料之后,将原理总结如下:
在DNS解析中,我们购买域名后,可以设置对应域名的权威DNS解析服务器。以访问www.qq.com.为例,DNS解析首先会递归查找对应域名的IP地址。一直查找到根域.,根域让我们去问com.的权威服务器, 之后去问qq.com.的权威服务器,再问www.qq.com.的权威服务器,这时候我们终于找到了www.qq.com.的权威服务器ns-edu1.qq.com.ns-edu2.qq.com.,权威服务器经过一系列算法最后给了我们请求域名的IP地址。

DNS解析图

购买域名后,域名往往被默认的设置为平台默认的DNS解析服务器上,我们也可以对其进行更改,比如设置到dnspod,并自己在dnspod进行配置。对于一些大厂,也可以通过自行架设DNS解析服务器并编写自定义的规则进行处理来达到高度定制化的管控。常见的管控如下:

  • 通过识别用户是电信网还是联通网,将对应的网络内部署的服务器地址返回,以避免用户请求的跨网,跨网会带来一定的网络传输性能的下降

  • 识别用户归属地,分配到最近的服务器以减少网络传输的距离

最后需要注意的是DNS解析的更改的实时性存在很大的限制,因为各地ISP服务商刷新域名DNS的时间不一致,所以导致解析在全球生效一般需要0-72小时。

负载均衡

这里的负载均衡只特指负载均衡的节点。DNS解析后的IP地址即对应负载均衡的IP地址,请求到达负载均衡节点后,将由负载均衡节点对请求进行转发到相应的http应用处理服务器。负载均衡节点可以设置相应转发的策略,例如最简单通过将用户的ip来hash到不同的http应用服务器来分散压力,这样的好处是可以保证每次请求都打到同一台机器上。另外负载均衡节点也会监听应用服务器,并且及时隔离掉异常状态的服务器,在服务器恢复健康后,再次接入。

通过负载均衡节点接入多台应用服务器,当遇到促销等场景时,动态增加应用服务器即可满足需求。

此外,我们还需要确保负载均衡节点的高可用性。通过VRRP(Virtual Router Redundancy Protocol, 虚拟路由冗余协议)保证负载均衡节点的高可用性。原理如下:
负载均衡节点往往由2台机器通过VIP(virtual IP,负载均衡向客户端提供服务的 IP 地址)技术向用户提供服务,两台机器同时只有一台机器保持在active的状态,两台机器之间通过Keepalived技术互相监听对方的状态,如果active的机器宕机,则另一台机器自动切换到active的状态,通过冗余来保证负载均衡节点的高可用性。

消息服务

项目简单的时候,我们往往会把所有的代码耦合在一起,同步执行。诸如购买一件商品,执行下单,减库存,支付等等操作同步运行完成之后再将请求返回,造成单个请求驻留时间过长,堆积大量的请求,造成应用服务器的不可用。

通过消息服务,我们可以将这些服务解耦,并且通过将同步逻辑异步化,减少请求的驻留,从而减轻并发压力。用户操作产生消息,再通过建立另外的消费者进行消费。

我们还可以根据情况,设置消费者的策略,比如,通过拉取消息而非推送消息,来保证无论前端并发多大的流量,都可以在消息服务这里熨平,消费者根据自己的能力拉取,不至于超负荷造成服务不可用。

CDN配合对象存储服务

CDN这个技术基本上写代码的人都知道,说优化的时候大家都能提到,可是过往也一直没有真正的设置过CDN的使用,这次专门去腾讯云上查看了下配置,并了解了下策略。

首先,用户准备一个域名用来作为CDN的分发域名,这里比如说qian-img.tenpay.com。设置qian-img.tenpay.com的别名CNAME为CDN厂商给我们提供的域名比如说tenpay.com.CDN.dnsv1.com,之后还需要设置源站(ip/域名)即你静态文件实际存放的机器地址。这样对qian-img.tenpay.com的请求都会打到对应的CDN域名上,CDN域名也会解析到最近的CDN节点上,并且递归查找资源,类似于DNS解析。当没有找到资源的时候,才会去用户设置的源站IP上去获取资源。这样对自己的静态资源源站的性能要求会大大减少,系统性能也会大大提高。

而源站的资源管理上也推荐使用对象存储服务,相比与使用自己搭建服务器的文件系统。对象存储服务,也可以存储任意形式的非结构化的数据,并且高可用、高稳定、强安全。

Redis缓存

Redis是基于内存的键值对数据库,IO性能远远高于基于文件系统的数据库。对一个接口的请求的多个请求过程中,往往数据并没有产生变化,如果每次都去数据库中去查询,则会造成数据库压力过大,同时接口性能下降,通过将数据缓存在Redis这样的内存键值对数据库中可以大大提高系统的性能。

分库分表

常用的数据库诸如MySQL都是基于文件系统,而文件系统是基于磁盘,整个系统中,磁盘的IO可以说是最慢的一个地方。因此数据库往往是系统的性能瓶颈,分库分表,是最常用的策略。

单个数据库存在并发连接数上线单位是百,因此面对海量的请求,是无能为力的。因此需要通过分库来将压力分担到不同的数据库机器上,以承载高并发的请求。分库的策略可以简单的根据用户UID的尾号进行水平拆分,同时分库后,单个数据库的记录数也减少了,读写性能也得到提高。

写在最后

大半年前,在公司听后端童鞋讲解后端架构的时候,很多东西都是一脸懵逼,大半年里不断认知学习,认识上终于有不少进步。学无止境,需要去学习的还有很多~
行将毕业,7月入职,希望在未来工作中能够在Web这一块有更加深入的认识。

相关文章:

  • 深入理解Java内存模型(四)——volatile
  • 亲历服务器ARP攻击处理办法
  • docker 安装 Error response from daemon: Cannot start container no such file or directory
  • Ruby on rails开发从头来系列教程(附ruby电子书下载)
  • 测试计划模板
  • [转] Session简介
  • rocketmq 学习记录-2
  • 浅谈 Java 主流开源类库解析 XML
  • ASP.NET MVC - 旧形式URL的路由
  • v4l2 spec 中文 Ch01【转】
  • 在WinForm中使用Web Services 来实现 软件 自动升级(C#)
  • CISCO路由器license激活图解教程
  • [LeetCode] Wiggle Sort
  • ASP得到当前页面完整地址
  • Photoshop脚本 关闭所有已打开的文档
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 2017-09-12 前端日报
  • k8s如何管理Pod
  • npx命令介绍
  • PaddlePaddle-GitHub的正确打开姿势
  • react-native 安卓真机环境搭建
  • webpack入门学习手记(二)
  • 关于Flux,Vuex,Redux的思考
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 使用Gradle第一次构建Java程序
  • 我从编程教室毕业
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 扩展资源服务器解决oauth2 性能瓶颈
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #、%和$符号在OGNL表达式中经常出现
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (BFS)hdoj2377-Bus Pass
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (zt)最盛行的警世狂言(爆笑)
  • (八十八)VFL语言初步 - 实现布局
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (一)基于IDEA的JAVA基础12
  • (原)本想说脏话,奈何已放下
  • (转)visual stdio 书签功能介绍
  • (转)关于pipe()的详细解析
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET Core 成都线下面基会拉开序幕
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET MVC第三章、三种传值方式
  • .NET 设计一套高性能的弱事件机制
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET导入Excel数据
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • @Autowired注解的实现原理
  • @selector(..)警告提示
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [Angularjs]asp.net mvc+angularjs+web api单页应用
  • [ArcPy百科]第三节: Geometry信息中的空间参考解析
  • [Asp.net MVC]Bundle合并,压缩js、css文件