惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
N
News and Events Feed by Topic
T
Tor Project blog
AI
AI
S
Schneier on Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hacker News: Ask HN
Hacker News: Ask HN
Spread Privacy
Spread Privacy
The Last Watchdog
The Last Watchdog
B
Blog
G
GRAHAM CLULEY
Recent Commits to openclaw:main
Recent Commits to openclaw:main
W
WeLiveSecurity
GbyAI
GbyAI
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Check Point Blog
SecWiki News
SecWiki News
Y
Y Combinator Blog
I
Intezer
S
Securelist
WordPress大学
WordPress大学
小众软件
小众软件
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
Schneier on Security
Schneier on Security
F
Full Disclosure
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Proofpoint News Feed
Jina AI
Jina AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Help Net Security
Help Net Security
P
Privacy International News Feed
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
The Register - Security
The Register - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
MyScale Blog
MyScale Blog
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threatpost
H
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
T
Tailwind CSS Blog
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
C
Cisco Blogs
The GitHub Blog
The GitHub Blog
博客园 - 司徒正美

顾宇的博客

用 AI 重启生活 初始化 MacOS 关于我 再次见面,期待相遇 演讲和分享 如何通过政策红利获利?——海南发展(SZ.002163)交易复盘 2025年的总结 2024年的总结 2023年的总结 2022年的总结 《敏捷测试价值观、方法与实践》序 【翻译】函数式编程中的领域驱动设计 【翻译】通过跟踪技术债来改进你的开发实践 【翻译】不要把测试用例自动化 【翻译】持续部署 vs 持续交付 【翻译】测试替身 【翻译】做多少测试才足够 【翻译】蓝绿部署的起源 【翻译】持续部署 【翻译】作为演进式架构的微服务架构 【翻译】gRPC 的动机和设计原则 【翻译】分布式计算谬误 【翻译】微服务和分布式对象第一法则 采用 Multipass 管理本机虚拟 K8S 集群 博客主题升级到 Congo 2.0 【翻译】Terraform 最佳实践:模块组合 【翻译】Kubernetes 部署语言(Kubernetes Deployment Language) 通过 Vagrant 一键初始化 K8S 集群 2021年的总结 通过 Github Actions 部署 Mkdocs 文档 博客迁移到了新的 Hugo 主题 2020年的总结 2019年的总结 千人规模组织级 DevOps 演进的 9 个实践技巧 从技术雷达看 DevOps 的十年——容器技术与微服务 DevOps 模式 - 引入 DevOps 顾问 DevOps 模式 - 索引 DevOps 模式 - 定义你的DevOps 从技术雷达看 DevOps 的十年——基础设施即代码与云计算 DevOps 模式 - 采用模式语言讨论 DevOps 从星巴克店面运营学习 DevOps 从技术雷达看 DevOps 的十年——DevOps与持续交付 【翻译】微服务安全:所有应该被问到的问题 云原生下的 DevSecOps 实践 【翻译】软件定义交付宣言 微服务演进中的经验和反思 迟到的 2018 年终总结 成功微服务实施的组织演进 从第19期技术雷达看 DevOps 的发展趋势 成功微服务实施的技术演进 我们如何衡量微服务的成功? 关于四周四 AWS 架构工作坊的设计和实践 讨论微服务之前,你知道微服务的 4 个定义吗? 公有云(AWS)上的生产环境架构优化案例和迁移套路总结 公有云(AWS)上的生产环境性能分析案例 采用 DevOps 故事落地 DevOps 测试驱动开发 Nginx 配置 云原生 DevOps 翻译-混沌工程的原则 Serverless 风格的微服务的持续交付 从最新一期技术雷达看 DevOps 的发展 关于 DevOps ,咱们聊的可能不是一回事 Serverless 风格的微服务的架构案例 提升微服务实施效率的 7 个步骤 微服务实施常被忽视的 5 个难点 你的 CI 在挖矿吗? DevOps前世今生 - 4. DevOps 的文化 DevOps发展的九个趋势 不要让你的持续集成服务器成为安全隐患 DevOps 前世今生 - 3. DevOps 的目标和核心 DevOps 前世今生 - 2. DevOps 矛盾从何而来 DevOps 前世今生 - 1. DevOps 编年史
一怒之下,我又写了一个开源流量测试工具
顾宇 · 2018-07-07 · via 顾宇的博客
  1. 顾宇的博客/
  2. Blogs/
  3. 一怒之下,我又写了一个开源流量测试工具/

