做者:Java关博
连接:http://blog.51cto.com/14049376/2329037?utm_source=tuicool&utm_medium=referral复制代码
架构以及我理解中架构的本质前端
在开始谈我对架构本质的理解以前,先谈谈对今天技术沙龙主题的我的看法,千万级规模的网站感受数量级是很是大的,对这个数量级咱们 战略上 要重 视 它 , 战术上又 要 藐 视 它 。先举个例子感觉一下千万级究竟是什么数量级?如今很流行的优步(Uber),从媒体公布的信息看,它天天接单量平均在百万左右, 假如天天有10个小时的服务时间,平均QPS只有30左右。对于一个后台服务器,单机的平均QPS能够到达800-1000,单独看写的业务量很简单 。为何咱们又不能说轻视它?第一,咱们看它的数据存储,天天一百万的话,一年数据量的规模是多少?其次,刚才说的订单量,每个订单要推送给附近的司机、司机要并
发抢单,后面业务场景的访问量每每是前者的上百倍,轻松就超过上亿级别了。面试
今天我想从架构的本质谈起以后,但愿你们理解在作一些建构设计的时候,它的出发点以及它解决的问题是什么。算法
架构,刚开始的解释是我从知乎上看到的。什么是架构?有人讲, 说架构并非一 个很 悬 乎的 东西 , 实际 上就是一个架子 , 放一些 业务 和算法 ,跟咱们的生活中的晾衣架很像。更抽象一点, 说架构其 实 是 对 我 们 重复性业务 的抽象和我 们 将来 业务 拓展的前瞻 ,强调过去的经验和你对整个行业的预见。数据库
咱们要想作一个架构的话须要哪些能力?我以为最重要的是架构师一个最重要的能力就是你要有 战 略分解能力。这个怎么来看呢:后端
第一, 你必需要有抽象的能力 ,抽象的能力最基本就是去重,去重在整个架构中体如今方方面面,从定义一个函数,到定义一个类,到提供的一个服务,以及模板,背后都是要去重提升可复用率。浏览器
第二, 分类能力 。作软件须要作对象的解耦,要定义对象的属性和方法,作分布式系统的时候要作服务的拆分和模块化,要定义服务的接口和规范。缓存
第三, 算法(性能) ,它的价值体如今提高系统的性能,全部性能的提高,最终都会落到CPU,内存,IO和网络这4大块上。安全
这一页PPT举了一些例子来更深刻的理解常见技术背后的架构理念。bash
第一个例子,在分布式系统咱们会作 MySQL分 库 分表,咱们要从不一样的库和表中读取数据,这样的抽象最直观就是使用模板,由于绝大多数SQL语义是相同的,除了路由到哪一个库哪一个表,若是不使用Proxy中间件,模板就是性价比最高的方法。服务器
第二看一下加速网络的CDN,它是作速度方面的性能提高,刚才咱们也提到从CPU、内存、IO、网络四个方面来考虑,CDN本质上一个是作网络智能调度优化,另外一个是多级缓存优化。
第三个看一下服务化,刚才已经提到了,各个大网站转型过程当中必定会作服务化,其实它就是作抽象和作服务的拆分。第四个看一下消息队列,本质上仍是作分类,只不过不是两个边际清晰的类,而是把两个边际不清晰的子系统经过队列解构而且异步化。
新浪微博总体架构是什么样的
接下咱们看一下微博总体架构,到必定量级的系统整个架构都会变成三层,客户端包括WEB、安卓和IOS,这里就不说了。
接着还都会有一个接口层, 有三个主要做用:
第一个做用,要作 安全隔离,由于前端节点都是直接和用户交互,须要防范各类恶意***;
第二个还充当着一个 流量控制的做用,你们知道,在2014年春节的时候,微信红包,每分钟8亿屡次的请求,其实真正到它后台的请求量,只有十万左右的数量级(这里的数据可能不许),剩余的流量在接口层就被挡住了;
第三,咱们看对 PC 端和移 动 端的需求不同的,因此咱们能够进行拆分。接口层以后是后台,能够看到微博后台有三大块:
一个是 平台服 务,
第二, 搜索,
第三, 大数据。
到了后台的各类服务其实都是处理的数据。 像平台的业务部门,作的就是 数据存储和读 取,对搜索来讲作的是 数据的 检 索,对大数据来讲是作的数据的 挖掘。微博其实和淘宝是很相似
微博其实和淘宝是很相似的。通常来讲,第一代架构,基本上能支撑到用户到 百万 级别,到第二代架构基本能支撑到 千万 级别都没什么问题,当业务规模到 亿级别时,须要第三代的架构。
从 LAMP 的架构到面向服 务 的架构,有几个地方是很是难的,首先不可能在第一代基础上经过简单的修修补补知足用户量快速增加的,同时线上业务又不能停, 这是咱们常说的 在 飞 机上 换 引擎的 问题。前两天我有一个朋友问我,说他在内部推行服务化的时候,把一个模块服务化作完了,其余部门就是不接。我建议在作服务化的时候,首先更可能是偏向业务的梳理,同时要找准一个很好的切入点,既有架构和服务化上的提高,业务方也要有收益,好比提高性能或者下降维护成本同时升级过程要平滑,建议开始从原子化服务切入,好比基础的用户服务, 基础的短消息服务,基础的推送服务。 第二,就是可 以作无状 态 服 务,后面会详细讲,还有数据量大了后须要作数据Sharding,后面会将。 第三代 架构 要解决的 问题,就是用户量和业务趋于稳步增长(相对爆发期的指数级增加),更多考虑技术框架的稳定性, 提高系统总体的性能,下降成本,还有对整个系统监控的完善和升级。
大型网站的系统架构是如何演变的
咱们经过经过数据看一下它的挑战,PV是在10亿级别,QPS在百万,数据量在千亿级别。咱们可用性,就是SLA要求4个9,接口响应最多不能超过150毫秒,线上全部的故障必须得在5分钟内解决完。若是说5分钟没处理呢?那会影响你年终的绩效考核。2015年微博DAU已通过亿。咱们系统有上百个微服务,每周会有两次的常规上线和不限次数的紧急上线。咱们的挑战都同样,就是数据量,bigger and bigger,用户体验是faster and faster,业务是more and more。互联网业务更可能是产品体验驱动, 技 术 在 产 品 体验上最有效的贡献 , 就是你的性能 愈来愈好 。 每次下降加载一个页面的时间,均可以间接的下降这个页面上用户的流失率。
微博的技术挑战和正交分解法解析架构
下面看一下 第三代的 架构 图 以及 我 们 怎么用正交分解法 阐 述。 咱们能够看到咱们从两个维度,横轴和纵轴能够看到。 一个 维 度 是 水平的 分层 拆分,第二从垂直的维度会作拆分。水平的维度从接口层、到服务层到数据存储层。垂直怎么拆分,会用业务架构、技术架构、监控平台、服务治理等等来处理。我相信到第二代的时候不少架构已
经有了业务架构和技术架构的拆分。咱们看一下, 接口层有feed、用户关系、通信接口;服务层,SOA里有基层服务、原子服务和组合服务,在微博咱们只有原子服务和组合服务。原子服务不依赖于任何其余服务,组合服务由几个原子服务和本身的业务逻辑构建而成 ,资源层负责海量数据的存储(后面例子会详细讲)。技 术框架解决 独立于 业务 的海量高并发场景下的技术难题,由众多的技术组件共同构建而成 。在接口层,微博使用JERSY框架,帮助你作参数的解析,参数的验证,序列化和反序列化;资源层,主要是缓存、DB相关的各种组件,好比Cache组件和对象库组件。监 控平台和服 务 治理 , 完成系统服务的像素级监控,对分布式系统作提早诊断、预警以及治理。包含了SLA规则的制定、服务监控、服务调用链监控、流量监控、错误异常监控、线上灰度发布上线系统、线上扩容缩容调度系统等。
下面咱们讲一下常见的设计原则。
第一个,首先是系统架构三个利器:
一个, 我 们 RPC 服 务组 件 (这里不讲了),
第二个,咱们 消息中 间 件 。消息中间件起的做用:能够把两个模块之间的交互异步化,其次能够把不均匀请求流量输出为匀速的输出流量,因此说消息中间件 异步化 解耦 和流量削峰的利器。
第三个是配置管理,它是 代码级灰度发布以及 保障系统降级的利器。
第二个 , 无状态 , 接口 层 最重要的就是无状 态。咱们在电商网站购物,在这个过程当中不少状况下是有状态的,好比我浏览了哪些商品,为何你们又常说接口层是无状态的,其实咱们把状态从接口层剥离到了数据层。像用户在电商网站购物,选了几件商品,到了哪一步,接口无状态后,状态要么放在缓存中,要么放在数据库中, 其 实 它并非没有状 态 , 只是在 这 个 过 程中我 们 要把一些有状 态 的 东 西抽离出来 到了数据层。
第三个, 数据 层 比服 务层 更须要 设计,这是一条很是重要的经验。对于服务层来讲,能够拿PHP写,明天你能够拿JAVA来写,可是若是你的数据结构开始设计不合理,未来数据结构的改变会花费你数倍的代价,老的数据格式向新的数据格式迁移会让你痛不欲生,既有工做量上的,又有数据迁移跨越的时间周期,有一些甚至须要半年以上。
第四,物理结构与逻辑结构的映射,上一张图看到两个维度切成十二个区间,每一个区间表明一个技术领域,这个能够看作咱们的逻辑结构。另外,不论后台仍是应用层的开发团队,通常都会分几个垂直的业务组加上一个基础技术架构组,这就是从物理组织架构到逻辑的技术架构的完美的映射,精细化团队分工,有利于提升沟通协做的效率 。
第五, www .sanhao.com 的访问过程,咱们这个架构图里没有涉及到的,举个例子,好比当你在浏览器输入www.sanhao网址的时候,这个请求在接口层以前发生了什么?首先会查看你本机DNS以及DNS服务,查找域名对应的IP地址,而后发送HTTP请求过去。这个请求首先会到前端的VIP地址(公网服务IP地址),VIP以后还要通过负载均衡器(Nginx服务器),以后才到你的应用接口层。在接口层以前发生了这么多事,可能有用户报一个问题的时候,你经过在接口层查日志根本发现不了问题,缘由就是问题可能发生在到达接口层以前了。
第六,咱们说分布式系统,它最终的瓶颈会落在哪里呢?前端时间有一个网友跟我讨论的时候,说他们的系统遇到了一个瓶颈, 查遍了CPU,内存,网络,存储,都没有问题。我说你再查一遍,由于最终你不论用上千台服务器仍是上万台服务器,最终系统出瓶颈的必定会落在某一台机(多是叶子节点也多是核心的节点),必定落在CPU、内存、存储和网络上,最后查出来问题出在一台服务器的网卡带宽上。
微博多级双机房缓存架构
接下来咱们看一下微博的Feed多级缓存。咱们作业务的时候,常常不多作业务分析,技术大会上的分享又都偏向技术架构。其实你们更多的平常工做是须要花费更多时间在业务优化上。这张图是统计微博的信息流前几页的访问比例,像前三页占了97%,在作缓存设计的时候,咱们最多只存最近的M条数据。 这里强调的就是作系统设计 要基于用 户 的 场 景 , 越细致越好 。举了一个例子,你们都会用电商,电商在双十一会作全国范围内的活动,他们作设计的时候也会考虑场景的,一个就是购物车,我曾经跟相关开发讨论过,购物车是在双十一以前用户的访问量很是大,就是不停地往里加商品。在真正到双十一那天他不会往购物车加东西了,可是他会频繁的浏览购物车。针对这个场景,活动以前重点设计优化购物车的写场景, 活动开始后优化购物车的读场景。
你看到的微博是由哪些部分聚合而成的呢?最右边的是Feed,就是微博全部关注的人,他们的微博所组成的。微博咱们会按照时间顺序把全部关注人的顺序作一个排序。随着业务的发展,除了跟时间序相关的微博还有非时间序的微博,就是会有广告的要求,增长一些广告,还有粉丝头条,就是拿钱买的,热门微博,都会插在其中。分发控制,就是说和一些推荐相关的,我推荐一些相关的好友的微博,我推荐一些你可能没有读过的微博,我推荐一些其余类型的微博。 固然对非时序的微博和分发控制微博,实际会起多个并行的程序来读取,最后同步作统一的聚合。这里稍微分享一下, 从SNS社交领域来看,国内如今作的比较好的三个信息流:
微博 是 基于弱关系的媒体信息流 ;
朋友圈是基于 强 关系的信息流 ;
另一个作的比 较 好的就是今日 头 条 , 它并非基于关系来构建信息流 , 而是基于 兴趣和相关性的个性化推荐 信息流 。
信息流的聚合,体如今不少不少的产品之中,除了SNS,电商里也有信息流的聚合的影子。好比搜索一个商品后出来的列表页,它的信息流基本由几部分组成:第一,打广告的;第二个,作一些推荐,热门的商品,其次,才是关键字相关的搜索结果。 信息流 开始的时候 很 简单 , 可是到后期会 发现 , 你的 这 个流 如何作控制分发 , 很是复杂, 微博在最近一两年一直在作 这样 的工做。
刚才咱们是从业务上分析,那么技术上怎么解决高并发,高性能的问题?微博访问量很大的时候,底层存储是用MySQL数据库,固然也会有其余的。对于查询请求量大的时候,你们知道必定有缓存,能够复用可重用的计算结果。能够看到,发一条微博,我有不少粉丝,他们都会来看我发的内容,因此 微博是最适合使用 缓 存 的系统,微博的读写比例基本在几十比一。微博使用了 双 层缓 存,上面是L1,每一个L1上都是一组(包含4-6台机器),左边的框至关于一个机房,右边又是一个机房。在这个系统中L1缓存所起的做用是什么? 首先,L1 缓 存增长整个系 统 的 QPS, 其次 以低成本灵活扩容的方式 增长 系统 的 带宽 。想象一个极端场景,只有一篇博文,可是它的访问量无限增加,其实咱们不须要影响L2缓存,由于它的内容存储的量小,但它就是访问量大。这种场景下,你就须要使用L1来扩容提高QPS和带宽瓶颈。另一个场景,就是L2级缓存发生做用,好比我有一千万个用户,去访问的是一百万个用户的微博 ,这个时候,他不仅是说你的吞吐量和访问带宽,就是你要缓存的博文的内容也不少了,这个时候你要考虑缓存的容量, 第二 级缓 存更多的是从容量上来 规划,保证请求以较小的比例 穿透到 后端的 数据 库 中 ,根据你的用户模型你能够估出来,到底有百分之多少的请求不能穿透到DB, 评估这个容量以后,才能更好的评估DB须要多少库,须要承担多大的访问的压力。另外,咱们看双机房的话,左边一个,右边一个。 两个机房是互 为 主 备 , 或者互 为热备 。若是两个用户在不
同地域,他们访问两个不一样机房的时候,假设用户从IDC1过来,由于就近原理,他会访问L1,没有的话才会跑到Master,当在IDC1没找到的时候才会跑到IDC2来找。同时有用户从IDC2访问,也会有请求从L1和Master返回或者到IDC1去查找。 IDC1 和 IDC2 ,两个机房都有全量的用户数据,同时在线提供服务,可是缓存查询又遵循最近访问原理。
还有哪些多级缓存的例子呢?CDN是典型的多级缓存。CDN在国内各个地区作了不少节点,好比在杭州市部署一个节点时,在机房里确定不止一台机器,那么对于一个地区来讲,只有几台服务器到源站回源,其余节点都到这几台服务器回源便可,这么看CDN至少也有两级。Local Cache+ 分布式 缓 存,这也是常见的一种策略。有一种场景,分布式缓存并不适用, 好比 单 点 资 源 的爆发性峰值流量,这个时候使用Local Cache + 分布式缓存,Local Cache 在 应用 服 务 器 上用很小的 内存资源 挡住少许的 极端峰值流量,长尾的流量仍然访问分布式缓存,这样的Hybrid缓存架构经过复用众多的应用服务器节点,下降了系统的总体成本。
咱们来看一下 Feed 的存 储 架构,微博的博文主要存在MySQL中。首先来看内容表,这个比较简单,每条内容一个索引,天天建一张表,其次看索引表,一共建了两级索引。首先想象一下用户场景,大部分用户刷微博的时候,看的是他关注全部人的微博,而后按时间来排序。仔细分析发如今这个场景下, 跟一个用户的本身的相关性很小了。因此在一级索引的时候会先根据关注的用户,取他们的前条微博ID,而后聚合排序。咱们在作哈希(分库分表)的时候,同时考虑了按照UID哈希和按照时间维度。很业务和时间相关性很高的,今天的热点新闻,明天就没热度了,数据的冷热很是明显,这种场景就须要按照时间维度作分表,首先冷热数据作了分离(能够对冷热数据采用不一样的存储方案来下降成本),其次, 很容止控制我数据库表的爆炸。像微博若是只按照用户维度区分,那么这个用户全部数据都在一张表里,这张表就是无限增加的,时间长了查询会愈来愈慢。二级索引,是咱们里面一个比较特殊的场景,就是我要快速找到这我的所要发布的某一时段的微博时,经过二级索引快速定位。
分布式服务追踪系统
分布式追踪服务系统,当系统到千万级之后的时候,愈来愈庞杂,所解决的问题更偏向稳定性,性能和监控。刚才说用户只要有一个请求过来,你能够依赖你的服务RPC一、RPC2,你会发现RPC2又依赖RPC三、RPC4。分布式服务的时候一个痛点,就是说一个请求从用户过来以后,在后台不一样的机器之间不停的调用并返回。
当你发现一个问题的时候,这些日志落在不一样的机器上,你也不知道问题到底出在哪儿,各个服务之间互相隔离,互相之间没有创建关联。因此致使排查问题基本没有任何手段,就是出了问题无法儿解决。
咱们要解决的问题,咱们刚才说日志互相隔离,咱们就要把它创建联系。创建联系咱们就有一个请求ID,而后结合RPC框架, 服务治理功能。假设请求从客户端过来,其中包含一个ID 101,到服务A时仍然带有ID 101,而后调用RPC1的时候也会标识这是101 ,因此须要 一个惟一的 请求 ID 标识 递归迭代的传递到每个 相关 节点。第二个,你作的时候,你不能说每一个地方都加,对业务系统来讲须要一个框架来完成这个工做, 这 个框架要 对业务 系 统 是最低侵入原 则 , 用 JAVA 的 话 就能够用 AOP,要作到零侵入的原则,就是对全部相关的中间件打点,从接口层组件(HTTP Client、HTTP Server)至到服务层组件(RPC Client、RPC Server),还有数据访问中间件的,这样业务系统只须要少许的配置信息就能够实现全链路监控 。为何要用日志?服务化之后,每一个服务能够用不一样的开发语言, 考虑多种开发语言的兼容性 , 内部定 义标 准化的日志 是惟一且有效的办法。
最后,如何构建基于GPS导航的路况监控?咱们刚才讲分布式服务追踪。分布式服务追踪能解决的问题, 若是 单一用 户发现问题 后 , 能够通 过请 求 ID 快速找到 发 生 问
题 的 节 点在什么,可是并无解决如何发现问题。咱们看现实中比较容易理解的道路监控,每辆车有GPS定位,我想看北京哪儿拥堵的时候,怎么作? 第一个 , 你确定要知
道每一个 车 在什么位置,它走到哪儿了。其实能够说每一个车上只要有一个标识,加上每一次流动的信息,就能够看到每一个车流的位置和方向。 其次如何作 监 控和 报 警,咱们怎么能了解道路的流量情况和负载,并及时报警。咱们要定义这条街道多宽多高,单位时间能够通行多少辆车,这就是道路的容量。有了道路容量,再有道路的实时流量,咱们就能够基于实习路况作预警?
对应于 分布式系 统 的话如何构建? 第一 , 你要 定义 每一个服 务节 点它的 SLA A 是多少 ?SLA能够从系统的CPU占用率、内存占用率、磁盘占用率、QPS请求数等来定义,至关于定义系统的容量。 第二个 , 统计 线 上 动态 的流量,你要知道服务的平均QPS、最低QPS和最大QPS,有了流量和容量,就能够对系统作全面的监控和报警。
刚才讲的是理论,实际状况确定比这个复杂。微博在春节的时候作许多活动,必须保障系统稳定,理论上你只要定义容量和流量就能够。但实际远远不行,为何?有技术的因素,有人为的因素,由于不一样的开发定义的流量和容量指标有主观性,很难全局量化标准,因此真正流量来了之后,你预先评估的系统瓶颈每每不正确。实际中咱们在春节前主要采起了三个措施:第一,最简单的就是有降 级 的 预 案,流量超过系统容量后,先把哪些功能砍掉,须要有明确的优先级 。第二个, 线上全链路压测,就是把如今的流量放大到咱们日常流量的五倍甚至十倍(好比下线一半的服务器,缩容而不是扩容),看看系统瓶颈最早发生在哪里。咱们以前有一些例子,推测系统数据库会先出现瓶颈,可是实测发现是前端的程序先遇到瓶颈。第三,搭建在线 Docker 集群 , 全部业务共享备用的 Docker集群资源,这样能够极大的避免每一个业务都预留资源,可是实际上流量没有增加形成的浪费。
总结
接下来讲的是如何不停的学习和提高,这里以Java语言为例,首先, 必定要 理解 JAVA;第二步,JAVA完了之后,必定要 理 解 JVM;其次,还要 理解 操做系统;再次仍是要了解一下 Design Pattern,这将告诉你怎么把过去的经验抽象沉淀供未来借鉴;还要学习 TCP/IP、 分布式系 统、数据结构和算法。加裙:834962734 免费获取一份Java架构进阶技术精品视频。(高并发+Spring源码+JVM原理解析+分布式架构+微服务架构+多线程并发原理+BATJ面试宝典)以及架构思惟导图。
最后就是我想说的就是今天我所说的可能一切都是错的!你们经过不停的学习、练习和总结, 造成本身的一套架构设计原则和方法,谢谢你们。