一、性能优化指标
(1)cpu
(2) memory
(3) disk io - ssd sas
(4) network
(5) qps 每秒查询率
(6) tps 每秒处理的事务数
(7) response time
二、进程内存布局(Linux Memory Layout of a C Program)
三、算法时间复杂度分析大 O表示法
四、操作系统存储访问速度
五、优化策略-空间换时间
(1)将数据都缓存到距离cpu更近的地方,比如内存
(2) 将网络请求的数据缓存到redis 或者 本机内存
六、优化策略-时间换空间
(1)redis里面的数据淘汰机制LRU算法等
(2)虚拟内存
七、性能优化常用linux 命令
(1)htop
(2) ab
(3) free
(4) netstat
(5) telnet
(6) ping
(7) lsof
八、golang benchmark 基准测试
基准测试框架对一个测试用例的默认测试时间是 1 秒。开始测试时,当以 Benchmark 开头的基准测试用例函数返回时还不到 1 秒,那么 testing.B 中的 N 值将按 1、2、5、10、20、50……递增,同时以递增后的值重新调用基准测试用例函数。通过-benchtime参数可以自定义测试时间
(1) 度量函数执行效率
// url.go
func GetPersonHomeUrlAdd(uid string) string {
return "a.comxxxx?uid=" + uid
}
func GetPersonHomeUrlFmt(uid string) string {
return fmt.Sprintf("a.comxxxx?uid=%s", uid)
}
// url_test.go
func BenchmarkGetPersonHomeUrlAdd(b *testing.B) {
for n := 0; n < b.N; n++ {
GetPersonHomeUrlAdd("u1111111111")
}
}
func BenchmarkGetPersonHomeUrlFmt(b *testing.B) {
for n := 0; n < b.N; n++ {
GetPersonHomeUrlFmt("u1111111111")
}
}
go test -v -benchtime=5s -bench .
(2) 内存使用 和 分配次数
//slice.go
func NoCap(n int) {
result := make([]int, 0)
for i := 0; i < n; i++ {
result = append(result, i)
}
}
func HasCap(n int) {
result := make([]int, 0, n)
for i := 0; i < n; i++ {
result = append(result, i)
}
}
// slice_test.go
func BenchmarkNoCap20(b *testing.B) {
for n := 0; n < b.N; n++ {
NoCap(20)
}
}
func BenchmarkNoCap200(b *testing.B) {
for n := 0; n < b.N; n++ {
NoCap(200)
}
}
func BenchmarkHasCap20(b *testing.B) {
for n := 0; n < b.N; n++ {
HasCap(20)
}
}
func BenchmarkHasCap200(b *testing.B) {
for n := 0; n < b.N; n++ {
HasCap(200)
}
}
go test -v -benchtime=5s -benchmem -bench .
// map.go
// map.go
func NoCap(n int) {
result := make(map[int]int, 0)
for i := 0; i < n; i++ {
result[i] = i
}
}
func HasCap(n int) {
result := make(map[int]int, n)
for i := 0; i < n; i++ {
result[i] = i
}
}
// map_test.go
func BenchmarkNoCap20(b *testing.B) {
for n := 0; n < b.N; n++ {
NoCap(20)
}
}
func BenchmarkNoCap200(b *testing.B) {
for n := 0; n < b.N; n++ {
NoCap(200)
}
}
func BenchmarkHasCap20(b *testing.B) {
for n := 0; n < b.N; n++ {
HasCap(20)
}
}
func BenchmarkHasCap200(b *testing.B) {
for n := 0; n < b.N; n++ {
HasCap(200)
}
}
go test -v -benchtime=5s -benchmem -bench .
九、promethus
基本架构
main.go 加入以下代码
// 一个端口开启 pprof+charts+prometheus
prometheus.AddPrometheus()
// AddPrometheus将启动promethues监控功能,这样就能收集metrics信息了
func AddPrometheus() {
go func() {
defer func() {
if err := recover(); err != nil {
zap_logger.Errorf(nil, logTag, "prometheus客户端出现了问题 %+v", err)
}
}()
server := http.NewServeMux()
// start an http server using the mux server
// register a new handler for the /metrics endpoint
server.Handle("/metrics", promhttp.Handler())
// start an http server using the mux server
zap_logger.Errorf(nil, logTag, "prometheus error:%v", http.ListenAndServe(":6060", server))
}()
}
http://172.20.10.120:6060/metrics
NewProcessCollector 只在Linux 有
十、pprof
main.go 加入以下代码
monitor.StartPprof()
func StartPprof() {
// dev test
if config.IsDev() || config.IsTest() {
go func() {
defer func() {
if err := recover(); err != nil {
zap_logger.Errorf(nil, logTag, "StartPprof %+v", err)
}
}()
//pprof, go tool pprof -http=:6061 http://localhost:6061/debug/pprof/heap
// http://localhost:6061/debug/charts
zap_logger.Errorf(nil, logTag, "prometheus error:%v", http.ListenAndServe(":6061", nil))
}()
}
}
参考: