SRE&Devops 每周分享 Issue #4 AWS Layer

SRE 监控的黄金指标

服务响应延迟、请求总量、错误数量、系统资源使用率是 Google SRE 提出的“四大黄金监控”指标,之后被很多团队实践。本文介绍了为什么这四个指标是了解系统当前状态最合适的四个指标。也提出了一些其他在提高系统可用性方面的实践。

Observability at Scale: Building Uber’s Alerting Ecosystem

Uber 的官方博客,介绍了它们的监控报警系统。Uber 有两个监控系统,一个是 uMonitor,从时序数据库中检测异常,发出报警(业务层面);一个是 Neris,监控基础设施,比如 CPU/Mem 等。文中分别介绍了这两个监控系统,以及如何报警、如果管理报警。

Why Use K-Means for Time Series Data? (Part One)

K-means 算法处理时序数据教程:

  1. Part1:如何使用统计学函数和 K-means 聚类从时序数据中检测异常
  2. Part2:代码实践,如何将 K-means 算法应用到时序数据,以及一些缺点
  3. Part3:如何使用 K-means 和 InfluxDB 在 EKG 数据中检测异常

Get Application Performance Metrics on Python Flask With Elastic APM on Kibana and Elasticsearch

很多 APM 客户端是开源的,Server 不开源。ELK 架构就很良心了。这是使用 Elastic APM 和 ES 的一个手把手教程。

Garbagedog: How eero does continuous monitoring of Java garbage collection

Eero 开发的一个监控 JVM GC 的组件(Python 编写)。Github

Open-Sourcing Our Incident Response Training

PagerDuty 开源了它们的应急反应培训资料。

Kubernetes Security — Are your Container Doors Open?

本文介绍了一些常见的 Kubernetes 误留下的漏洞,以及检查漏洞的方法。

Amazon Lambda 宣布 Layer 功能

Amazon Lambda 问世 4 年了,本周又宣布了重量级功能:Layer。Layer 可以允许不同语言编写的 Function 互相调用。之前,如果有不同的 Funtion 引用了相同的代码,那么就要将代码同引用代码一同打包发布。现在,你可以将被引用部分的代码单独发布,然后在 Function 中引用。Function 可以带有单独的版本控制,这样升级也不会影响所有的代码。

另外公布了 Runtime API,你可以提供一个可执行文件(比如 Python 解释器),然后 Lambda 会处理 Function 的调用和你的解释器执行代码这一层,你可以使用自己定制的 Runtime,也可以使用 AWS 官方制作的 Runtime。Runtime API 将是 AWS Lambda 将来支持新语言的方式。

这里有一个 awesome-layers 整理了一些 Runtime、可以调用的 Layer Function、以及一些监控的 Layer.

工具 twistlock/cloud-discovery

可以列举出你当前使用的所有云服务,原理就是你给它秘钥,它对接了每一个云平台服务商,会给你查询当前运行的各类云服务。举个例子就很明白了:

此工具以 Docker 形式提供,使用方便。主要可以用来审计,如果用了“弹性”的服务,这个工具就很实用了。我觉得可以和监控平台配合起来,每分钟扫描,记录下实时的资源使用。

另外它只使用读的 API,所以可以放心使用(不放心的话还是去看一下源代码)。

它的另一个功能是可以扫描 IP 端和端口,这样可以管理自建的云服务。

工具 dive

可以分析对比每一层 Docker image 都有哪些 diff,再也不用猜着做出更小的镜像了!

The Human Side of Microservices

InfoQ 对一位软件工程师的采访,涉及微服务、软件架构、devops 等话题。

 

SRE&Devops 每周分享 Issue #3

Scaling Spark Streaming for Logging Event Ingestion

在 Airbnb,用户的每一次搜索、预订都会产生 log。这些 log 可以帮助 Airbnb 更懂客户,为顾客和房东提供更好的服务。这些数据也会驱动业务发展和产品迭代——因为他们会反过来影响机器学习的模型和搜索排名。

Airbnb 的日志处理是近乎实时的。客户端和服务器将事件发往 Kafka,Spark Streaming Job 会持续从 Kafka 读出来然后放到 Hbase 中做去重,然后每小时从 Hbase dump 到 Hive 中。

这些日志是很多图表和控制台的元数据,所以保证这些数据的实时性和 SLA 就很重要。

然而,这些日志事件的量无法预估(由于促销、假期或者其他原因),而且事件会有偏斜(大小不一致),而 Kafka 的 partition 又不能自动水平扩展。这样就有很多挑战(具体见文),比如 HBase down 了一段时间,恢复之后无法给 Spark 分更多的资源,就要花很多时间追平。

另一方面,读日志最终还是存到 Hbase 中,所以时序并不重要,据此可以重新设计模型。Airbnb 开发出负载均衡的 Kafka reader,最终解决了文中描述的所有问题,可以水平扩展 reader。

Linux 系统网络管理员最常用的 32 个 Nmap 命令

Nmap 是一个开源的网络安全软件,它使用 IP 包来探测,可以统计网络上的 Hosts,这些 Hosts 提供的服务,运行的操作系统,安全、防火墙规则等。使用在监控方面非常方便。

Nginxconfig.io

一个可以自动根据你的选择生成 Nginx Conf 文件的网站。

Kubernetes Cheat Sheet

Red Hat 的有关 k8s 的介绍,以及如何在本地安装。

Starting and Scaling DevOps in the Enterprise

Gitlab 首页推荐的一本书,Devops 在大型企业的实践。

Cheat sheet: Linux networking

Linux 常用网络命令速查表

Ansible2.7: reboot plugin

Ansible2.1 就有了 win_reboot,因为 windows 重启的需求比 Linux 更频繁。Linux 的重启也可以通过 shell wait_for 来实现。但是有很多坑需要注意。

被折磨很久之后,reboot for linux 终于出现了。本文介绍了 reboot  这个 plugin 的设计、实现和用法。

Java 微服务:容器与框架的介绍 (By RedHat)

Orchestrating Chaos using Grab’s Experimentation Platform

Grab 做 Chaos 的经验分享。

Capacity planning for Etsy’s web and API clusters

Etsy 做容量规划的经验分享。

The Datacenter As A Computer: Designing Warehouse-Scale Machines, Third Edition

又名:Google 是如何建造数据中心的。第三版。读完可能要花一些力气,不过里面的图很酷炫。

 

SRE&Devops 每周分享 Issue #2

Python in RHEL 8

Red Hat 上周发布了 RHEL8,这是官网发布的一篇博客,讲了在 RHEL8 上面使用 Python 的一些注意事项,非常值得一读。

10 年前,Python 社区决定摆脱技术债,发布一个不向后兼容的版本 Python3,但是他们显然低估了这门语言的流行程度和带来的兼容性问题。

在 RHEL8 上面,Python3.6 是默认版本,但是也没有在系统默认安装,需要 yum install python3 。Python2 也是可以通过 yum 安装的: yum install python2 。

但是不带版本的命令 python 会导致 command not found 。因为现在有两拨人,一波认为默认 Python 应该是 Python2,用 Python3 的话应该显式键入 Python3。但是另一拨人应该向前看,默认 Python 应该换成 Python3 了。话说笔者在这周就遇到一个因为 Python 指向 Python37 导致 build 失败的 bug。在这方面,RHEL8 保留观点,默认的 Python 不指向任何命令,用户必须显示的写明版本(这样脚本也可以在任何版本的 Linux 下工作)。

既然 RHEL8 不自带 Python,那 yum 又是 Python 写的,yum 是怎么运行的呢?这个问题就留给读者自己去阅读此文吧。除此之外,这篇文中还写了如何正确使用 pip,如何正确使用 virtualenv,可以说都是一些“最佳实践”,非常值得一读。

Overload Control for Scaling WeChat Microservices

这是 the morning paper 推荐的一篇 Paper,非常值得一读。介绍了微信微服务的流量过载控制系统 DAGOR。此系统已经微信生产环境中服役 5 年,可谓身经百战。过载控制系统可以在当系统过载的时候有效的保护后端的系统,微服务的开发者很难正确估计真正生产流量,所以将过载控制系统从服务逻辑中解耦出来就非常重要。这篇 Paper 可能在这方面给你一些启发。

Analyzing the GitHub outage

非官方的,一篇有关 Github 10月故障的分析。

Some notes on running new software in production

当你想在生产环境使用新的软件时(我觉得新 lib 也差不多),应该花多少时间去了解你要用的这个东西?应该要了解到什么程度?此文是一篇不错的参考。(ps:Jvns 的博客有口皆碑)

工作、生活、side-project 和学习的平衡

是不是感觉很难做着一份工作的同时还保持学习新的技术?没时间去完成自己的 idea?甚至完全没有自己的生活了?

这篇帖子给出了很多有用的建议:

  1. 尽量减少通勤时间
  2. 保证锻炼和休息的时间
  3. 集中精力
  4. 每天进步一点点
  5. 理智的选择社交生活
  6. 接收事情要花很长时间,不要总是想 ALL IN、把其他事情放到一边。慢慢来,即使某件事要花上十年。不要期望某个事情会从一个时间马上就发生改变,接受事情是慢慢做成的。

