plantegg-10+倍性能提升全过程–优酷账号绑定淘宝账号的TPS从500到5400的优化历程

原文地址:https://plantegg.github.io/2018/01/23/10+%E5%80%8D%E6%80%A7%E8%83%BD%E6%8F%90%E5%8D%87%E5%85%A8%E8%BF%87%E7%A8%8B/

背景说明

2016年的双11在淘宝上买买买的时候,天猫和优酷土豆一起做了联合促销,在天猫双11当天购物满XXX元就赠送优酷会员,这个过程需要用户在优酷侧绑定淘宝账号(登录优酷、提供淘宝账号,优酷调用淘宝API实现两个账号绑定)和赠送会员并让会员权益生效(看收费影片、免广告等等)

这里涉及到优酷的两个部门:Passport(在上海,负责登录、绑定账号,下文中的优化过程主要是Passport部分);会员(在北京,负责赠送会员,保证权益生效)

在双11活动之前,Passport的绑定账号功能一直在运行,只是没有碰到过大促销带来的挑战

整个过程分为两大块:

  • 整个系统级别,包括网络和依赖服务的性能等,多从整个系统视角分析问题;
  • 但服务器内部的优化过程,将CPU从si/sy围赶us,然后在us从代码级别一举全歼。

系统级别都是最容易被忽视但是成效最明显的,代码层面都是很细致的力气活。

整个过程都是在对业务和架构不是非常了解的情况下做出的。

会员部分的架构改造

  • 接入中间件DRDS,让优酷的数据库支持拆分,分解MySQL压力
  • 接入中间件vipserver来支持负载均衡
  • 接入集团DRC来保障数据的高可用
  • 对业务进行改造支持Amazon的全链路压测

主要的压测过程

在这里插入图片描述
上图是压测过程中主要的阶段中问题和改进,主要的问题和优化过程如下:

- docker bridge网络性能问题和网络中断si不均衡    (优化后:500->1000TPS)
- 短连接导致的local port不够                   (优化后:1000-3000TPS)
- 生产环境snat单核导致的网络延时增大             (优化后生产环境能达到测试环境的3000TPS)
- Spring MVC Path带来的过高的CPU消耗           (优化后:3000->4200TPS)
- 其他业务代码的优化(比如异常、agent等)          (优化后:4200->5400TPS)

优化过程中碰到的比如淘宝api调用次数限流等一些业务原因就不列出来了

概述

由于用户进来后先要登录并且绑定账号,实际压力先到Passport部分,在这个过程中最开始单机TPS只能到500,经过N轮优化后基本能达到5400 TPS,下面主要是阐述这个优化过程

Passport部分的压力

Passport 核心服务分两个:

  • Login 主要处理登录请求
  • userservice 处理登录后的业务逻辑,比如将优酷账号和淘宝账号绑定

为了更好地利用资源每台物理加上部署三个docker 容器,跑在不同的端口上(8081、8082、8083),通过bridge网络来互相通讯

Passport机器大致结构

在这里插入图片描述

userservice服务网络相关的各种问题

太多SocketConnect异常(如上图)
在userservice机器上通过netstat也能看到大量的SYN_SENT状态,如下图:
在这里插入图片描述

因为docker bridge通过nat来实现,尝试去掉docker,让tomcat直接跑在物理机上
这时SocketConnect异常不再出现
在这里插入图片描述

从新梳理一下网络流程

docker(bridge)—-短连接—>访问淘宝API(淘宝open api只能短连接访问),性能差,cpu都花在si上;

如果 docker(bridge)—-长连接到宿主机的某个代理上(比如haproxy)—–短连接—>访问淘宝API, 性能就能好一点。问题可能是短连接放大了Docker bridge网络的性能损耗

当时看到的cpu si非常高,截图如下:
在这里插入图片描述
去掉Docker后,性能有所提升,继续通过perf top看到内核态寻找可用的Local Port消耗了比较多的CPU,gif动态截图如下(可以点击看高清大图):
在这里插入图片描述

注意图中ipv6_rcv_saddr_equal和inet_csk_get_port 总共占了30%的CPU (系统态的CPU使用率高意味着共享资源有竞争或者I/O设备之间有大量的交互。)

一般来说一台机器默认配置的可用 Local Port 3万多个,如果是短连接的话,一个连接释放后默认需要60秒回收,30000/60 =500 这是大概的理论TPS值【这里只考虑连同一个server IP:port 的时候】

这500的tps算是一个老中医的经验。不过有些系统调整过Local Port取值范围,比如从1024到65534,那么这个tps上限就是1000附近。

