原创 吴就业 252 0 2022-12-29
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/c1b3d030fd764a48bd5f457bdddd109d
作者:吴就业
链接:https://wujiuye.com/article/c1b3d030fd764a48bd5f457bdddd109d
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
基于go提供的基准测试能力编写并发测试用例,为排除脚本本身的性能影响,脚本只实现简单的逻辑,并实现预编译。通过调整虚拟机池策略、cpu数、并行度等,输出调用lua脚本的平均耗时、占用的内存。
function helloLua(n)
goSayHello("hello","my name is lua") -- 调用一下go方法
return n,100000
end
var luaMng = NewLuaPreCompileManager(NewLStatePool)
func init() {
err := luaMng.CompileLua("test.lua", script)
if err != nil {
panic(err)
}
}
func invokeLua() {
result, err := luaMng.InvokeScriptFunc("test.lua", "helloLua", 30*time.Second, 2, 1)
if err != nil {
panic(err)
}
fmt.Println(result[0], result[1])
}
// go test -bench='Parallel$' -cpu=2 -benchtime=5s -count=3 -benchmem
func BenchmarkLuaPreCompileManager_InvokeScriptFunc_Parallel(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
b.SetParallelism(2000)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
invokeLua()
}
})
}
虚拟机配置:
return NewLState(lua.Options{
CallStackSize: 32, // 最大调用栈大小,调用栈的深度,即最多可以有32个方法深度
MinimizeStackMemory: true, // 调用堆栈将根据需要自动增长和收缩,最大为 `CallStackSize`
})
几个概念:
虚拟机池 | 基准测试指定CPU数 | 基准测试时长 | 基准测试次数 | 并行度(goroutine数) | 毫秒/op | 内存消耗/op | cpu占用(峰值) | 内存占用(峰值) |
---|---|---|---|---|---|---|---|---|
不使用池 | 2 | 10s | 5 | 1000 | 0.18455 | 159.5KB | 190% | 476.9M |
不使用池 | 2 | 10s | 5 | 2000 | 0.168622 | 159.5KB | 191% | 935.8M |
不使用池 | 2 | 10s | 5 | 4000 | 0.175112 | 159.6KB | 190% | 1.82G |
使用池,不固定大小 | 2 | 10s | 5 | 1000 | 0.065165 | 6.53KB | 44% | 291M |
使用池,不固定大小 | 2 | 10s | 5 | 2000 | 0.073247 | 6.50KB | 50% | 560M |
使用池,不固定大小 | 2 | 10s | 5 | 4000 | 0.077863 | 6.47KB | 52% | 1.08G |
固定核心数1000+不限非核心数 | 2 | 10s | 5 | 4000 | 0.046725 | 7.4KB | 90% | 883M |
固定核心数2000+不限非核心数 | 2 | 10s | 5 | 4000 | 0.045968 | 6.8KB | 66% | 962M |
固定核心数1000+阻塞等待 | 2 | 10s | 5 | 4000 | 0.048416 | 6.52KB | 70% | 326M |
固定核心数2000+阻塞等待 | 2 | 10s | 5 | 4000 | 0.04729 | 6.52KB | 72% | 652M |
固定核心数1000+阻塞等待 | 4 | 10s | 5 | 4000 | 0.046915 | 6.52KB | 100% | 348M |
固定核心数2000+阻塞等待 | 4 | 10s | 5 | 4000 | 0.047518 | 6.52KB | 102% | 649M |
固定核心1000+非核心2000+阻塞等待 | 2 | 10s | 5 | 4000 | 0.048806 | 7.2KB | 84% | 682M |
【报表分析】
脚本一次调用耗时小于0.2ms。
池化与非池化对比:
池化不固定池大小:
池化固定核心数+不限制非核心数:相同并行度,核心数越低,cpu占用越高,平均耗时越高。
池化固定核心数+阻塞等待:相同并行度,核心数越低,平均耗时越高,但总的内存占用越低。
池化固定核心数+不限制非核心数 vs 池化固定核心数+阻塞等待:同2000核心数,4000并发,阻塞等待比非阻塞等待,内存占用低,但平均耗时高。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
用go开发的一个文件上传中间件,由于依赖了ceph这个c库,早期通过pprof排查,怀疑内存泄露在c层,而项目依赖ceph,于是就怀疑是ceph的问题。但通过使用jemalloc排查后,并未发现ceph有什么异常。最后使用最笨的方法,定位到github.com/chai2010/webp库存在内存泄露bug。
一个微服务可能引入非常多的SDK,例如消息中间件kafka的组件、RPC框架dubbo、定时任务调度平台xxl-job的组件,以及提供web服务的jetty/tomcat等。这些组件的初始化是不确定的,那么假如启动初始化过程中,其中某个组件初始化失败了,会发生什么?
moosefs没有关于底层自定义二进制通信协议的文档,且各大版本api上差异很大。我们在github上找到一个go语言实现api操作moosefs的开源库,但不幸的是,这个组件实现的api版本很低,在测试阶段,我们发现上传文件到moosefs后,moosefs上存储的文件的md5与本地原文件md5不一致,如果是图片,能很明显的看出少了一块像素。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。
能否分享一下您的 lua 池相关代码呢