写点什么

电商网站的宕机案例分析

  • 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:506427
用户头像

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

关注

评论

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

IntelliJ IDEA 撤销和反撤销

HoneyMoose

IntelliJ IDEA 修改只读模式和可写模式

HoneyMoose

OpenMMLab图像分类实战代码演示

IT蜗壳-Tango

CV OpenMMLab 图片分类

SpringBoot动态配置文件及项目打包部署

微枫Micromaple

maven Profile springboot 部署 项目上线

解读 Java 云原生实践中的内存问题

阿里巴巴云原生

Java 阿里云 云原生

Relocating the Docker root directory

平凡人生

Docker

推进行业生态发展完善,中国信通院第八批RPA评测工作正式启动

王吉伟频道

RPA 机器人流程自动化 中国信通院 RPA评测 RPA产业推进方阵

vue实现一个鼠标滑动预览视频封面组件(精灵图版本)

JYeontu

Vue 视频

应用纳管和灰度发布:谐云基于 KubeVela 的企业级云原生实践

阿里巴巴云原生

阿里云 容器 云原生 KubeVela

架构实战营模块5 高性能高可用计算作业

西山薄凉

「架构实战营」

C++ 友元与运算符重载那些事

王玉川

c++ 编程语言 运算符 重载 friend

云原生微服务应用平台 EDAS 2022 年度报告

阿里巴巴云原生

阿里云 微服务 云原生

ChatGPT真的可以取代基础工作岗位吗?

老张

人工智能 产业发展 ChatGPT

docker setup mysql

平凡人生

MySQL

Higress + Nacos 微服务网关最佳实践

阿里巴巴云原生

阿里云 云原生 nacos Higress

全景剖析阿里云容器网络数据链路(五):Terway ENI-Trunking

阿里巴巴云原生

阿里云 容器 云原生

技术服务深耕本地市场:阿里云在日本的探索与实践|国家经理专栏

阿里巴巴云原生

阿里云 云原生

API Explorer 进阶之路 | 一篇文章快速入门!

华为云PaaS服务小智

ONES 支持多项信创适配,打造自主可控的国产化平台

万事ONES

渲染速度慢,使用云渲染会快多少?

Renderbus瑞云渲染农场

云渲染 渲染慢怎么办?

CleanMyMac X2023电脑最新版本更新内容

茶色酒

CleanMyMac X CleanMyMac X2023

突破边界:“超融合+”带来的商业化精益之路

脑极体

核心应用实现云原生改造升级,波司登数字化战略加速落地

阿里巴巴云原生

阿里云 云原生

基于SLO告警(Part 4):开源项目 pyrra 使用

Grafana 爱好者

云原生 可观测性 Prometheus SRE SLO

重磅发布丨《云原生实战指南》助力企业上云实践!

阿里巴巴云原生

阿里云 云原生实战

2022阿里云技术年报:基础产品篇

阿里巴巴云原生

阿里云 云原生 基础产品

10 亿月活用户下,快手基于 Dragonfly 的超大规模镜像分发实践

阿里巴巴云原生

阿里云 容器 云原生

试试 IntelliJ IDEA 新的 UI

HoneyMoose

为什么在容器中 1 号进程挂不上 arthas?

阿里巴巴云原生

Java 阿里云 容器 云原生

从 JDK 9 到 19,我们帮您提炼了和云原生场景有关的能力列表(上)

阿里巴巴云原生

阿里云 云原生

Java 中如何限制方法的返回时间

HoneyMoose

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