解Bug之路-with AI-应用被限流?
核心反常点:非高峰期只有单机被限流,表面像流量突增,实际请求是在应用短暂停顿后集中泄洪,CPU throttle、SafePoint 和宿主机 IO 指标又互相矛盾。
25 min read
核心反常点:非高峰期只有单机被限流,表面像流量突增,实际请求是在应用短暂停顿后集中泄洪,CPU throttle、SafePoint 和宿主机 IO 指标又互相矛盾。
25 min read
核心反常点:NAT 场景里的趋光性是一种自发的动力学模型,不同失败率通过表项寿命转化为选择压力,系统在没有健康感知的情况下自行完成流量迁移。
14 min read
紧接上篇<<高可用之路-闲聊监控指标的局限。上篇说到,指标只是事实的投影,由于代价的存在它无法无限的逼近真实。因此,指标自身的局限有时不仅无法帮助我们发现问题,反而可能迷惑甚至误导我们。本文将详细讨论指标局限最常见的一种表现——指标失明,即问题已经发生,指标却无法有效反映。
6 min read
笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 今天笔者就来从Linux源码的角度看下Server端的Socket在进行listen的时候到底做了哪些事情(基于Linux 3.10内核),当然由于listen的backlog参数和半连接hash表以及全连接...
5 min read
核心反常点:同应用同流量下部分机器 CPU.busy 高出 5 倍,接口 QPS、消息量和定时任务都对不上,最后发现是监控采样点位差异制造的假负载不均。
4 min read
在我和GPT探讨了很多天的人生之后,他终于说动了我,让我开启迟迟不想动笔的高可用系列。感谢GPT们让我从大量繁琐技术文档中解放出来,让我有时间进行真正的思考。写博客对我来说最大的收益是强制自己思考,如果连博客本身都被GPT代劳,那还不如不写。所以本文文字AI含量基本为0,纯手敲,顶多听取了一些AI在...
7 min read
核心反常点:一次普通 CRUD 上线后 Young GC 时间翻倍,代码改动看起来和 GC 无关,真正要解释的是对象分配/存活变化如何被版本发布放大。
4 min read
核心反常点:低流量时空闲后的第一笔请求超时,高流量反而正常,根因不是服务端处理慢,而是 NAT/LVS 空闲连接超时与客户端连接复用冲突。
5 min read
核心反常点:访问非洲服务商域名却解析到美国 IP,但非洲节点又确实收到了请求,问题不在单次 DNS 结果,而在不同地域、链路和解析视角不一致。
2 min read
核心反常点:支付成功后主子数据偶发只有一边被读到,表面像原子性破坏,实际要回到事务边界、读路径和主从/缓存时序看。
2 min read
核心反常点:同一事务里更新 A/B 后,另一个事务只读到 A 的新值却读不到 B,新旧版本混在一起,根因在普通快照读与 for update 当前读混用。
1 min read
核心反常点:凌晨低峰期连续出现 NP 异常,流量不高却集中爆发,真正共同点是运维改表动作改变了读数据的一致性假设。
3 min read
核心反常点:连接数涨到约 4.5W 后突然从高位跌到几百,并伴随大量报错,像应用雪崩,实际要从连接上限、端口/内核资源和关闭行为解释。
3 min read
核心反常点:应用节点不是同时宕掉,而是 BusyThread 从发布后持续增长直到逐台摘除,根因藏在 Guava Cache 异步加载和永远不会完成的 Future。
5 min read
核心反常点:查询服务 999 线升高后扩容反而更糟,Young GC 变慢只出现在部分机器,根因不是 JVM 容量,而是宿主机超卖和 cgroup CPU 记账造成的指标误导。
9 min read
核心反常点:应用启动后前 10 分钟正常,之后 MQ 开始固定堆积,重启又短暂恢复,关键矛盾是消费线程并非一开始失败,而是在运行一段时间后卡住。
3 min read
核心反常点:读从库时业务看起来读到了事务的一半结果,像主从复制破坏原子性,真正问题要区分从库回放顺序、隔离级别和业务观察点。
2 min read
Seconds_behind_master是我们观察主从延迟的一个重要指标。但任何指标所能表示的精度都是有限的。例如用精度只能到秒的指标去衡量毫秒级的表现就会产生非常大的误差。如果再以此误差去分析问题,就会让思维走上弯路。例如用Seconds_behind_master去评估1s内的主从延迟就是一个...
4 min read
核心反常点:不同从库看起来长期相差约 500ms 延迟,但网络并没有对应差异,真正的问题是 Seconds_behind_master 的秒级精度无法刻画毫秒级主从延迟。
4 min read
最近笔者阅读资料的时候,发现竟然会有这种坑。如下图所示: 这个坑触发需要以下几个条件: 在这种情况下,Server竟然会认为没有收到的第一个packet是确认了的,导致客户端认为第一个"dog"收到了,实际Server应用端完全没有感知! 如果第一个包3bytes的时候,在上面的情况下,由于chec...
1 min read
核心反常点:ZK Leader 宕机后剩余节点没有顺利选主,集群整体拒绝服务,异常不在单次宕机本身,而在 snapshot 耗时、initLimit 和历史数据膨胀共同放大故障。
7 min read
Linux作为一个强大的操作系统,提供了一系列内核参数供我们进行调优。光TCP的调优参数就有50多个。在和线上问题斗智斗勇的过程中,笔者积累了一些在内网环境应该进行调优的参数。在此分享出来,希望对大家有所帮助。 好了,在这里先列出调优清单。请记住,这里只是笔者在内网进行TCP内核参数调优的经验,仅供...
6 min read
我们的服务器时间校准一般是通过ntp进程去校准的。但由于校准这个动作,会导致时钟跳跃变化的现象。 而这种情况里面,往往回拨最能引起我们的困扰,回拨如下所示: 假设有一个任务每天0点时候获取昨天所有的数据进行对账,正常情况和时钟回拨的情况如下图所示: 针对这种情况,笔者让业务调整了调度触发时间,不要精...
1 min read
核心反常点:系统失去响应并伴随 Full GC 告警,看起来像 JVM 内存问题,但根因是 Redis 使用方式把应用拖进阻塞和内存压力。
3 min read
核心反常点:请求只是偶发超时且一会儿又恢复,应用层很难定位,真正异常是磁盘坏道/IO 卡顿在业务请求路径上被间歇性放大。
1 min read
在前面的文章中,笔者详细的阐述了Prometheus的数据插入存储查询等过程。但作为一个监控神器,报警计算功能是必不可少的。自然的Prometheus也提供了灵活强大的报警规则可以让我们自由去发挥。在本篇文章里,笔者就带读者去看下Prometheus内部是怎么处理报警规则的。
3 min read
核心反常点:数据库主从切换后大多数应用都切走了,个别应用连接却还留在老主库上,表面像切换失败,实际是连接生命周期和应用侧感知机制的问题。
5 min read
产线一些应用其JVM只占了8G中的2个G的空间。Page cache也只占了1个G,但是free -g出来内存确已经耗尽: 这个看上去很吓人。遇到这种情况,我们先cat /proc/meminfo看下具体的内存占用情况 我们可以看到有将近3.6G被耗尽在Slab这一项里面,紧接着下面一项SRecla...
1 min read笔者最近担起了公司监控的重任,而当前监控最流行的数据库即是Prometheus。按照笔者打破砂锅问到底的精神,自然要把这个开源组件源码搞明白才行。在经过一系列源码/资料的阅读以及各种Debug之后,对其内部机制有了一定的认识。今天,笔者就来介绍下Prometheus的存储结构。
4 min read
在之前的文章里,笔者详细的阐述了数据的存储/写入以及查询过程。那么Prometheus又是怎么去主动获得数据的呢?这个问题,笔者将在本篇文章详细阐述。 Prometheus是通过pull从各个Target(目标)Exporter中去获取数据。 作为一个成熟的监控系统,自然可以这对这些Target进行...
4 min read
在之前的博客里,笔者详细阐述了Prometheus数据的插入过程。但我们最常见的打交道的是数据的查询。Prometheus提供了强大的Promql来满足我们千变万化的查询需求。在这篇文章里面,笔者就以一个简单的Promql为例,讲述下Prometheus查询的过程。
4 min read
在之前的文章里,笔者详细的阐述了Prometheus时序数据库在内存和磁盘中的存储结构。有了前面的铺垫,笔者就可以在本篇文章阐述下数据的插入过程。 在这里,笔者并不会去讨论Promtheus向各个Endpoint抓取数据的过程。而是仅仅围绕着数据是如何插入Prometheus的过程做下阐述。对应方法...
2 min read
之前的文章里,笔者详细描述了监控数据在Prometheus内存中的结构。而其在磁盘中的存储结构,也是非常有意思的,关于这部分内容,将在本篇文章进行阐述。 首先我们来看Prometheus运行后,所形成的文件目录结构 在笔者自己的机器上的具体结构如下: 一个Block就是一个独立的小型数据库,其保存了...
4 min read
笔者最近完成了一个非常有意思的隧道机制(已在产线运行),可以让注册到不同zookeeper之间的dubbo集群之间能够正常进行通信。如下图所示: 例如图中A/B两个网络隔离的集群,两者只能通过专线进行通信。但是对于在里面的应用来说,调用另外一个集群的dubbo服务(例如app1调用app3)依旧和原...
5 min read
笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 今天笔者就从Linux源码的角度看下Server端的Socket在进行Accept的时候到底做了哪些事情(基于Linux 3.10内核)。 众所周知,一个Server端Socket的建立,需要socket、b...
5 min read
笔者一直以为在Linux下TIME_WAIT状态的Socket持续状态是60s左右。线上实际却存在TIME_WAIT超过100s的Socket。由于这牵涉到最近出现的一个复杂Bug的分析。所以,笔者就去Linux源码里面,一探究竟。 TIME_WAIT这个参数通常和五元组重用扯上关系。在这里,笔者先...
6 min read
核心反常点:应用以为每次 read 都能拿到完整业务包,线上却随机出现解析错乱,本质是把 TCP 流误当消息边界,粘包/拆包后触发协议解析异常。
7 min read
笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 今天笔者就来从Linux源码的角度看下Server端的Socket在进行bind的时候到底做了哪些事情(基于Linux 3.10内核)。 众所周知,一个Server端Socket的建立,需要socket、bi...
6 min read
核心反常点:数百万请求里只有少量超过 1s,GC、网络和业务日志都不像根因,最后靠日志规律发现慢请求和宿主机上的 Redis 活动存在隐蔽关联。
5 min read
DPVS是一款爱奇艺开源的基于DPDK的优秀软件(https://github.com/iqiyi/dpvs)。利用DPDK工作在用户空间的特性,相比于内核空间的LVS,我们可以使用用户空间的一系列工具/中间件等完成很多在内核空间很难完成的功能。 虽然笔者日常工作中是搞Java中间件开发的,但一直都...
4 min read
核心反常点:后端应用压测无压力,但经过 Nginx 就 502 且 Nginx CPU 接近 100%,真正瓶颈不是业务处理能力,而是单 upstream 地址端口耗尽与 TIME_WAIT。
6 min read
核心反常点:同一条 SQL 看起来被中间件重复执行,数据库日志和中间件日志互相打架,根因藏在多节点返回、引用计数和一个为排查打开的日志/缓存开关里。
5 min read
笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。上篇博客讲了socket的阻塞和非阻塞,这篇就开始谈一谈socket的close(以tcp为例,且基于linux-2.6.24内核版本) 众所周知,TCP的close过程是四次挥手,状态机的变迁也逃不出TCP状...
7 min read
核心反常点:调用外网服务只是概率性失败,应用逻辑和服务端都不像有问题,真正异常藏在基础网络环境、路由/出口与联调链路的差异里。
6 min read
当今互联网中的大千世界都驻足于TCP/IP协议之上。而通过Socket操作TCP/IP协议已经成为了事实上的标准,Socket甚至已经成为了网络编程的同义词。当然了,由于我们早已习惯于各种封装/框架,很少裸用Socket,所以对它的理解始终有一种模糊的感觉。 今天,我就来介绍一下Socket。
2 min read
核心反常点:业务请求偶发超时却很难联想到硬件,应用层现象稀奇古怪,最终指向存储硬件故障在分库分表链路中的间歇性放大。
4 min read
在阅读了大量关于数据库的资料后,笔者情不自禁产生了一个造数据库轮子的想法。来验证一下自己对于数据库底层原理的掌握是否牢靠。在笔者的github中给这个database起名为Freedom。 既然造轮子,那当然得从前端的网络协议交互到后端的文件存储全部给撸一遍。下面是Freedom实现的整体结构,里面...
6 min read
核心反常点:网络恢复后 Dubbo 应用没有自动重连 Zookeeper,只能靠重启恢复,根因不是注册中心单点异常,而是低版本 ZK 客户端、session 过期和 DNS 缓存共同触发。
6 min read
新冠疫情让笔者不禁回忆起10多年前甲流流行的那段过往。也就是那时,在封闭的大学宿舍里,笔者开启了自己的编程之旅。 初涉编程时那个C语言展示hello world的黑框并没有激起笔者的任何兴趣。为什么寥寥几句就可在屏幕上展示输出成为萦绕笔者心头的一个疑问。在全校封闭、无法组团dota、百无聊赖的境遇下...
5 min read网络编程中超时时间是一个重要但又容易被忽略的问题,对其的设置需要仔细斟酌。在经历了数次物理机宕机之后,笔者详细的考察了在网络编程(tcp)中的各种超时设置,于是就有了本篇博文。本文大部分讨论的是socket设置为block的情况,即setNonblock(false),仅在最后提及了nonblock...
8 min read
在linux的高性能网络编程中,绕不开的就是epoll。和select、poll等系统调用相比,epoll在需要监视大量文件描述符并且其中只有少数活跃的时候,表现出无可比拟的优势。epoll能让内核记住所关注的描述符,并在对应的描述符事件就绪的时候,在epoll的就绪链表中添加这些就绪元素,并唤醒对...
8 min read
核心反常点:应用每次发布后只有第一笔请求超时,后续全部正常,表面影响很小,实际暴露的是连接刚建立但还不可用、listen backlog 与 TCP 握手队列之间的时序问题。
9 min read
MySQL是当今最流行的开源数据库,阅读其源码是一件大有裨益的事情(虽然其代码感觉比较凌乱)。而笔者阅读一个Server源码的习惯就是先从其网络IO模型看起。于是,便有了本篇博客。 看源码,首先就需要找到其入口点,mysqld的入口点为mysqld_main,跳过了各种配置文件的加载
3 min read
分库分表中间件在我们一年多的锤炼下,基本解决了可用性和高性能的问题(只能说基本,肯定还有隐藏的坑要填),问题自然而然的就聚焦于高可用。本文就阐述了我们在这方面做出的一些工作。 作为一个无状态的中间件,高可用问题并没有那么困难。但是尽量减少不可用期间的流量损失,还是需要一定的工作的。这些流量损失主要分...
7 min read
笔者在阅读了一大堆源码后,就会情不自禁产生造轮子的想法。于是花了数个周末的时间用C语言撸了一个DBProxy(MySQL协议)。在笔者的github中给这个DBProxy起名为Hero。 笔者一直有C情节,求学时候一直玩C。工作之后,一直使用Java,就把C渐渐放下了。在笔者最近一年阅读了一堆关于l...
7 min read
核心反常点:慢 SQL 是主键查询/更新且只偶发几条,数据库本身并不慢,真正卡点在分库分表中间件 reactor 线程被字符串处理拖住。
7 min read
核心反常点:对端机器宕机后同一类调用有的 821s 后 reset,有的 900s 后 timeout,异常时间并不随机,而是 TCP 重传、soTimeout 和内核恢复窗口共同决定。
7 min read
作为一个数据库爱好者,自己动手写过简单的SQL解析器以及存储引擎,但感觉还是不够过瘾。<<事务处理-概念与技术诚然讲的非常透彻,但只能提纲挈领,不能让你玩转某个真正的数据库。感谢cmake,能够让我在mac上用xcode去debug MySQL,从而能去领略它的各种实现细节。
5 min read
核心反常点:容器迁移后物理内存持续异常但堆内看不出同等增长,真正泄漏在堆外,需要从堆内对象线索反推并用物理内存模型定量闭环。
6 min read
此篇博客主要是讲述MySql(仅限innodb)的两阶段加锁(2PL)协议,而非两阶段提交(2PC)协议,区别如下: MySql本身针对性能,还有一个MVCC(多版本控制)控制,本文不考虑此种技术,仅仅考虑MySql本身的加锁协议。 在对记录更新操作或者(select for update、lock...
3 min read
核心反常点:应用网络 IO 异常看起来像业务协议问题,最后落到低版本 Druid 的已修复 Bug,说明基础组件版本差异也可能制造线上假象。
4 min read
核心反常点:Redis 被大量 hget/hset 拖垮后业务出现串包式异常,表面是数据错乱,实质仍是网络读写边界和协议解析假设被打破。
4 min read
核心反常点:业务把 TCP 当成一问一答的包协议使用,低流量时正常,高并发或长连接场景下就会暴露粘包/拆包导致的随机解析问题。
7 min read
笔者觉得Cobar之类的分库分表最神奇的部分就是靠一条sql查询不同schema下(甚至不同实例下)的不同的表。例如 以笔者这种刨根到底的性格当然要把这个过程DIY出来。 由于Cobar对MySql的连接是BIO的。而笔者喜欢NIO,于是用NIO将Corbar的多节点查询全部重写(基于Netty)。...
2 min read
本篇Blog在总体层面介绍了SQL查询引擎Rider的功能及设计,其细节部分将会在后面的篇章中一一道来。 笔者在实际工作中经常需要解析文件,每次文件稍有变化,都得拷贝粘贴一堆代码。 于是就想着能不能做一个通用的服务,通过配置的方式解析文件。 最通用的方法就是自己定义一个文件描述语言,用语言去描述文件...
2 min read
在开发过程中,由于频繁的修改数据库的字段,导致rd和qa环境的数据库表经常不一致。 而由于这些修改数据库的操作可能由多个rd操作,很难一次性收集全。人手工去和QA环境对字段又特别繁琐,容易遗漏。 于是笔者就写了一个能够自动比较两个数据库的表结构,并生成alter语句的程序。同时还可以进行配置从而自动...
1 min read
MyBatis能够通过获取MySql中的information_schema从而获取表的字段等信息,最后通过这些信息生成代码。 笔者受此启发,将MyBatis-Generator中的核心结构体剥离出来,写成了能自动生成简单CRUD的工具。 mysql本身存在一个information_schema,...
1 min read
紧接上篇流程篇,本篇主要将binlog的event报文。 event报文主要分三层。 (1)MySql报文都有的length-body防粘包结构。 (2)Event Header (2)Event Body 总体结构如下图所示: Event Header结构如下图所示:
1 min read
MySql-Binlog在MySql主从不同方面发挥着不可或缺的作用,同时我们也能通过Binlog实时监控数据的变化。本系列就讲述了怎样接收并解析Binlog。本篇就主要对接收binlog的流程做了一下探讨。 流程如下图所示: (1)第一步和上篇blog一样,通过HandShake协议进行Clien...
1 min read
MySql事务协议主要是通过set autocommit、commit以及rollback这三个报文(命令)来实现的。 autocommit,顾名思义,是否自动提交(事务)。如果设置为1,表明自动提交,设置为0,则是非自动提交,这样就隐式的开启了事务。 值得注意的是,一但运行了set autocom...
1 min read
一般对DB的CRUD操作都由com_query报文封装并发送给DB。com_query报文如下图所示: PacketLength:3byte表示body长度,防"粘包"。 sequenceId:1byte防串包。 body部分:是一个以0x00结尾的字符串,这个字符串就是想要执行的SQL,实际操作中...
2 min read
各位有没有对Cobar、MyCat这些MySqlProxy感到新奇。反正笔者在遇到这些proxy时,感受到其对代码的无侵入兴感到大为惊奇。于是走上了研究MySql协议的不归路。现在我就在博客里面将其中所得分享出来,以飨大家。 下图是笔者整理的HandShake协议交互流程
3 min read