继一怒之下我写出了 Vivian(详见“ 测试驱动开发 Nginx 配置”)之后。又在等待客户审批流程的时间里自己写了一个流量测试工具。

背景 #

客户的站点是通过 Wordpress 搭建的,这个应用放在一台 EC2 虚拟机上。奇葩的是,这个应用的 MySQL 数据库也在这台虚拟机上,之前做过一次 RDS 迁移,失败了,原因未知。看起来这个应用和数据库就像筷子兄弟一样,不离不弃,而且没有办法通过 AutoScaling Group 进行水平扩展。也就是说,所有的东西都在一台虚拟机上。

我所要做的,就是把这个架构重新变成可自动水平扩展且高可用高性能有缓存低消耗具备监控和更加安全且有版本控制并可以通过持续交付流水线来半自动部署的架构。你可以重新读一下上一句加粗文字的内容。没错,目前他们连版本控制都没有,所有的操作在服务器上通过 mv 之间 scp 进行。

很不巧的时候,这个“筷子兄弟”应用在上周开始,晚上随机的 Down 机,表现为数据库被删。但通过日志可以发现,是由于内存资源不足导致的 MySQL 数据引擎加载不了导致的。

由于需要做“筷子兄弟”拆分手术,目的是要把数据库和应用程序分开,并且需要进行一些服务的重启和拆分。这些操作中会导致停机时间,为了能够度量这个停机时间,便于做出更好的决策,客户希望在测试环境上能够通过模拟生产环境的工作状态来完成这个任务。我设计了方案,包括以下几点:

  1. 知道每一个可能引起停机的操作引起停机的时长。
  2. 测试 RDS 能带来多少的性能提升。
  3. 找出整个架构引起停机的根本问题。
  4. 在 500 个并发用户访问的情况下,会出现的性能拐点。
  5. 能够度量应用的资源损耗。

客户已经购买了 NewRelic 和 Flood.io (我在 17 期技术雷达里提交的条目,叉会腰。)但是 Flood.io 的账号分配需要一个额外的审批才可以使用,也就是说,我得等到第二天才能使用。

我想,也许 github 上会有这样的工具能够满足我这个简单的需求,搜了一圈,没有合适的。

于是,一怒之下,我用了大概两个小时的时间用 Python 编写了这样一个测试工具。

工具的设计 #

There are only two hard things in Computer Science: cache invalidation and naming things.

– Phil Karlton

命名是一件很困难的事情。于是,为了纪念这个事情,一开始我用提出这个需求的客户的名字(Dave)来命名它,但可能不太好记忆。所以最后还是用 Wade (Web Application Downtime Estimation)作为这个工具的名字。它很简单,可以在https://github.com/wizardbyron/wade找到。

如果我需要知道停机时长,我必须要先能够持续不断的发出 http 请求,并记录下相应 状态不是 200 OK 的返回。我并不希望应用是一个死循环,因此我需要能够加入时间控制。我期望用下面的这样的方式来使用:

wade -t 10 -u https://www.google.com

其中,-t 代表时间,10 代表持续分钟,-u 表示要测试的 url。我期望这个工具能够连续的帮我输出每次请求的时间和 HTTP 状态字。

例如:

1
2
3
[2018-07-05 22:30:57]status:200
[2018-07-05 22:31:08]status:200
[2018-07-05 22:31:15]status:200

这个需求其实很简单,我大概花了半个小时就完成了。

在实际应用中,你需要先运行这个程序,然后再执行那些可能引起停机的操作。于是我准备让它运行30分钟,因为这些操作会执行多久我并不清楚。

很好,经过测试,这些操作只会引起 5 秒左右的停机。

不过,我好像忘了一个重要的事情…… #

