`
猫耳呀
  • 浏览: 170657 次
社区版块
存档分类
最新评论

深度解析Tengine的调试与资源监控方法论

 
阅读更多

摘要: Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,提供更强大的流量负载均衡能力、全站HTTPS服务、安全防攻击、链路追踪等众多高级特性。团队的核心成员来自于淘宝、搜狗等互联网企业,从2011年12月开始,Tengine成为一个开源项目,团队在积极地开发和维护着它,最终目标是打造一个高效、稳定、安全、易用的Web平台。

阿里云CDN现在服务超过24万家客户,Tengine作为接入层提供高性能Web Server服务,是CDN系统最核心的组件之一。无论是来自阿里集团内部还是外部客户的流量服务,几乎都是由Tengine承载。可以毫不夸张地说,Tengine的服务质量直接影响着国内外无数大中小型Web站点的服务质量和业务存活,所以,维护Tengine的稳定性一直是我们团队的最高优先级目标之一。经过了多年淘宝、天猫等大型网站双十一活动的洗礼,Tengine的性能和稳定性已经得到了很好的验证。

有一句俗语:“上帝说要有光,于是便有了光。“阿里云高级开发工程师墨飏说,“Tengine在做工具化的时候,也基本沿袭了这样的思路。在做开发之前,我们会系统性地思考:我们需要面对什么样的场景,会碰到什么样的问题,需要怎样的调试技巧和工具,是否可以解决更多此类问题,于是,我们的工具便会在这样的思路下逐渐成型和完善。同时,在服务客户的过程中,我们也会遇到各种新场景新问题,为了定位和解决问题,我们也会针对性地提出解决方案,沉淀出更多调试技巧和工具。作为一线开发团队,我们一路走来积累了非常多调试技巧、工具化的经验。”

本文由阿里云CDN团队的研发同学笑臣和墨飏带来,从Tengine的内存调试、核心结构、upstream、coredump四个部分展开,为大家整理和分享一些实践经验。

内存调试——精准定位问题

Tengine作为C语言开发的应用,在内存的使用中会碰到一些问题,第一部分将重点介绍内存调试方面的相关内容。

从下图可以清晰的看出,Tengine内存分布可以从三个维度来理解:底层实现、抽象层、应用层。

一、底层实现

Tengine底层实现依赖操作系统的内存分配机制,常见的内存分配器包括jemalloc(FreeBSD)、ptmalloc(glic)、tcmalloc(Google),luajit则使用内置的dlmalloc库。Tengine在每个连接accept后会malloc一块内存,作为整个连接生命周期内的内存池, 当HTTP请求到达的时候,又会malloc一块当前请求阶段的内存池, 因此对malloc的分配速度有一定的依赖关系。jemalloc的性能是ptmalloc的两倍以上,我们在使用Tengine的时候默认采用jemalloc。jemalloc在追踪实际内存分配时可以使用“malloc_stats_print”来查看内部细节,帮助定位内存泄露等问题。

二、nginx pool调试

在底层内存分配工具无法定位问题时,我们需要从抽象层分析出了什么问题。
Tengine作为nginx 的fork,在使用nginx pool方面与官方nginx基本没什么区别,它的内存池管理机制在HTTP请求的任一阶段都可能被调用来分配内存,我们可以从内存分配的真实函数调用来统计内存分配的占用量、历史数量、当前数量、large alloc等。mod_debug_pool已经在Tengine社区开源,有兴趣可以自行查阅文档,它的原理是通过hook ngx_create_pool函数来记录__func__/__LINE__,在需要排查问题时可以展示历史数据,从抽象层定位内存泄露等问题。

三、lua内存统计

lua/luajit是另一个非常成熟的开源项目,在nginx生态系统中,lua-nginx-module允许lua/luajit以虚拟机形式内嵌到nginx提供强大的脚本能力,我们在阿里云CDN海量业务开发中大量使用到lua/luajit。在调试luajit内存占用时,可以通过collectgarbage来展示总内存占用量,通过扫描gc object,可以统计global_State中所有gc对象,OpenResty社区也提供了GDB工具来输出gc对象的数量和内存占用。

四、共享内存调试

Tengine是多进程服务模型,其进程间的通信主要依赖操作系统共享内存机制,随着业务的发展共享内存的使用频率越来越高,如何去定位、调试共享内存,是一个比较严峻的问题,且业内缺少相关工具。我们在调试共享内存问题时,沉淀和开源了mod_slab_stat工具,在Tengine社区可以查阅详细的文档,该工具统计和展示了每个zone的内存分配细节,包括page、slab和alloc num等,突出业务通信内容块分布情况等。该工具适用于ngx shm,基于ngx slab的stub stats模块是个例外。

以上,从底层实现、抽象层、应用层三个维度,可以定位到绝大部分Tengine系统和业务的内存问题,包括一些内存的调试技巧。

核心结构——调试与解决故障

Tengine作为高性能服务器被广泛应用,它的核心框架和核心数据结构决定了其承载服务的质量。针对所遇到的CDN用户上报故障的工单,比如请求异常、访问慢等,如何从Tengine核心结构去调试、定位和解决问题,是本部分要介绍的内容。

Tengine主要的核心结构包括连接、请求和计时器等。连接承载着请求,以连接池的形式提供前端、后端网络服务,其异步事件驱动的特性是Tengine高性能网络服务的基石,而其事件模型又和计时器紧紧关联,这些核心结构组成了Tengine的核心框架。

要调试和定位Tengine网络问题,需要从连接、请求、计时器等多角度思考,从读写请求状态、解析请求阶段、应答输出阶段、建连等多维度采集,从而得到更详细的全局监控数据。

Tengine在nginx stub status工具基础上,开发了tsar工具(已开源),来展示更细粒度的历史资源监控,包括应用层QPS、HTTPS和网络层的accept、读写等待等。基于reqstatus的域名级监控,可以针对任意粒度域名级来统计请求数、连接数和5xx、4xx等状态码数量,还包括连接的复用情况等。

有了tsar和reqstatus工具,我们可以从全局来分析Tengine系统的服务和性能状态,但是,这够了么?CDN系统中,我们会遇到一些问题,比如:为啥tengine/nginx访问慢?是因为客户端慢、后端慢、还是nginx本身hang住?如何去衡量“慢“?我们需要对请求时间进一步细分。

Tengine新增了responsefirstbytetime、responsefirstbytetime、upstream_response_time、writewaittime、writewaittime、upstream_read_wait_time等变量来记录从请求进入到响应结束整个请求流程中的包括不限于应答首字节、后端应答首字节、socket读写等待时间总和等关键指标。

Tengine在衡量和监控请求卡顿时,将events cycle内event平均处理时间和events cycle内timer平均处理时间综合来定位单cycle平均耗时长的异常,常见的问题如同步IO(磁盘负载高时写log卡顿)、CPU密集型执行流(lua实现的CPU密集型逻辑)。

有些时候,我们无法从全局资源监控角度定位问题,这时候可以从ngx_cycles->connections[]来查询当前执行的请求或连接结构信息,通过gdb脚本来扫描worker内当前连接信息,查看和调试是否有请求堆积或连接泄露等问题。mod_debug_conn(待开源)工具是上述调试技巧的沉淀,它还可以帮助我们查看请求/连接的内存占用、分析连接和请求上的各类信息。

同时,Tengine的计时器(timer)在异步业务场景中有重要作用,通过扫描计时器红黑树,分析每个event timer,我们可以调试和定位异步操作中的问题。有时候我们在平滑升级tengine服务时,worker一直处于shutting down状态无法退出,其实便是因为一直存在timer导致的。也可以通过hook ngx.timer.at函数来统计lua-nginx-module中的timer caller次数,解决timer超限的报错等。

回源监控

CDN是内容分发网络的简称,其分发的内容来自用户源站,负责回源的upstream模块是Tengine最重要组成部分之一,使Tengine跨越单机的限制,完成网络数据的接收、处理和转发。这部分主要介绍upsteam的一些调试技巧和回源资源监控的内容,以及相应的实例分享。

在上面的章节中,我们已经分析过如何依靠Tengine提供的关键指标来衡量和监控请求卡顿,那么,我们同样可以提出问题:如何去分析请求代理或回源失败?是因为客户端主动断连、后端异常还是请求超时?如何去分析真实的原因,从而实时监控回源失败,这也是经常困扰CDN用户和开发人员的难题。

从Tengine的请求处理流程分析,客户端在完成TCP三次握手后,比较常见的错误是:1、客户端异常断开连接;2、客户端主动断开连接;3、等待读写客户端超时。在Tengine读取请求内容后,解析客户端请求失败如请求行/请求头等协议出错,在upstream模块回源时,也可能发生连接后端失败、后端异常断开连接、后端主动断开连接、等待读写后端超时、解析后端应答头失败等错误,我们可以从Tengine的错误日志查看对应的报错信息,在此基础上,我们从ngx_http_upstream_connect、ngx_http_upstream_send_request、ngx_http_upstream_process_header、ngx_http_upstream_process_body_in_memory等回源关键函数切入,提供error flag来监控真实的客户端/回源失败原因,将错误统计输出至访问日志、reqstatus工具等,关联和分析域名/请求级别的回源失败问题,保障CDN服务的稳定性。

现在,我们有了回源的关键指标变量和error flag,可以依靠一些调试技巧来分享一个upstream问题实例。如图所示,当客户端请求通过Tengine upstream回源时,我们可能碰到这样的问题:

  • 读源站,读满buffer
  • 发送buffer size数据给客户端,全发完了
  • 循环上述两步骤…
  • 继续读源站,读出若干数据,且源站已读完
  • 发送部分给客户端,未发完(客户端卡或者其他原因)
  • 再次读upstream,读出again(显然,因为之前源站数据读完了)
  • 继续发送数据给客户端,未发完(客户端卡或者其他原因)
  • upstream回源先超时了,这个时候$error_flag表明等待读源站超时,但是事实是这样吗?

我们提供了完整的复现方法,如图所示:

站在上帝视角,很明显可以看到其实是客户端问题,但是回源采集的关键指标:errorflag、errorflag、upstream_read_wait_time、$write_wait_time,却告诉我们是源站出错导致的问题,数据不会欺骗我们,那么问题到底在哪里?

上述调试的一些技巧和回源监控,帮助我们理解upstream模块的原理:
1、upstream有2个计时器,前端的和后端的;
2、Tengine/Nginx即使写客户端写不进去,只要proxy buf没满也会尝试读后端,如果后端数据读完了,会读出EAGAIN;
3、后端计时器较短先超时了,关闭请求,此时往往认为后端出错,真实情况是客户端出错;

这个特殊实例,在某些场景下,甚至在很多的生成环境中,都是比较常见但却往往被忽视的问题,在帮助提升用户体验和服务质量的目标下,即使是nginx核心代码不易发现的bug,在完善的调试工具和回源监控下,一样无所遁形。有兴趣的同学可以搜索nginx邮件列表来详细了解问题背景,虽然nginx 官方因为一些原因没有合入该patch,我们在Tengine中也做了单独的优化策略。

Coredump

coredump是Tengine这类C开发的应用程序比较常见的问题,随着业务的迅猛发展,coredump往往会变得越来越大,甚至越来越频繁,我们从空间、数量、自动分析等角度层层递进来优化Tengine的coredump。

“cat /proc/PID/coredump_filter”这行指令帮助我们了解Linux操作系统coredump机制所支持的内存形态,包括私有内存、共享内存等。我们在使用Tengine时可以去除共享内存,降低coredump文件大小。同时,也可以限制一定时间内crash写coredump文件的次数,防止磁盘IO过高或磁盘空间被占满,Tengine提供了“worker_core_limit”指令(待开源)来限制至分钟/小时/天级别。

现在我们已经从空间和数量角度优化了coredump,方便了调试。那么是否可以自动化完成分析,提升定位问题的速度?答案是肯定的。

我们通过gdb python脚本来自动分析coredump文件,从中提取得到触发问题的请求的host、URL、headers等,有了这些信息,就可以不断复现来快速调试和定位问题。但是有时候,coredump栈并不能告诉我们完整的现场,而在crash时,Tengine丢失了日志中的请求信息,我们将这些信息记录在环形内存中,通过coredump文件将环形缓冲数据输出到文件,环环相扣,完整的现场,真相只有一个。

原理:http://nginx.org/en/docs/ngx_core_module.html#error_log

事后诸葛只能查漏补缺,我们需要提前发现问题,实时流量拷贝工具应运而生。http_copy是Tengine的扩展模块,可以实时放大转发本机的流量(HTTP请求),可以配置放大流量到指定地址和端口,也可设置放大的倍数和并发量等,更可以通过源站健康检查来自动关停流量,避免过大流量对Tengine和源站的正常服务造成影响。

在流量压测/流量拷贝时,不需要真实返回响应的内容,减少带宽消耗,drop_traffic工具添加body filter直接丢弃数据,或者截获c->send_chain/c->send函数直接丢弃数据,在调试时发现问题而不产生问题。

以上就是阿里云CDN团队对于Tengine的内存调试与资源监控方面的一些实践经验,希望对于正在使用开源Tengine的同学有一些帮助。

Tengine官网:http://tengine.taobao.org

Tengine Github:https://github.com/alibaba/tengine

阿里云CDN:https://www.aliyun.com/product/cdn

最后,阿里云CDN团队正在招聘志同道合的伙伴,欢迎加入~

原文链接

分享到:
评论

相关推荐

    tengine淘宝Web服务器 v3.1.0.zip

    4. 防盗链:Tengine提供了防盗链机制,防止其他网站未经许可引用你的资源,保护了网站的流量和资源安全。 5. 负载均衡:Tengine具有负载均衡能力,可以根据预设策略将请求分发到不同的后端服务器,提高系统可用性。...

    Tengine(tengine-2.3.3.tar.gz)

    7. **日志与监控**:Tengine的日志功能强大,可以方便地进行访问日志记录和分析。同时,通过与其他监控系统集成,可以实时监控服务器状态和性能指标。 8. **故障转移与备份**:Tengine支持主备模式,当主服务器出现...

    tengine图片裁剪相关资源

    linux环境下tengine整合lua和gm。实现自动图片裁剪,的安装包。可实现将图片剪切为指定的比例,加快前端的加载速度,对应使用博客https://blog.csdn.net/qq_36911145/article/details/82898096

    tengine2.1.2

    Tengine是淘宝团队基于Nginx开发的一款高性能的Web服务器/反向代理服务器,它包含了Nginx的所有功能,并在性能、稳定性和功能扩展性上进行了优化。标题提到的"Tengine2.1.2"是该软件的一个特定版本,这个版本包含了...

    tengine-2.2.0.tar.gz

    6. **热更新与平滑升级**:Tengine支持在线热更新配置,可以在不中断服务的情况下更新配置文件,降低了维护成本。 7. **更好的社区支持**:由于Tengine由淘宝公司开发并维护,因此在遇到问题时,用户可以获得来自...

    nginx-tengine-3.0.0

    Tengine是由淘宝发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝,天猫,优酷,全球速卖通,Lazada,阿里云等得到了很好...

    tengine-2.3.2_win64.rar

    标题 "tengine-2.3.2_win64.rar" 提供的是 Tengine 的一个特定版本,即 2.3.2,适用于 Windows 64 位系统的版本。Tengine 是一个基于 Nginx 的高性能 Web 和反向代理服务器,由淘宝网开发并维护,它在 Nginx 的基础...

    tengine-2.1.0.tar.gz

    《深入解析Tengine 2.1.0:构建高性能Web服务器》 Tengine是由淘宝网发起的Web服务器项目,它是Nginx的分支,旨在打造一个高效、稳定、易用且具有广泛社区支持的Web服务器平台。Tengine在Nginx的基础上进行了许多...

    阿里Tengine网关最佳实践.pdf

    - 灰度发布与监控:在进行服务更新时,Tengine支持灰度发布,能够将流量逐步迁移到新的版本。同时,它还集成了监控系统,可以监控服务的状态和数据统计。 - Tengine背后的协议卸载、动态推送、HTTPS优化等技术,都...

    Tengine 用户使用手册丨OPEN AI LAB

    Tengine 用户使用手册 Tengine是一款轻量级模块化高性能的神经网络推理引擎,专门针对Arm嵌入式设备优化,支持Arm Cortex CPU、Arm Mali GPU、Arm DLA以及第三方DSP。开发者可以使用Tengine在主流框架模型和嵌入式...

    tengine-2.3.1.tar.gz

    7. **日志管理和监控**:Tengine可能会提供更灵活的日志格式和统计工具,帮助管理员更好地监控服务器状态,及时发现并解决问题。 8. **模块热更新**:Tengine支持模块的热更新,无需重启服务器即可实现配置的变更,...

    tengine-2.3.2 for windows full modules

    在这个过程中,开发者已经修复了源代码中许多与Windows编译不兼容的问题,确保了Tengine在Windows上的稳定运行。 在提供的文件列表中,我们看到的是一系列动态链接库(DLL)文件,这些文件对于在Windows上运行...

    淘宝Tengine 易运维的高性能Nginx服务器

    因此,为了更好地满足实际业务需求,淘宝的技术团队基于Nginx的核心功能进行了深度定制和开发,推出了Tengine。 #### Tengine的核心特点 - **高兼容性**:Tengine完全兼容Nginx的所有特性,并在此基础上增加了更多...

    tengine-2.0.1.tar.gz

    **Nginx基础与Tengine的关系** Nginx是一款广泛使用的开源HTTP服务器和反向代理服务器,以其轻量级、高效的性能和模块化设计而闻名。Tengine是在Nginx的基础上进行二次开发的产物,它不仅包含了Nginx的所有特性,还...

    tengine安装包和依赖包

    Tengine是一款基于Nginx开发的高性能Web服务器,由淘宝网发起并维护,它在Nginx的基础上增加了一些特性和优化,更适合大规模高并发的互联网应用。以下是对"Tengine安装包和依赖包"的详细解释: 一、Tengine概述: ...

    Tengine for windows

    Tengine web server for windows ,兼容nginx Tengine 使用cygwin编译适用于windows x64,编译了健康检查模块,health check check interval=3000 rise=2 fall=2 timeout=1000 type=http; check_...

    基于 tengine-2.3.3 制作的 nginx rpm离线安装包

    3. **日志查看**:日志文件一般在`/var/log/nginx`目录下,可用于监控和调试。 4. **更新升级**:如果需要升级到新版本,可以重复上述制作和安装过程,但需注意备份现有配置和数据。 综上所述,基于Tengine-2.3.3的...

    cpp-Tengine一个精简高性能用于嵌入式设备的模块化推理引擎

    2. **高性能**:通过优化计算库和内存管理,Tengine能够充分利用硬件资源,实现深度学习模型的快速推理。特别适合于ARM架构的处理器,如Cortex-A和Cortex-M系列,以及各种GPU和 DSP。 3. **跨平台兼容**:Tengine...

    Tengine与Nginx的特性

    ### Tengine与Nginx的特性对比分析 #### 一、引言 随着互联网技术的飞速发展,网站流量的增长速度惊人,对于Web服务器的要求也越来越高。为了满足这些需求,淘宝网推出了Tengine项目,这是一个基于Nginx的高性能Web...

    淘宝开源的Web服务器 Tengine.zip

    监控系统的负载和资源占用从而对系统进行保护;显示对运维人员更友好的出错信息,便于定位出错机器;更强大的防攻击(访问速度限制)模块;更方便的命令行参数,如列出编译的模块列表、支持的指令等;可以根据访问...

Global site tag (gtag.js) - Google Analytics