项目DinosaurStore3

一些调优

关于Kubernets运营部署

Ubuntu 下安装 kubectl, kubelet, kubeadm

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo su
apt update && apt install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

apt update

apt install -y kubelet kubeadm kubectl # 教程中装的都是1.17.3

systemctl enable kubelet
systemctl start kubelet



# master节点
kubeadm init \
--apiserver-advertise-address=124.222.48.192 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version v1.24.3 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16

抓包调试问题

JVM调优问题

压力测试的一些优化

ScreenShot2022-09-01at22.20.24

尝试压力测试秒杀

后台上架秒杀商品

上架的时候也是周期性上架的,首先从coupon远程调用拿到优惠的商品,然后秒杀服务器进行商品上架,上架的时候看redis中有没有这个key,没有才上架。上架需要加分布式锁,防止两个秒杀为服务同时上架。

秒杀根据当前场次-该商品的sku来进行查询,点击商品后进入商品详情,然后远程调用coupon查询该商品是不是秒杀商品,然后判断时间是不是符合。

所以点击商品,进入详情的时候,查询商品的库存,查询商品的图片,查询商品的其他类别的物品,还有查询商品是否是秒杀商品,这都是需要异步实现的,用到线程池的。

上架秒杀商品的时候我之前是判断有key删除重新添加,但是这样会出问题,有key就不添加了呗。

不知道为啥,只有我这个启动的服务器上架了商品,那么redission才能tryacquire获取成功,不然的话会超时异常。(就是上架完成后,不重启服务,重启微服务貌似就没用了。)

首先批量注册用户

先postman测试接口

取消注册时候的验证码输入,以及redis里面的验证码校验功能。

也去除了后台,对输入数据的校验。

但是注意,注册的手机号码和用户名字还得是唯一的。

1
POST:     http://auth.dinosaurstore.com:20000/register ,然后body内容如下:

ScreenShot2022-09-02at11.59.58

postman测试秒杀接口

上面上架商品的时候,才会给该商品出来一个code,才能根据这个链接进行秒杀,存在了redis中(key是场次-skuid)。

1
GET:      http://seckill.dinosaurstore.com/kill?killId=14&key=92c1cfe5d580498a9cd7a2dd539036c2&num=1

如果只是这么写,在秒杀微服务的 拦截器里面会拦截未登录,需要先登陆。

但是其实拦截器里面,是从当前服务器的浏览器给出的cookie的token中拿到的session,从里面看有没有用户,所以说用户确实要先登陆,而不是我直接url中传入用户的token就行了(这样的前提应该要每个用户先登陆一遍吧?)。所以直接还是拦截器里面将登陆用户判断删除,测试秒杀。

所以测试秒杀,我关了拦截器,然后里面用户占位,setnx+ex的时候用户的key改为随机生成一串字符串。然后rabbitmq这一串消息发送,但是不开启相应的微服务接受了,我只是只是测试redis的信号量这一边即可,看看瞬间的压力测试能有多少。

ScreenShot2022-09-04at14.15.27

jemeter压测

009–【秒杀】进行秒杀压测

其实不只是JVM优化的测试

超卖问题,测试没有问题。商品100,用1000个线程。

一人一订单问题,由于没有放用户,没有测量。

首先上架,然后删除redis中所有的秒杀,然后开启服务器让他上架商品缓存到redis中去,然后找到我要的那个场次-商品对应的code,放入url中去,然后进行压测。

分布式用的是信号量:

1
2
3
4
5
// 这样就好了,下面那个网redis里面放入count-1的根本不需要好嘛
RSemaphore semaphore = redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE + randomCode);
//TODO 秒杀成功,快速下单
// 此处不能阻塞
boolean semaphoreCount = semaphore.tryAcquire(num, 100, TimeUnit.MILLISECONDS);

然后测试:100个线程进入,会有大概6个左右抢不到,也就是信号量会从100到94左右。

接下去进行狠狠的压测,首先先限制一下堆内存好了,到时候再JVM调节新生代老年代大小等等

步骤:

上架

删除redis中的缓存秒杀商品

开启秒杀微服务

在redis中找到我要秒杀的场次-商品的code,放到url中,然后配置好

使用阶梯测试法:

安装插件 JMeter阶梯式加压测试插件-Stepping Thread Group解析

4-8(九)Jmeter性能测试之阶梯式场景(负载测试)、波浪式场景(压力测试)

性能测试—如何确定最大并发用户数

现象:

在-Xmx和-Xms堆大小在100M的情况下,老年新生代的比例(默认说是2:1,我没有调),老年代67M,在大量并发秒杀的时候不怎么变的,就是eden大概两秒会满一次进行GC,GC了之后S0和S1会互换,S1和S0其实占用挺少的,不到1M,而且感觉秒杀的时候主要就是eden区增加变快了,其他两个区域没有影响。

在1分0几秒的时候,开始出现很多的错误请求tpsTransactions Per Second(最大每秒250)开始下降,,然后响应时间变大(平均400ms左右),而这个时候的并发量在550个活跃线程数左右。

秒杀压测总结

我先定在堆内存为100M的前提下,使用Jemeter阶梯式压测方法对我编写的秒杀程序进行了压测。这次压测是在增加redis秒杀商品库存缓存,创建订单使用rabbitmq消息队列接收进行之后,从100个线程开始,没10s增加100个线程进行压测,发现在1s的时候,tps开始下降,而且失败的http请求很高,得出结论在这种情况下最大并发在550个用户线程左右。

在此期间,我使用Jvisialvm观察该秒杀微服务的GC回收情况,发现老年代基本上不会发生回收,而且老年代占用比较满,新生代中幸存者去占用的比较少,与没有秒杀的时候类似,就是eden园区垃圾增加的更快一点。

然后我尝试将老年代和新生代比例调成1:1后(-XX:NewRatio=1,默认-XX:NewRatio=2,新生代1/3),在1

min3s的时候失败率开始急速上升,所以并发量可以到600左右。

ScreenShot2022-09-04at18.36.56

ScreenShot2022-09-04at13.58.59

ScreenShot2022-09-04at18.22.57

ScreenShot2022-09-04at18.31.16

ScreenShot2022-09-04at14.16.19

ScreenShot2022-09-04at14.16.56

ScreenShot2022-09-04at14.16.39

ScreenShot2022-09-04at14.17.15

ScreenShot2022-09-04at14.19.05

ScreenShot2022-09-04at14.18.26

ScreenShot2022-09-04at14.17.51

下面这张是1:1的TPS,ActiveThreads Over Time是一样的,所以可以得到,在1min03s的时候,失败HTTP开始急速上升,所以最大并发在600左右,相比于默认的1:2要好一点(老年代为2)。

ScreenShot2022-09-04at18.36.09

Author: Jcwang

Permalink: http://example.com/2022/06/24/%E9%A1%B9%E7%9B%AEDinosaurStore3/