Travis CI <3 Honeycomb

 本文介绍 Honeycomb 给 Travis 带来的巨大价值。Travis 一周会运行超过 300 万次 build,在这么大的流量中,如果没有足够的数据的话,调试某一次 build 问题,或者接口问题是很困难的。Travis 在没有 Honeycomb 之前是使用几个 Metric(四条黄金监控)来监控线上的服务状态的。但是这样的问题是,没办法知道某一次 outage 影响了多少用户,耗时高的流量是从哪里来的。也就是粒度不够。第二个资源是日志,日志是原始的信息,动辄好几屏,如果没有好的工具,很难使用日志。

Honeycomb 就是这样的工具,以前无法使用的庞大数据,用 Honeycomb,只需要点几下鼠标就可以了。文章举了一个例子,某一个用户(很可能是 bot)持续访问一个非常慢的 API,拖慢了整个接口耗时。有了 Honeycomb,Travis 很快定位出了这个用户,并确定这个是没有对其他用户造成影响的。要是没有 Honeycomb,可能要排查日志、定位、评估很长时间。

在生产环境中部署 Django Channel

本文介绍了在生产环境中部署 ASGI 应用和 WSGI 应用的方法(分别分开部署的)。包括 Nginx、gunicorn、daphne 的部署等。还有 websocket 的压测方法。放在书签里以后可能会有用:)

Introducing PyEnvDiff-lib and a Hub & Spoke Python Environment Diff Tool

本周正好遇到一个 flake8 的结果本地和 CI 不一致的情况,搞了半天发现是本地有一个全局的 config (啥时候写的我自己都忘了)。所以类似的工具可能可以解决这种问题。

The ultimate DevOps hiring guide

《Devops 雇佣指南》给雇主和寻找工作的 devops 的建议。

Highly Available Microservices with Health Checks and Circuit Breakers

介绍了几种负责均衡的方案,和健康检查、熔断的方法。很好的一篇入门文章,后面介绍了 Kong 的解决方案和使用方法。个人很看好这个项目!

 

Nginx if 指令工作原理

Nginx 的 if 指令被认为是“邪恶”的,就和 C 语言的 goto 一样。甚至官方有一篇 If is Evial 来警告你不要使用 if 。但有时候 if 还是非常有用的,如果掌握了它的原理,在合适的地方正确使用 if,会让事情更简单一些。当然前提是你真正知道自己在做什么,就和 goto 一样。 ——这是我的观点。

首先每个接触 Nginx 的人应该意识到的事情是,Nginx 是分 phase(阶段) 的,并不像 C 这种编程语言一样顺序执行。指令执行的顺序和书写的顺序没有太大关系(跟具体模块的实现有关),一个 phase 执行完了就会执行到下一个阶段。

If 是属于 rewrite 模块的,所以对于 if 来讲,会和其他的 rewrite 模块执行全部执行完之后再进行下一阶段。如果 if 指令的结果是 match 的,那么 if 会创建一个内嵌的 location 块,只有这里面的 content 处理指令(NGX_HTTP_CONTENT_PHASE 阶段)会执行。

下面是 agentzh 的四个例子,我这里稍加自己的解释。

实验的机器 IP 是 172.28.128.4 ,结果如下:

首先,对于一个请求 Nginx 会执行 rewrite 阶段,即如下代码。rewrite 阶段的执行顺序和指令的顺序是一样的,这个 rewrite 模块的实现有关。

$a 被设为 32,然后进入 if block,$a 在这里被设为 56,最后 $a 被设为 76. 中间 if block 生效。但是 if block 中没有任何 content 阶段的指令,所以会继承 outer block,即 ngx_proxy 模块的 proxy_pass 设置。这里要注意的是请求在 if block 内完成,if 命中之后就进入了 if block 来处理下一阶段,而不会跳出 if。

第二段示例如下:

结果如下:

Rewrite 阶段的过程和上面一样,不同是这一次 if block 中有了 content 阶段的指令,所以会执行 echo,不会执行到 proxy_pass 。

Rewrite 阶段的 break 可以终止 rewrite 阶段的执行。

以上代码的结果是

在 rewrite 阶段中,执行完 if ($a = 32) 之后执行 set $a 56 ,此时下一行是 break ,然后 rewrite 阶段就停止了,进行下一阶段。set $a 76 并没有被执行到。所以最后 $a 的值是 56。

ngx_proxy 会继承 outter scope,但是很多模块并不会这样,这个地方挺坑人的,我就是在这里被坑到的。

参考这段配置,正常来说,所有的 echo 都会执行,即如果不存在 if 的话,这段配置的结果应该是 hello \n java 。但是这里结果会是:

可以看到 echo 并没有继承 outter 。

顺便说一下我写的那段配置吧。简化之后如下:

我期望如果进 if 和不进 if,都会执行我的 access_by_lua_file ,但事实看来,进入 if 之后并不会再出来,而且 access_by_lua 和 access_by_lua_file 像 echo 一样,if 内并不会继承外面的 access_by_lua_file 。所以如果 if 命中,那么 access_by_lua_file 永远不会执行到。

最后一个例子是会继承 outter 的:

结果如下:

可以看到,这个模块的 more_set_headers 指令是默认继承 outter 的。

所以,官方给出的建议是尽量不要使用 if 指令,比如说有些地方其实可以使用 try_files

如果用,那么尽量只在 if block 内使用 rewrite 模块的指令。因为大家都是在这一个 phase 里面的,不会有 surprise 了。

在某些情况下,这些需要 if 的指令可以用嵌入的第三方模块来完成,比如 ngx_lua perl 等。

实在要用的话,做好充足的测试。

 

SRE&Devops 每周分享 Issue #1 Opening

Hi, 我平时看到一些有趣的文章很喜欢分享给朋友(这也是我写博客的原因吧),现在订阅的内容也越来越多了,有些也实在看不过来(Pocket 都堆满了)。其中订阅了很多 newsletter,newsletter 并不是每一篇都对你的胃口,但是总有几篇不错的,所以我也打算将我的分享整理成这种形式。一方面,我的工作中很多方面还在摸索,另一方面,这样可以将我看过的东西整理下来。最重要是的希望这种方式可以遇到更多同行,大家可以互相交流。

关于形式,暂时我先发布在博客上,后面如果找到不错的 Newsletter 托管(欢迎大家推荐),可能迁移到邮件形式。我每周将想要分享的东西存成草稿,周五中午 1:00 定时发布。当前分那几个板块还没确定,写到哪算哪吧,后面根据需要来调整。

关于投稿,大家发到博客右侧的邮箱即可。

关于内容,暂时会以 URL + 我的推荐语、概括为准。内容我尽量推荐自己看过的,但是有些实在太长,我可能放到 Pocket 慢慢看,还没看完就推荐给大家也说不定。所以大家要带着自己的脑子来读这里推荐的东西,并不一定都是好的。大部分内容都来自 Hacker News,这是我主要的订阅源。

最后,这是一项个人工作,所以无法保证能更新多久也无法保证内容有多少,请见谅。以下是第一期内容。

Honeycomb’s Charity Majors: Go Ahead, Test in Production

“分布式系统天生就是不好克隆、模拟、staged的,所以放弃 Staging 吧。加入线上环境出现问题,有些用户访问图片很慢,有些正常,你能在 Staging 环境发现问题吗?”这是 Honeycomb 在 ChaosConf 2018 的一个演讲,很多人反对在 Production 环境中测试的原因是,他们认为这样会破坏真实用户的体验。但是有像 A/B 测试,金丝雀测试的存在,可以将影响控制在一定范围。

gRPC Load Balancing on Kubernetes without Tears

gRPC 是基于 HTTP/2 的,而 Kubernetes 的负载均衡是基于 TCP 连接的。而 gRPC over HTTP/2 只会建立一个 TCP 连接,所以这样负载均衡就会有问题,所有的请求都发到了一个节点上去。官方推荐使用 Linerd2 来做 gRPC 的负载均衡。

HTTP-over-QUIC to be renamed HTTP/3

HTTP over QUIC(Quick UDP Internet Connections) 被重命名为 HTTP/3,将不再使用 TCP。

Time Series Analysis with LSTM using Python’s Keras Library

这是一篇教程,使用 LSTM 对时间序列数据分析。类似股票走势之类。这对流量监控系统非常有用,普通的规则设定报警很容易出噪音,如果能够基于预测出的流量走势设定监控报警也许更准确一些。

The History of Unix, Rob Pike

上周的一个不错的视频,一位资深程序员 Rob Pike 怀念了 Unix 几十年的历史,和他的故事。

Incident Management in Gitlab

Gitlab 是一家很开放的公司,这是他们的事故管理策略。

Chaos Monkey Guide for Engineers – Tips, Tutorials, and Training

Chaos Monkey 教程,介绍了其理念,实践以及相关的阅读资料(制作很精美)。

How Automatic Root Cause Analysis Works

Instana 如何在复杂的系统中自动定位故障的根因。

Getafix: How Facebook tools learn to fix bugs automatically

我们可以自由的写 Bug 了,毕竟有机器人来修复。

October 21 post-incident analysis

Github 10月32日 故障分析。