同时观察这个时候CPU的主要花在sy上,最理想肯定是希望CPU主要用在us上,截图如下:
在这里插入图片描述
规则:性能优化要先把CPU从SI、SY上的消耗赶到US上去(通过架构、系统配置);然后提升 US CPU的效率(代码级别的优化)

sy占用了30-50%的CPU,这太不科学了,同时通过 netstat 分析连接状态,确实看到很多TIME_WAIT:
在这里插入图片描述
cpu要花在us上,这部分才是我们代码吃掉的

于是让PE修改了tcp相关参数:降低 tcp_max_tw_buckets和开启tcp_tw_reuse,这个时候TPS能从1000提升到3000

鼓掌,赶紧休息,迎接双11啊
在这里插入图片描述

测试环境优化到3000 TPS后上线继续压测

居然性能又回到了500,太沮丧了,其实最开始账号绑定慢,Passport这边就怀疑taobao api是不是在大压力下不稳定,一般都是认为自己没问题,有问题的一定是对方。我不觉得这有什么问题,要是知道自己有什么问题不早就优化掉了,但是这里缺乏证据支撑,也就是如果你觉得自己没有问题或者问题在对方,一定要拿出证据来(有证据那么大家可以就证据来讨论,而不是互相苍白地推诿)。

这个时候Passport更加理直气壮啊,好不容易在测试环境优化到3000,怎么一调taobao api就掉到500呢,这么点压力你们就扛不住啊。 但是taobao api那边给出调用数据都是1ms以内就返回了(alimonitor监控图表–拿证据说话)。

看到alimonitor给出的api响应时间图表后,我开始怀疑从优酷的机器到淘宝的机器中间链路上有瓶颈,但是需要设计方案来证明这个问题在链路上,要不各个环节都会认为自己没有问题的,问题就会卡死。但是当时Passport的开发也只能拿到Login和Userservice这两组机器的权限,中间的负载均衡、交换机都没有权限接触到。

在没有证据的情况下,肯定机房、PE配合你排查的欲望基本是没有的(被坑过很多回啊,你说我的问题,结果几天配合排查下来发现还是你程序的问题,凭什么我要每次都陪你玩?),所以我要给出证明问题出现在网络链路上,然后拿着这个证据跟网络的同学一起排查。

讲到这里我禁不住要插一句,在出现问题的时候,都认为自己没有问题这是正常反应,毕竟程序是看不见的,好多意料之外逻辑考虑不周全也是常见的,出现问题按照自己的逻辑自查的时候还是没有跳出之前的逻辑所以发现不了问题。但是好的程序员在问题的前面会尝试用各种手段去证明问题在哪里,而不是复读机一样我的逻辑是这样的,不可能出问题的。即使目的是证明问题在对方,只要能给出明确的证据都是负责任的,拿着证据才能理直气壮地说自己没有问题和干净地甩锅。

在尝试过tcpdump抓包、ping等各种手段分析后,设计了场景证明问题在中间链路上。

设计如下三个场景证明问题在中间链路上:

  1. 压测的时候在userservice ping 依赖服务的机器;
  2. 将一台userservice机器从负载均衡上拿下来(没有压力),ping 依赖服务的机器;
  3. 从公网上非我们机房的机器 ping 依赖服务的机器;

这个时候奇怪的事情发现了,压力一上来场景1、2的两台机器ping淘宝的rt都从30ms上升到100-150ms,场景1 的rt上升可以理解,但是场景2的rt上升不应该,同时场景3中ping淘宝在压力测试的情况下rt一直很稳定(说明压力下淘宝的机器没有问题),到此确认问题在优酷到淘宝机房的链路上有瓶颈,而且问题在优酷机房出口扛不住这么大的压力。于是从上海Passport的团队找到北京Passport的PE团队,确认在优酷调用taobao api的出口上使用了snat,PE到snat机器上看到snat只能使用单核,而且对应的核早就100%的CPU了,因为之前一直没有这么大的压力所以这个问题一直存在只是没有被发现。

于是PE去掉snat,再压的话 TPS稳定在3000左右

到这里结束了吗? 从3000到5400TPS

优化到3000TPS的整个过程没有修改业务代码,只是通过修改系统配置、结构非常有效地把TPS提升了6倍,对于优化来说这个过程是最轻松,性价比也是非常高的。实际到这个时候也临近双11封网了,最终通过计算(机器数量*单机TPS)完全可以抗住双11的压力,所以最终双11运行的版本就是这样的。 但是有工匠精神的工程师是不会轻易放过这么好的优化场景和环境的(基线、机器、代码、工具都具备配套好了)

