tcp压测工具_掌门全链路灰度压测实战

灰度背景

随着掌门用户数量,业务的快速迭代,服务发布出现的事故影响面越来越大,有可能是新业务流程与老业务流程的互相兼容的问题,或者是前后端一些较小的手误导致应用故障(中台受此风险的影响更大)。

在不断的挖坑填坑中,我们总结出以下的问题:

  • 影响范围不可控。一旦发布到生产,特别是一些特别重要的服务的发布,如登录、首页、组织架构、消息中心等。这些服务一旦出问题,会导致将近90%业务不可连续。

  • 发布后验证的时间节点。为了保证上线后第一时间进行生产验证,一般在非业务高峰期(半夜12点后)进行发布和回归验证。深夜发布,不仅参与发版的开发,测试和运维同学较为疲劳,而且发布过程中遇到的各种小问题导致发布完成大多在深夜2点,这个时候因为发布人员都比较疲劳,在进行线上回归验证时难以保持足够的警惕心,容易产生漏测的情况。

  • 问题反馈不易,出现生产问题后,只能通过被动的投诉来发现问题,开发人员疲于奔命,产品还要遭到差评。

灰度方案

针对以上背景,测试需要对已有的两套方案分别进行压测。综合评估,选取最优方案作为公司内部使用。

  • 方案一:Java Agent

  • 方案二:Solar(Java SDK)

Java Agent :是运行在 main方法之前的拦截器,内定的方法名是 premain ,原理是先执行 premain 方法然后再执行 main 方法。在加载java文件之前做拦截修改字节码,实现了按流量匹配灰度和按条件匹配灰度2种方式。

Java SDK:Solar运用SDK实现了基于http header传递和规则订阅的全链路发布。采用配置中心配置路由规则映射在网关过滤器中植入Header信息,路由规则传递到全链路服务中而实现。灰度路由方式主要有:多版本匹配灰度和多版本权重匹配灰度。

Java Agent:

1.按流量匹配灰度:
支持完全随机和路径随机,通过规则中设置百分比实现。如:

参数来源参数流量比
headergray30

2.按条件匹配灰度:
支持header,param,cookie,body参数来源,通过设置equals,in,notIn,range, startWith,endWith条件,配置的key,value的值。如:

参数来源参数条件条件值
headergrayin1

只要请求满足规则配置,则路由灰度机器,否则路由common 机器。
路由架构图:

f1baf64b22f59be66a6e84e7fc5f5204.png

Solar(Java SDK):

1.多版本匹配灰度
灰度和common环境分别是2个不同版本号,配置中设置某个服务路由哪个版本号,配置文件中这样配置:

{"solar-service-a":"1.0", 
"solar-service-b":"1.1"}

2.多版本权重匹配灰度  
配置中设置不同版本的权重(流量比例),配置文件中这样配置:

{"solar-service-a":"1.0=90;1.1=10", "solar-service-b":"1.0=90;1.1=10"}

按服务指定版本号和权重路由对应权重到版本号。
路由架构图:

9bb15b702bafb51510dafecf5123bbf9.png

业务拓扑图

公司业务复杂度请参考下图,这是内部某业务的局部拓补图:

cadae322aefaf7000d5f07a1c048e12c.png

由于业务调用链的复杂性,为了尽可能覆盖生产场景,又要做到不冗余。测试设计选用了1个网关+2个微服务的策略进行压测,详情见下文。

压测策略

1.压测阶段:集成测试-系统测试-验收测试-回归测试-性能测试
2.压测方法:逻辑覆盖法、基本路径测试法,场景法等
3.压测机器:所有实例选用阿里云独享型机器(1个网关+2个微服务)

多核独享CPUMemoryEnvironment个数(台)
压测机4C8GUAT1
网关8C16GUAT1
微服务A4C8GUAT3
微服务B4C8GUAT4

4.压测分类:spring cloud原生,加包无灰度,加包有灰度
5.压测链路:网关-A-B,A-B
6.压测规则:为了保持2个方案条件一致性,统一选用权重30%的灰度流量作为规则
7.压测工具:
不是大家喜闻乐见的jMeter而是wrk。由于wrk具有一个良好的特性:很少的线程能够压出很大的并发量
以下是jmeter与wrk的实现原理的对比:

28a880a359909fda1899af4dab60947a.png

-------------------------------------------------------------------------------------------------------

5fa17eae8cb581e9263d6cbad6f38a25.png

其次,在同等压力下,wrk占用的资源远远小于jMeter,故本次压测中我们采用了wrk
简单介绍一下wrk的用法:
wrk配合lua脚本使用,属于命令行工具。命令格式:./wrk -c1 -t1 -d10m -T8s -s ./scripts/wrk.lua --latency "http://10.25.174.21:8080"

参数解析:

1-c  --connections(连接数)
2-d  --duration(测试持续时间)
3-t  --threads(线程)
4-s  --script(脚本)
5--lantency (响应信息。包括平均值, 标准偏差, 最大值等)

8.压测参数:

-c =1000, -t=16, -d =3m

9.压测脚本:

 1local getq = "/gray-demo-a/go?name=a"
2function request()
3    req = wrk.format("GET",getq)
4    return req
5end
6function done (summary, latency, requests)
7    local durations=summary.duration / 1000000    
8    local errors=summary.errors.status            
9    local requests=summary.requests             
10    local valid=requests-errors                 
11    io.write("Durations:       "..string.format("%.2f",durations).."s".."\n")
12    io.write("Requests:        "..summary.requests.."\n")
13    io.write("Avg RT:          "..string.format("%.2f",latency.mean / 1000).."ms".."\n")
14    io.write("Max RT:          "..(latency.max / 1000).."ms".."\n")
15    io.write("Min RT:          "..(latency.min / 1000).."ms".."\n")
16    io.write("Error requests:  "..errors.."\n")
17    io.write("Valid requests:  "..valid.."\n")
18    io.write("QPS:             "..string.format("%.2f",valid / durations).."\n")
19    io.write("--------------------------\n")
20End