那就是这个应用是单线程的,也就是说,这个实际上和真实的场景相差很远。我需要能够有 500 个并发 HTTP 请求,于是我把它改造成了多线程的。我期望用下面的这样的方式来使用:

wade -t 10 -n 5 -u https://www.google.com

其中,-n 代表线程数量。

有了多线程,我就需要改变这些应用的输出。对于多线程应用,输出需要知道每个线程的执行情况并且要能够汇总。因此,我期望应用能够这样输出:

1
2
3
4
5
{'Thread': 0, '2XX': 2, '3XX': 0, '4XX': 0, '5XX': 0}
{'Thread': 3, '2XX': 2, '3XX': 0, '4XX': 0, '5XX': 0}
{'Thread': 1, '2XX': 4, '3XX': 0, '4XX': 0, '5XX': 0}
{'Thread': 4, '2XX': 4, '3XX': 0, '4XX': 0, '5XX': 0}
{'Thread': 2, '2XX': 4, '3XX': 0, '4XX': 0, '5XX': 0}

因为,其实3XX 类的返回值在某些情况下也应该算是正确,而 4XX 和 5XX 类的返回值应该分开统计。因此,我改进了一下这个工具。

在改进后我重新测试,我找到了问题的答案:

我成功的把数据库迁移到了 RDS 上,并在测试环境实例上停止了 MySQL 进程,带来了 40 倍的性能提升。发现这个应用的数据库需要最少 10 GB 的内存才能正常工作。

当我以 500 个线程去持续请求的时候,我把服务器弄挂了。输入的响应很慢,且执行命令会返回-bash: fork: Cannot allocate memory 的错误。通过减少进程数,我发现一个用户请求会占用 110 MB 左右内存,要满足 500 个用户的并发访问,主机需要最少 64 GB 的内存。

由于并发用户增长的同时,内存也在增长,物理内存用完之后会使用 Swap 区的虚拟内存空间。当 Swap 区的空间占满后,这个时候因为没有可分配内存,所以应用响应奇慢。即便是我终止了测试请求,仍然没有缓解,我猜之前的请求已经在 HTTP 端排队,在请求没有结束或者超时释放资源,后续的请求会继续排队。

那个…… 好像,我刚才对这个服务器进行了一次 DoS (拒绝服务)攻击

加载了 NewRelic,我发现这个应用在加载首页的时候性能是最低的,而大部分的资源都消耗在了 select 查询上。因此,我判断其中的表或者数据有问题,会进行大量加载。其次,可以通过给首页增加页面缓存,或者在数据库库端加入缓存,来缓解资源占用。毕竟,首页的访问时最频繁的。

最后,我们可以把 wade 在测试中度量到的数据当做是架构演进中的验收测试或者冒烟测试,集成在持续部署流水线中,在变更基础设施或者部署应用之后执行。我们需要非功能的架构级别的自动化测试来保护应用架构的重构。

反思 - 少即是多 #

如果没有这个工具,想得到以上的答案。我需要同时在三个服务(AWS CloudWatch, NewRelic, Flood.io)之间来回切换,并且搜集到需要的数据。那么多的数据,找到一个简单直接能反应问题的数据也很困难。而在等待账号审批的过程中,我就写下了这个工具。这个工具覆盖了客户会关心的基本场景和数据之间的关系。而这三个工具不能同时都满足(其实NewRelic 其实就差一点点)。虽然每个工具在各自领域 和所面对的客户都是非常强大的工具,而一个真实客户需求的场景 - 找到在正常压力下影响停机时间的因素 - 却很难被满足。

所以,对于非目标的用户和使用场景,产品丰富的功能和数据有可能是需要被过滤的噪音。一个产品所要面对的用户场景越多样,它所引入的噪音就会越多。而更多的增值服务和高价值服务,则被淹没在了这样的噪音里。

支付宝和银行的手机端应用就有这样的问题,什么都做的事情,一般什么都做不好。

最后 #

作为一个两个小时之内完成的工具,wade 缺乏各种自动化测试。但是,从 wade 设计过程我们可以看出,虽然我没有写自动化测试,但是设定期望并完成期望的结果是一致的。从这个角度上讲,TDD 也是把大脑中对程序的设计过程记载下来的一个活动