优化完环境问题后,3000TPS能把CPU US跑上去,于是再对业务代码进行优化也是可行的了。

进一步挖掘代码中的优化空间

双11前的这段封网其实是比较无聊的,于是和Passport的开发同学们一起挖掘代码中的可以优化的部分。这个过程中使用到的主要工具是这三个:火焰图、perf、perf-map-java。相关链接:

  • http://www.brendangregg.com/perf.html
  • https://github.com/jrudolph/perf-map-agent

通过Perf发现的一个SpringMVC 的性能问题

这个问题具体参考我之前发表的优化文章。 主要是通过火焰图发现spring mapping path消耗了过多CPU的性能问题,CPU热点都在methodMapping相关部分,于是修改代码去掉spring中的methodMapping解析后性能提升了40%,TPS能从3000提升到4200.

著名的fillInStackTrace导致的性能问题

代码中的第二个问题是我们程序中很多异常(fillInStackTrace),实际业务上没有这么多错误,应该是一些不重要的异常,不会影响结果,但是异常频率很高,对这种我们可以找到触发的地方,catch住,然后不要抛出去(也就是别触发fillInStackTrace),打印一行error日志就行,这块也能省出10%的CPU,对应到TPS也有几百的提升。
在这里插入图片描述
部分触发fillInStackTrace的场景和具体代码行(点击看高清大图):
在这里插入图片描述
对应的火焰图(点击看高清大图):
在这里插入图片描述
在这里插入图片描述

解析useragent 代码部分的性能问题

整个useragent调用堆栈和cpu占用情况,做了个汇总(useragent不启用TPS能从4700提升到5400)
在这里插入图片描述
实际火焰图中比较分散:
在这里插入图片描述

最终通过对代码的优化勉勉强强将TPS从3000提升到了5400(太不容易了,改代码过程太辛苦,不如改配置来得快)

优化代码后压测tps可以跑到5400,截图:
在这里插入图片描述

最后再次总结整个压测过程的问题和优化历程

- docker bridge网络性能问题和网络中断si不均衡    (优化后:500->1000TPS)
- 短连接导致的local port不够                   (优化后:1000-3000TPS)
- 生产环境snat单核导致的网络延时增大             (优化后能达到测试环境的3000TPS)
- Spring MVC Path带来的过高的CPU消耗           (优化后:3000->4200TPS)
- 其他业务代码的优化(比如异常、agent等)         (优化后:4200->5400TPS)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/775731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是生态智慧公厕@光明源

生态智慧公厕是一种结合生态环保理念和智能科技的公厕设施。这种公厕旨在提供更加环保、节能、可持续的卫生解决方案,同时通过智能化技术提升管理效率和用户体验。生态智慧公厕通常具有以下特点: 节能环保:生态智慧公厕采用了各种节能环保技…

npm淘宝镜像源更新

目录 前情提要: 背景: 镜像源更新: 清楚缓存: 直接切换镜像源: 补充: 错误解释: 解决方法: 前情提要: 2024 /1 /22 ,registry.npm.taobao.org淘宝镜像源的SSL…

【面试】Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?

Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法? Elasticsearch是一个分布式搜索和分析引擎,它在Linux环境下的性能和稳定性可以通过一些优化方法进行提升。以下是一些针对Linux环境下Elasticsearch部署的优化方法: 1. 内…

【2024系统架构设计】案例分析- 3 数据库

