架构篇09:架构设计原则案例

news2024/11/15 23:51:56

文章目录

    • 淘宝案例
    • 手机QQ案例
    • 小结

我们先复习一下架构设计的三条核心原则:合适原则简单原则演化原则
我们在架构设计实践中,应该时刻谨记这三条设计原则,指导我们设计出合适的架构,即使是代表中国互联网技术最顶尖水平的 BAT,其架构的发展历程也同样遵循这三条原则。

今天就以大家耳熟能详的淘宝和手机QQ 作为案例,来简单探讨一下。

淘宝案例

注:以下部分内容摘自《淘宝技术发展》。

淘宝技术发展主要经历了:

个人网站→Oracle/ 支付宝 / 旺旺→Java 时代 1.0→Java 时代 2.0→Java 时代 3.0→分布式时代

我们看看每个阶段的主要驱动力是什么。

  1. 个人网站

2003 年 4 月 7 日马云提出成立淘宝,2003 年 5 月 10 日淘宝就上线了,中间只有 1 个月,怎么办?淘宝的答案就是:买一个。

估计大部分人很难想象如今技术牛气冲天的阿里最初的淘宝竟然是买来的,我们看看当初决策的依据:

当时对整个项目组来说压力最大的就是时间,怎么在最短的时间内把一个从来就没有的网站从零开始建立起来?了解淘宝历史的人知道淘宝是在 2003 年 5 月 10 日上线的,这之间只有一个月。要是你在这个团队里,你怎么做?我们的答案就是:买一个来。

淘宝当时在初创时,没有过多考虑技术是否优越、性能是否海量以及稳定性如何,主要的考虑因素就是:

因为此时业务要求快速上线,时间不等人,等你花几个月甚至十几个月搞出一个强大的系统出来,可能市场机会就没有了,黄花菜都凉了。

同样,在考虑如何买的时候,淘宝的决策依据主要也是“快”。

买一个网站显然比做一个网站要省事一些,但是他们的梦想可不是做一个小网站而已,要做大,就不是随便买个就行的,要有比较低的维护成本,要能够方便地扩展和二次开发。

那接下来就是第二个问题:买一个什么样的网站?答案是:轻量一点的,简单一点的。

买一个系统是为了“快速可用”,而买一个轻量级的系统是为了“快速开发”。因为系统上线后肯定有大量的需求需要做,这时能够快速开发就非常重要。

从这个实例我们可以看到:淘宝最开始的时候业务要求就是“快”,因此反过来要求技术同样要“快”,业务决定技术,这里架构设计和选择主要遵循的是“合适原则”和“简单原则”。

第一代的技术架构如图所示。

img

  1. Oracle/ 支付宝 / 旺旺

淘宝网推出后,由于正好碰到“非典”,网购很火爆,加上采取了成功的市场运作,流量和交易量迅速上涨,业务发展很快,在 2003 年底,MySQL 已经撑不住了。

一般人或者团队在这个时候,可能就开始优化系统、优化架构、分拆业务了,因为这些是大家耳熟能详也很拿手的动作。那我们来看看淘宝这个时候怎么采取的措施:

技术的替代方案非常简单,就是换成 Oracle。换 Oracle 的原因除了它容量大、稳定、安全、性能高,还有人才方面的原因。

可以看出这个时候淘宝的策略主要还是“买”,买更高配置的 Oracle,这个是当时情况下最快的方法。

除了购买 Oracle,后来为了优化,又买了更强大的存储:

后来数据量变大了,本地存储不行了。买了 NAS(Network Attached Storage,网络附属存储),NetApp 的 NAS 存储作为了数据库的存储设备,加上 Oracle RAC(Real Application Clusters,实时应用集群)来实现负载均衡。

为什么淘宝在这个时候继续采取“买”的方式来快速解决问题呢?我们可以从时间上看出端倪:此时离刚上线才半年不到,业务飞速发展,最快的方式支撑业务的发展还是去买。如果说第一阶段买的是“方案”,这个阶段买的就是“性能”,这里架构设计和选择主要遵循的还是“合适原则”和“简单原则”。

换上 Oracle 和昂贵的存储后,第二代架构如图所示。

img

  1. 脱胎换骨的 Java 时代 1.0

淘宝切换到 Java 的原因很有趣,主要因为找了一个 PHP 的开源连接池 SQL Relay 连接到 Oracle,而这个代理经常死锁,死锁了就必须重启,而数据库又必须用 Oracle,于是决定换个开发语言。最后淘宝挑选了 Java,而且当时挑选 Java,也是请 Sun 公司的人,这帮人很历害,先是将淘宝网站从 PHP 热切换到了 Java,后来又做了支付宝。

这次切换的最主要原因是因为技术影响了业务的发展,频繁的死锁和重启对用户业务产生了严重的影响,从业务的角度来看这是不得不解决的技术问题。

但这次淘宝为什么没有去“买”呢?我们看最初选择 SQL Relay 的原因:

但对于 PHP 语言来说,它是放在 Apache 上的,每一个请求都会对数据库产生一个连接,它没有连接池这种功能(Java 语言有 Servlet 容器,可以存放连接池)。那如何是好呢?这帮人打探到 eBay 在 PHP 下面用了一个连接池的工具,是 BEA 卖给他们的。我们知道 BEA 的东西都很贵,我们买不起,于是多隆在网上寻寻觅觅,找到一个开源的连接池代理服务 SQL Relay。

不清楚当时到底有多贵,Oracle 都可以买,连接池买不起 ?所以我个人感觉这次切换语言,更多是为以后业务发展做铺垫,毕竟当时 PHP 语言远远没有 Java 那么火、那么好招人。淘宝选择 Java 语言的理由可以从侧面验证这点:

Java 是当时最成熟的网站开发语言,它有比较良好的企业开发框架,被世界上主流的大规模网站普遍采用,另外有 Java 开发经验的人才也比较多,后续维护成本会比较低。

综合来看,这次架构的变化没有再简单通过“买”来解决,而是通过重构来解决,架构设计和选择遵循了“演化原则”。

从 PHP 改为 Java 后,第三代技术架构如图所示。

img

  1. 坚若磐石的 Java 时代 2.0

Java 时代 2.0,淘宝做了很多优化工作:数据分库、放弃 EJB、引入 Spring、加入缓存、加入 CDN、采用开源的 JBoss。为什么在这个时候要做这些动作?原文作者很好地概括了做这些动作的原因:

这些杂七杂八的修改,我们对数据分库、放弃 EJB、引入 Spring、加入缓存、加入 CDN、采用开源的 JBoss,看起来没有章法可循,其实都是围绕着提高容量、提高性能、节约成本来做的。

我们思考一下,为什么在前面的阶段,淘宝考虑的都是“快”,而现在开始考虑“容量、性能、成本”了呢?而且为什么这个时候不采取“买”的方式来解决容量、性能、成本问题呢?

简单来说,就是“买”也搞不定了,此时的业务发展情况是这样的:

随着数据量的继续增长,到了 2005 年,商品数有 1663 万,PV 有 8931 万,注册会员有 1390 万,这给数据和存储带来的压力依然很大,数据量大,性能就慢。

原有的方案存在固有缺陷,随着业务的发展,已经不是靠“买”就能够解决问题了,此时必须从整个架构上去进行调整和优化。比如说 Oracle 再强大,在做 like 类搜索的时候,也不可能做到纯粹的搜索系统如 Solr、Sphinx 等的性能,因为这是机制决定的。

另外,随着规模的增大,纯粹靠买的一个典型问题开始成为重要的考虑因素,那就是成本。当买一台两台 Oracle 的时候,可能对成本并不怎么关心,但如果要买 100 台 Oracle,成本就是一个关键因素了。这就是“量变带来质变”的一个典型案例,业务和系统发生质变后,架构设计遵循“演化原则”的思想,需要再一次重构甚至重写。

Java 架构经过各种优化,第四代技术架构如图所示。

img

  1. Java 时代 3.0 和分布式时代

Java 时代 3.0 我个人认为是淘宝技术飞跃的开始,简单来说就是淘宝技术从商用转为“自研”,典型的就是去 IOE 化。 分布式时代我认为是淘宝技术的修炼成功,到了这个阶段,自研技术已经自成一派,除了支撑本身的海量业务,也开始影响整个互联网的技术发展。

到了这个阶段,业务规模急剧上升后,原来并不是主要复杂度的 IOE 成本开始成为了主要的问题,因此通过自研系统来降低 IOE 的成本,去 IOE 也是系统架构的再一次演化。

手机QQ案例

注:以下部分内容摘自《QQ 1.4 亿在线背后的故事》。

手机 QQ 的发展历程按照用户规模可以粗略划分为 4 个阶段:十万级、百万级、千万级、亿级,不同的用户规模,IM 后台的架构也不同,而且基本上都是用户规模先上去,然后产生各种问题,倒逼技术架构升级。

  1. 十万级 IM 1.X

最开始的手机 QQ 后台是这样的,可以说是简单得不能再简单、普通得不能再普通的一个架构了,因为当时业务刚开始,架构设计遵循的是“合适原则”和“简单原则”。

img

  1. 百万级 IM 2.X

随着业务发展到 2001 年,QQ 同时在线人数也突破了一百万。第一代架构很简单,明显不可能支撑百万级的用户规模,主要的问题有:

  • 以接入服务器的内存为例,单个在线用户的存储量约为 2KB,索引和在线状态为 50 字节,好友表 400 个好友 × 5 字节 / 好友 = 2000 字节,大致来说,2GB 内存只能支持一百万在线用户。
  • CPU/ 网卡包量和流量 / 交换机流量等瓶颈。
  • 单台服务器支撑不下所有在线用户 / 注册用户。

于是针对这些问题做架构改造,按照“演化原则”的指导进行了重构,重构的方案相比现在来说也还是简单得多,因此当时做架构设计时也遵循了“合适原则”和“简单原则”。IM 2.X 的最终架构如图所示。

img

  1. 千万级 IM 3.X

业务发展到 2005 年,QQ 同时在线人数突破了一千万。第二代架构支撑百万级用户是没问题的,但支撑千万级用户又会产生新问题,表现有:

  • 同步流量太大,状态同步服务器遇到单机瓶颈。
  • 所有在线用户的在线状态信息量太大,单台接入服务器存不下,如果在线数进一步增加,甚至单台状态同步服务器也存不下。
  • 单台状态同步服务器支撑不下所有在线用户。
  • 单台接入服务器支撑不下所有在线用户的在线状态信息。

针对这些问题,架构需要继续改造升级,再一次“演化”。IM 3.X 的最终架构如下图,可以看到这次的方案相比之前的方案来说并不简单了,这是业务特性决定的。

img

  1. 亿级 IM 4.X

业务发展到 2010 年 3 月,QQ 同时在线人数过亿。第三代架构此时也不适应了,主要问题有:

  • 灵活性很差,比如“昵称”长度增加一半,需要两个月;增加“故乡”字段,需要两个月;最大好友数从 500 变成 1000,需要三个月。
  • 无法支撑某些关键功能,比如好友数上万、隐私权限控制、PC QQ 与手机 QQ 不可互踢、微信与 QQ 互通、异地容灾。

除了不适应,还有一个更严重的问题:

IM 后台从 1.0 到 3.5 都是在原来基础上做改造升级的,但是持续打补丁已经难以支撑亿级在线,IM 后台 4.0 必须从头开始,重新设计实现!

这里再次遵循了“演化原则”,决定重新打造一个这么复杂的系统,不得不佩服当时决策人的勇气和魄力!

重新设计的 IM 4.0 架构如图所示,和之前的架构相比,架构本身都拆分为两个主要的架构:存储架构和通信架构。

  • 存储架构 img
  • 通信架构 img

小结

今天我们探讨了淘宝和手机QQ 两个典型互联网业务的架构发展历程,通过这两个案例我们可以看出,即使是现在非常复杂、非常强大的架构,也并不是一开始就进行了复杂设计,而是首先采取了简单的方式(简单原则),满足了当时的业务需要(合适原则),随着业务的发展逐步演化而来的(演化原则)。

罗马不是一天建成的,架构也不是一开始就设计成完美的样子,然后可以一劳永逸一直用下去。

诚如硅谷所推崇的”60分比100分更重要“的理念,也是告诉我们不要一味的追求完美,而是在过程中不断优化。


【星猿杂谈】:在这里我们共同探索科技新趋势,分享积累的点滴,从编程语言到系统架构,从人工智能到高性能计算,我们追求技术的进步,同时珍视分享的力量。欢迎关注我们,在技术的精彩世界中一起遨游,发现更多未知!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1404161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习(5)---自注意力机制

文章目录 1. 输入与输出2. Self-attention2.1 介绍2.2 运作过程2.3 矩阵相乘理解运作过程 3. 位置编码4. Truncated Self-attention4.1 概述4.2 和CNN对比4.3 和RNN对比 1. 输入与输出 1. 一般情况下在简单模型中我们输入一个向量,输出结果可能是一个数值或者一个类…

利用STM32CubeMX和keil模拟器,3天入门FreeRTOS(2.0) —— 如何删除任务

前言 (1)FreeRTOS是我一天过完的,由此回忆并且记录一下。个人认为,如果只是入门,利用STM32CubeMX是一个非常好的选择。学习完本系列课程之后,再去学习网上的一些其他课程也许会简单很多。 (2&am…

基于Java开发的校园跳蚤市场管理系统详细设计和实现【附源码】

基于Java开发的校园跳蚤市场管理系统详细设计和实现【附源码】 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种…

React进阶 - 12(浅谈 state、props与render函数的关系)

本章内容 目录 一、state 与 render 函数的关系二、props 与 render函数的关系 上一节我们讲了如何使用 PropTypes及 DefaultProps来进行属性的类型校验及设置属性默认值。本节内容我们来了解一下 state、props与render函数的关系。 一、state 与 render 函数的关系 我们知道…

助力焊接场景下自动化缺陷检测识别,基于YOLOv8【n/s/m/l/x】全系列参数模型开发构建工件表面焊接裂纹缺陷检测识别分析系统

焊接是一个不陌生但是对于开发来说相对小众的场景,在工件表面焊接场景下常常有对工件表面缺陷智能自动化检测识别的需求,工业AI结合落地是一个比较有潜力的场景,在我们前面的博文开发实践中也有一些相关的实践,感兴趣的话可以自行…

防御第二次作业-防火墙组网实验(2)

目录 实验拓扑图 实验要求 一般组网步骤 to isp区域ping通 dmz区域 trust区域 实验拓扑图 实验要求 1.防火墙向下使用子接口分别对应两个内部区域 2.所有分区设备可以ping通网关 一般组网步骤 1.先配ip、接口、区域、安全策略 2.内网配置回包路由 3.配置dmz区域的服务器映…

vue2(Vuex)、vue3(Pinia)、react(Redux)状态管理

vue2状态管理Vuex Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它使用集中式存储管理应用的所有组件的状态,以及规则保证状态只能按照规定的方式进行修改。 State(状态):Vuex 使用单一状态树,即一个对象包含全部的应用层…

分布式日志

1 日志管理 1.1 日志管理方案 服务器数量较少时 直接登录到目标服务器捞日志查看 → 通过 rsyslog 或shell/python 等脚本实现日志搜集并集中保存到统一的日志服务器 服务器数量较多时 ELK 大型的日志系统,实现日志收集、日志存储、日志检索和分析 容器环境 …

基于SpringBoot Vue汽车租赁系统

大家好✌!我是Dwzun。很高兴你能来阅读我,我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结,还为大家分享优质的实战项目,本人在Java项目开发领域有多年的经验,陆续会更新更多优质的Java实战项目&#x…

【代码随想录】刷题笔记Day54

前言 差单调栈就结束代码随想录一刷啦,回家二刷打算改用python补充进博客,小涛加油!!! 647. 回文子串 - 力扣(LeetCode) 双指针法 中心点外扩,注意中心点可能有一个元素可能有两个…

Android14源码剖析:MediaPlayer与MediaPlayerService区别?(五十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

C#,入门教程(35)——哈希表(Hashtable)的基础知识与用法

上一篇: C#,入门教程(34)——关于函数的参数之引用(ref)的一点知识与源程序https://blog.csdn.net/beijinghorn/article/details/125411351 有一段故事: King Log The frogs in the lake had an easy life doing ex…

神经网络算法与逻辑回归:优势与差异

神经网络算法和逻辑回归都是预测模型中的重要工具,但它们在处理复杂和非线性问题时表现出不同的性能。本文将深入探讨神经网络算法相对于逻辑回归的优势,以及它们在不同场景下的适用性。 一、引言 神经网络算法和逻辑回归都是预测模型中的重要工具&…

C# CefSharp 根据输入日期段自动选择日期

前言 搞这个Demo整整搞几天通宵,爆肝了。后做的效果出来,还是不错的。给小伙伴看看效果图。 2, 遇到的问题 日期之间相差多少个月数。开始时间框点击对应月份要点击多少次,结束时间框点击对应月份要点击多少次Xpath获取问题。找到对应html元…

力扣刷题第七天 分割数组的最大值

给定一个非负整数数组 nums 和一个整数 k &#xff0c;你需要将这个数组分成 k 个非空的连续子数组。 设计一个算法使得这 k 个子数组各自和的最大值最小。 注&#xff1a; 1 < nums.length < 10000 < nums[i] < 1061 < k < min(50, nums.length) 示例一 输入…

cdh6.3.2的hive配udf

背景 大数据平台的租户要使用udf&#xff0c;他们用beeline连接&#xff0c; 意味着要通过hs2&#xff0c;但如果有多个hs2&#xff0c;各个hs2之间不能共享&#xff0c;需要先把文件传到hdfs&#xff0c;然后手动在各hs2上create function。之后就可以永久使用了&#xff0c;…

宠物互联网医院系统

在数字时代&#xff0c;宠物医疗迎来了一场革新&#xff0c;动物互联网医院系统以其先进的技术和智能的特性成为宠物护理的领军者。本文将介绍宠物互联网医院系统的一些关键技术和代码示例&#xff0c;揭示这一科技奇迹的实现原理。 1. 远程医疗服务的实现 远程医疗服务是宠…

<蓝桥杯软件赛>零基础备赛20周--第15周--快速幂+素数

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

Spring-配置文件

一、引子 了解完Spring的基本概念后&#xff0c;我们紧接着来了解Spring中的核心文件--Spring配置文件。 二、配置Bean 我们在上一节Spring的基本概念中快速使用了一下Spring&#xff0c;其中我们在配置文件中主要涉及到就是Bean标签的配置&#xff1a;主要的配置字段有id, …

[设计模式Java实现附plantuml源码~创建型] 对象的克隆~原型模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…