10.压测返回:为了避免处理复杂的逻辑,设计只返回一行简单的字符串

压测数据统计

压测QPSG-A-BA(1台)-B
spring cloud原生54347850
agent无灰度52237652
agent有灰度49576174
无灰度性能下降百分比(和spring cloud 原生比较)-3.88%-2.52%
有灰度性能下降百分比(和spring cloud 原生比较)-8.77%-21.35%
---------------
spring cloud 原生62445529
solar无灰度61205100
solar有灰度58304600
无灰度性能下降百分比(和spring cloud 原生比较)-1.98%-7.75%
有灰度性能下降百分比(和spring cloud 原生比较)-6.63%-16.80%

故障分析

测试过程中发现,同样的脚本,同样的场景,同样的参数在不同时间点,timeout个数较多,QPS波动较大,且qps较低,始终达不到预期。根据问题采取如下措施逐步得以解决(以原生为例):

  1. 分别在源和目标主机同时抓包:tcpdump -i any host x.x.x.x -w /x/x.pcap,分析比较有没有丢包。发现target没有响应SYN,想到查看TCP accept queue是否满了

    43cd7ced50f57d759800f6fd3ad772ef.png

  2. 查看接收端的系统日志/var/log/message有没有报错,结果并未有error信息

  3. 使用命令:netstat -s | egrep "listen|LISTEN",果然,有大量连接溢出126a305abe60bc40dbf8a4c66cc2e118.png

  4. 查看网关cat /proc/sys/net/ipv4/tcp_max_syn_backlogf7227f3a973086e932a5b4d3e8422fd8.png

  5. 查看网关cat /proc/sys/net/core/somaxconn,发现somaxconn和max_syn_backlog两个值较小,需要调整a202810f1896e2afca96dd60c7d97563.png

  6. 登录网关调整参数,步骤:

1、vi /etc/sysctl.conf2、调整如下2个参数值:
   net.core.somaxconn=128 调整为1280
   net.ipv4.tcp_max_syn_backlog=1024 调整为102403、生效
   sysctl -p
重新压测,发现QPS并没有明显提升。考虑可能是机器性能问题。
  1. 网关尝试换机器:
    网关实例规格由sn1(较老规格,CPU:8c)变更至 c6(新规格,CPU:8c)

    说明:

    同样核数的实例,新规格一般较停售的旧规格性能好。esc.c6具有2大优良特性:开启numa,CPU更厉害。

    换机器后QPS有部分提升但还是达不到预期。

  2. 通过grafana看板,查看tcp连接数分析到网关到微服务的有效连接数接近20,几乎等于默认值。考虑查看:zuul.host.maxTotalConnections,zuul.semaphore.max-semaphores,zuul.host.maxPerRouteConnections这三个参数的值。

    说明:

    zuul.host.maxTotalConnections

    适用于ApacheHttpClient,如果是okhttp无效。每个服务的http客户端连接池最大连接,默认是200。

    zuul.host.maxPerRouteConnections

    适用于ApacheHttpClient,如果是okhttp无效。每个route可用的最大连接数,默认值是20。

    zuul.semaphore.max-semaphores

    Hystrix 最大的并发请求

    execution.isolation.semaphore.maxConcurrentRequests,这个值并非TPS、QPS、RPS等都是相对值,指的是1秒时间窗口内的事务/查询/请求,semaphore.maxConcurrentRequests是一个绝对值,无时间窗口,相当于亚毫秒级的。当请求达到或超过该设置值后,其其余就会被拒绝。默认值是100

  3. 修改zuul的参数:

zuul.host.maxTotalConnections=20000
zuul.semaphore.max-semaphores=5000
MaxConnectionsPerHost=2000
再次压测,QPS大幅上升。
  1. 尝试将A,B各换为1台ecs.c6后,A-B QPS上升较多

    测试结果数据:

压测QPSG-BG-A-BA(1台)-B
网关:ecs.c6 1台,A:独享型3 台,B:独享型 4台901285127418
网关:ecs.c6 1台,A:ecs.c6 1台,B:ecs.c6 1台8932848611115

751a829eb987972c249a6685799f3b12.png

采取以上措施,最终timeout个数减少,所占比例不到0.1%。QPS达到9000左右,符合预期。

压测结论

性能测试过程中,CPU运行稳定,内存没有溢出现象。综合分析以上测试数据,由于solar 性能优于agent 5%左右, 未来将选用solar作为公司灰度方案,方便业务线灰度发布。

0ee119362b09f4c27a4386f6482d5f09.png

本文作者

谢璐,多年测试经历。 Github: pgxlxianjian@gmail.com, 现任职掌门1对1测试架构师,负责掌门基础架构部框架测试及组件测试。 谢庆芳,5年测试经验。 Github: Enersmill ,擅长性能测试,自动化测试。 熟悉java, python。 现任职掌门1对1测试开发工程师。 0ee119362b09f4c27a4386f6482d5f09.png 9fc9405b3c62516efec6d8915896e8d7.png f39ece3fb1c59d18059ef0176a013671.png 元旦快乐 6db4ea5e4005738d55f79d2c56bd2ded.png
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值