目录 一 基础知识 二 真题 一 基础知识 1 ORM ORM(Object—Relationl Mapping

Java学习笔记(22)

缓冲流 真正操作数据的还是基本流 字节缓冲流 缓冲区是长度为8192的字节缓冲区 byte[] 8K Bufferedininputstream 读取数据就是把数据放到缓冲区中,字节长度默认长度8192 关流只需要关缓冲流,因为在底层会关基本流 一次读多个字节 字节缓冲流提高效…

XR虚拟直播间,引领创新风潮,打破直播局限!

随着互联网技术日新月异的发展,直播行业也迎来了蓬勃发展的春天。然而,大多数直播间在吸引观众眼球和延长用户观看时长方面,仍然面临着巨大的挑战。正是在这样的背景下,XR虚拟直播系统应运而生,以其多维度的直播场景、…

自然语言处理3(NLP)—— 机器学习

1. 自然语言处理在机器学习领域的主要任务 自然语言处理(NLP)在机器学习领域中扮演着至关重要的角色,旨在使计算机能够理解、解释和生成人类语言。以下是NLP在机器学习领域中的主要任务及其分类方法: 1.1 按照功能类型分类 1.1.…

Nacos的搭建和使用——SpringCloud Alibaba

1. 概要说明 在使用Nacos之前,请在你的虚拟机中下载好Nacos,再进行连接本机使用 port:8848 本机访问地址:http://{虚拟机ip}:8848/nacos/ 访问账号密码:nacos/nacos 2. Nacos的作用 2.1 服务发现中心 微服务将自身注册至Nacos&am…

Netty服务端基本启动流程源码刨析

前言: 希望看这篇文章之前对Java Nio编程比较熟悉,并有用过Netty开发简单代码 服务端代码 先大致说一下NioEventLoopGroup组件的作用,可以把它看是作内部维护了一个NioEventLoop数组的对象,它的构造方法的参数用来指定维护数组的大小。NioEve…

【Flutter 面试题】 Dart 是不是单线程模型?是如何运行的?

【Flutter 面试题】 Dart 是不是单线程模型?是如何运行的? 文章目录 写在前面口述回答补充说明示例:异步编程示例:使用 Isolates 处理计算密集型任务总结 写在前面 🙋 关于我 ,小雨青年 👉 CSD…

Echarts之x轴,Y轴配置项大全

ECharts是一个强大的数据可视化库,提供了丰富的配置项来定制图表的x轴和y轴。下面是ECharts中x轴和y轴的配置项大全: xAxis配置项: type:轴类型,可选值有:“value”(数值轴), “cat…

docker 的网络管理

docker应用自带了三种类型的网络,然后我们自己也能自定义网络 roottest-virtual-machine:~# docker network ls NETWORK ID NAME DRIVER SCOPE 4c3e28760cff bridge bridge local afd1493dc119 host host local 5f200e2eaf22 n…

政安晨:【Keras机器学习实践要点】(六)—— 使用内置方法进行训练和评估

政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 本文涵盖使用内置 API 进行训练和验证&#…

01-DBA自学课-安装部署MySQL

一、安装包下载 1,登录官网 MySQL :: MySQL Downloads 2,点击社区版下载 3,找到社区服务版 4,点击“档案”Archives 就是找到历史版本; 5,选择版本进行下载 本次学习,我们使用MySQL-8.0.26版本…

机器学习 | 期望最大化(EM)算法介绍和实现

在现实世界的机器学习应用中,通常有许多相关的特征,但只有其中的一个子集是可观察的。当处理有时可观察而有时不可观察的变量时,确实可以利用该变量可见或可观察的实例,以便学习和预测不可观察的实例。这种方法通常被称为处理缺失…

vue2高德地图选点

<template><el-dialog :title"!dataForm.id ? 新建 : isDetail ? 详情 : 编辑" :close-on-click-modal"false" :visible.sync"show" class"rv-dialog rv-dialog_center" lock-scroll width"74%" :before-close&q…

Vue.js概述

一、概述 数据驱动的响应式框架&#xff0c;我们只关注Vue对象里面设置的数据即可&#xff0c;数据发生改变时&#xff0c;页面自动重新渲染 最典型的MVVM框架 二、挂载点 什么是“挂载点”&#xff1f;一个标签 作用&#xff1a;被Vue实例接收后&#xff0c;实例中设置的各…

boot整合xfire

最近换了项目组&#xff0c;框架使用的boot整合的xfire&#xff0c;之前没使用过xfire&#xff0c;所以写个例子记录下&#xff0c;看 前辈的帖子 整理下 pom文件 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot…

Python爬虫入门:从网站爬取文章内容并保存到本地文件

目录 前言 准备工作 简单爬虫实现 注意事项 爬虫伦理与合法性 总结 前言 在互联网时代&#xff0c;数据是宝贵的资源。然而&#xff0c;当需要从海量网站中抓取数据时&#xff0c;手动操作显然不切实际。这时&#xff0c;爬虫技术应运而生&#xff0c;成为我们获取数据的…

OSG编程指南<二十一>:OSG视图与相机视点更新设置及OSG宽屏变形

1、概述 什么是视图?在《OpenGL 编程指南》中有下面的比喻,从笔者开始学习图形学就影响深刻,相信对读者学习场景管理也会非常有帮助。 产生目标场景视图的变换过程类似于用相机进行拍照,主要有如下的步骤: (1)把照相机固定在三脚架上,让它对准场景(视图变换)。 (2)…