一、性能优化指标

(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))
}()
}
}




参考: