时隔16年Jeff Barr重返10.23-25 QCon上海站,带你看透AI如何重塑软件开发! 了解详情
写点什么

电商网站的宕机案例分析

  • 2012-11-08
  • 本文字数:2035 字

    阅读完需:约 7 分钟

性能调优社区 dynatrace 在其博客中分享了客户案例,电商网站在假日客流峰值期间数次崩溃,经过 SQL 优化和调整负载均衡算法解决了相关问题,值得读者借鉴。

按照博文的描述,该电子商务网站在圣诞节期间崩溃了七次,每次宕机的时间都超过 5 个小时。这种情况让企业损失了大量的收入和名誉。

我们的一个客户就曾经遭遇到这种情况,我们在此分享下他们的经历。宕机的原因有很多,不过我们这里只强调比较突出的一点,即负载均衡器在采用 Round-Robin(轮询)算法时比 Least-Busy (最休闲)算法更容易导致应用服务器因堆内存耗尽而崩溃。

在分析性能问题之前,先看一看该网站的拓扑结构。该电子商务网站部署在 6 个 Tomcat 应用服务器上,前面是 3 个 Apache Web 服务器。

面临的问题是,在负载高峰时刻,每个 Tomcat 实例处理的响应时间开始增长,等待队列中的请求数目增多。一段时间之后,这些 Tomcat 实例由于 OutOfMemory 异常而崩溃,随后其他实例也因为承受不住由此增加的负载而宕机。

即使在采用平均分布负载的算法(Round Robin)下,有些 Tomcat 应用服务器也会出现响应时间的跳跃。一旦服务器开始拒绝客户连接,我们会发现一些连锁反应。数据库层出现大量的异常,同时应用层之间会抛出异常,Web 服务器会返回给浏览器 HTTP 500 的错误。

比如,在实际的分析过程中,我们发现某一个 Tomcat 实例在 30 分钟内对 43000 个页面返回了 HTTP 500 错误。

原因分析:来自数据库层(JDBC)的异常是分析该问题的关键入口。仔细查看这些异常会发现连接池已经耗尽了,从而导致应用的各个部分出现问题。由于连接池的原因,每一个请求都需要平均等待 3.8 秒来从池里获取连接。

不光是连接池大小的设置问题,而且不少低效的数据库语句在执行应用的一些业务逻辑事务时花费了太长时间。这导致应用服务器维护这个连接的时间也较长。如果把负载均衡器设为 Round Robin 算法,应用服务器会继续获得其他的请求。最终,由于客户请求的随机性,某个应用服务器收到了不少执行低效数据库处理的请求。一旦连接池耗尽,应用服务器就开始抛出异常,并最终导致 JVM 崩溃。一旦第一个应用服务器出现问题,用不了多久其他服务器也挂掉了。

解决办法:优化应用程序和负载均衡器

首先要分析执行最慢的数据库语句,并做性能优化,比如增加索引等。同时也优化了连接池大小来满足高峰时刻的需求。然后,企业把负载均衡器的算法从 Round-Robin 改为了 Least-Busy,在生产环境中这个配置经常被人遗忘。自从对应用程序和负载均衡器做了修改之后,网站再也没有崩溃。

该企业之前做过负载测试,但是存在两个问题:

  1. 没有使用预期的峰值负载长时间测试。
  2. 没有完全模拟用户行为,测试脚本太少、太简单,缺少了用户的高交互性访问场景。

由此等到的经验教训:在生产环境的低访问量时段(凌晨 2 点到 6 点)执行负载测试,这样可以虽然有小的交易风险,但是可以避免大的经济损失。高峰时间长为 10 小时,不要测试太短时间。

关于负载均衡的基本算法,主要有以下几种(参考 F5 产品):

  • 随机:负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器,然后把连接发送给它。虽然许多均衡产品都支持该算法,但是它的有效性一直受到质疑,除非把服务器的可运行时间看的很重。
  • 轮询:轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。轮询算法在大多数情况下都工作的不错,但是如果负载均衡的设备在处理速度、连接速度和内存等方面不是完全均等,那么效果会更好。
  • 加权轮询:该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,比如你可以设定:第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第 3 台机器。
  • 动态轮询:类似于加权轮询,但是,权重值基于对各个服务器的持续监控,并且不断更新。这是一个动态负载均衡算法,基于服务器的实时性能分析分配连接,比如每个节点的当前连接数或者节点的最快响应时间等。
  • 最快算法:最快算法基于所有服务器中的最快响应时间分配连接。该算法在服务器跨不同网络的环境中特别有用。
  • 最少连接:系统把新连接分配给当前连接数目最少的服务器。该算法在各个服务器运算能力基本相似的环境中非常有效。
  • 观察算法:该算法同时利用最小连接算法和最快算法来实施负载均衡。服务器根据当前的连接数和响应时间得到一个分数,分数较高代表性能较好,会得到更多的连接。
  • 预判算法:该算法使用观察算法来计算分数,但是预判算法会分析分数的变化趋势来判断某台服务器的性能正在改善还是降低。具有改善趋势的服务器会得到更多的连接。该算法适用于大多数环境。

有关电商网站在假期峰值解决方案的经验分享,InfoQ 中文站以前曾专门采访过淘宝的几位专家:

国内一年一度的光棍节电商促销又要开始了,开发和运维人员将面临巨大的挑战。有关技术分享,InfoQ 中文站将持续关注。

2012-11-08 20:506817
用户头像

发布了 501 篇内容, 共 280.5 次阅读, 收获喜欢 64 次。

关注

评论

发布
暂无评论
发现更多内容

【组件攻击链】一文看懂Spring全家桶各类RCE漏洞

H

网络安全 漏洞

从零开发区块链应用(一)--golang配置文件管理工具viper

杰哥的技术杂货铺

golang 区块链

在Rainbond上使用Locust进行压力测试

北京好雨科技有限公司

Discord模式等十大场景,环信带你玩转泛娱乐行业

环信

即时通讯 IM 泛娱乐 Discord

逐鹿万亿赛道:智能重卡规模量产的困境与进化

脑极体

网关流控利器:结合 AHAS 实现 Ingress/Nginx 流量控制

阿里巴巴云原生

nginx 阿里云 高可用 云原生 ingress

最佳实践 | 如何避免一行错误代码造成的血案?

Atlassian

Atlassian Jira 代码评审

2021年小总结暨2022年打脸计划

秦怀杂货店

总结 程序人生、

使用MSF生成shellcode

喀拉峻

黑客 网络安全 安全 WEB安全

蚂蚁大规模 Sigma 集群 Etcd 拆分实践

SOFAStack

etcd #k8s SIGMA

如何快速调度 PTS 的百万并发能力

阿里巴巴云原生

阿里云 云原生 Jmeter 压测 PTS

架构实战营 4 期第五模块作业

jialuooooo

架构实战营

从零开发区块链应用(二)--mysql安装及数据库表的安装创建

杰哥的技术杂货铺

当基础设施故障后,声网 SD-RTN 如何保障 RTE 服务的高可用性

声网

人工智能 云计算

Ubuntu16.04/Scala2.11.8安装教程

CRMEB

金融云原生漫谈(六)|安全平稳高于一切的金融行业,如何构建云原生安全防线

York

容器 云原生 安全 金融科技

软件架构治理 之 架构优化方向

码猿外

架构设计 技术债 软件架构治理

一个cpp协程库的前世今生(二十)外部调度

SkyFire

c++ cocpp

使用 google_breakpad 分析 Electron 崩溃日志文件

编程三昧

Electron 1月月更 google_breakpad

Spring都在用的技术,你确定不过来看看?1️⃣

XiaoLin_Java

1月日更

从零开发区块链应用(三)--mysql初始化及gorm框架使用

杰哥的技术杂货铺

阿里云刘伟光:3.5万字拆解核心系统转型,核心从业者如何寻得“出路”

OceanBase 数据库

阿里 数字化转型 OceanBase 社区版 核心系统

架构实战营:模块五作业

Geek_93ffb0

「架构实战营」

混合云应用双活容灾最佳实践

阿里巴巴云原生

阿里云 运维 云原生 混合云 多活容灾

谈A股投资策略--《香帅中国财富报告》摘录(5/100)

hackstoic

投资

实时云渲染,汽车产业数字化转型新动能

3DCAT实时渲染

云计算 数字化 汽车 云渲染

创新推出 | Serverless 场景排查问题利器:函数实例命令行操作

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

基于 Prometheus 的边缘计算监控实践

火山引擎边缘云

云原生 监控 边缘计算

VuePress 博客优化之拓展 Markdown 语法

冴羽

JavaScript Vue markdown vuepress 博客搭建

电商网站的宕机案例分析_后端_崔康_InfoQ精选文章