golang gva 调优
环境:ubuntu、docker
软件:gva(web、server、redis、mysql)
工具:phpAdmin(数据库连接工具,可以避免3306对外直接暴露)、portainer(通过界面,操作docker的容器列表)
问题:系统卡顿,接口请求超时,报504错误
一开始是CPU过载,通过pprof进行分析,大部分的函数都是runtime运行时,后来删掉整个gva库,再重启server就好了。
等这个好了后,再次运行,发现系统运行一段时间后异常的卡顿,mysql的连接数飙升,进而设置了 max-idle-conns (空闲中的最大连接数) 和 max-open-conns (打开到数据库的最大连接数),分别设置为10和100,这样一来数据库的连接数确实是上不去了,但所有需要查询数据库的接口都报504错误。
查询了gva数据库中的 sys_operation_records 表,发现有一个接口请求非常的频繁,而且间隔很短,于此同时mysql的连接数一直维持在100+,怀疑是程序在等待数据库的可用连接,一直等不到所以time out了。
短期的解决方法是,把请求频繁的应有都cancel掉,并在频繁被调用的接口中增加缓存。
1. virtual machine
查看资源的消耗情况,可以看到“server”的CPU占用率比较高,一般CPU占用率比较高都是死循环导致的,进而需要是用golang的pprof来进行查看
# 查看进程的消耗
top
# 查看进程的信息
sudo pwdx {pid}
2. pprof
https://golang2.eddycjy.com/posts/ch6/01-pprof-1/
server 上新增pprof代码
package main
import (
"log"
"net/http"
"os"
"runtime"
_ "net/http/pprof" // 会自动注册 handler 到 http server,方便通过 http 接口获取程序运行采样报告
)
func main() {
//
profd()
}
func profd() {
runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪
runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪
go func() {
// 启动一个 http server,注意 pprof 相关的 handler 已经自动注册过了
if err := http.ListenAndServe(":6060", nil); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
}
# 记录60秒内的 CPU Profiling
go tool pprof http://{host}:6060/debug/pprof/profile\?seconds\=60
# 默认显示top 10
top
# 函数的执行详情,会列出cpu的占用情况
list {name}
图形化的展示
# 默认需要等待 30 秒,执行完毕后可在当前目录下发现采集的文件 profile
wget http://127.0.0.1:6060/debug/pprof/profile
# 该命令将在所指定的端口号运行一个 PProf 的分析用的站点
# Could not execute dot; may need to install graphviz.,那么意味着你需要安装 graphviz 组件
go tool pprof -http=:6001 profile
3. portainer
使用portainer进入mysql容器,查看连接情况,看是否有过多的数据库连接
# 使用root用户登录mysql,确保可以登录,使用用户名密码的形式可能遇到 “too many connections” 错误
mysql -uroot --password={root用户密码} [--execute {sql语句}]
#查询所有的连接
show full processlist;
# 查询连接数
show global status like 'Thread%';
如果sleep的数量比较多,需要设置mysql的超时时间
set global interactive_timeout=30;
set global wait_timeout=100;
欢迎在评论区留下你宝贵的意见,不论好坏都是我前进的动力(cnblogs 排名提升)!
如果喜欢,记得点赞、推荐、关注、收藏、转发 ... ;)