秀才


  • Home

  • About

  • Tags

  • Archives

  • Search

golang profiling

Posted on 2019-02-18 | Visitors:

golang的火焰图,多用于跟踪程序运行的状态,CPU消耗,内存消耗等

应用(server)搜集数据

做 Profiling 第一步就是怎么获取应用程序的运行情况数据。
go 语言提供了 runtime/pprof 和 net/http/pprof 两个库

工具型应用

pprof 封装了很好的接口供我们使用,比如要想进行 CPU Profiling,可以调用 pprof.StartCPUProfile() 方法,它会对当前应用程序进行 CPU profiling,并写入到提供的参数中(w io.Writer),要停止调用 StopCPUProfile() 即可。

对于CPU:

1
2
3
4
f, err := os.Create(*cpuprofile)
...
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()

对于内存

1
2
3
f, err := os.Create(*memprofile)
pprof.WriteHeapProfile(f)
f.Close()

服务型应用

默认的net/http

如果server是默认的net/http包,那就很简答了,net/http已经集成了profiling
只需要添加一行

1
import _ "net/http/pprof"

自定义的 Mux

如果你使用自定义的 Mux,则需要手动注册一些路由规则:

1
2
3
4
5
r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)

beego

beego框架也是可以自定义profiling的,需要做两步

第一步,加一个controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package controllers

import (
"net/http/pprof"

"github.com/astaxie/beego"
)

type ProfController struct {
beego.Controller
}

func (c *ProfController) Get() {
switch c.Ctx.Input.Param(":pp") {
default:
pprof.Index(c.Ctx.ResponseWriter, c.Ctx.Request)
case "":
pprof.Index(c.Ctx.ResponseWriter, c.Ctx.Request)
case "cmdline":
pprof.Cmdline(c.Ctx.ResponseWriter, c.Ctx.Request)
case "profile":
pprof.Profile(c.Ctx.ResponseWriter, c.Ctx.Request)
case "symbol":
pprof.Symbol(c.Ctx.ResponseWriter, c.Ctx.Request)
}
c.Ctx.ResponseWriter.WriteHeader(200)
}

第二步,注册路由

1
2
beego.Router(`/debug/pprof`, &controllers.ProfController{})
beego.Router(`/debug/pprof/:pp([\w]+)`, &controllers.ProfController{})

gin

先装一个包

1
go get github.com/DeanThompson/ginpprof

然后在使用 ginpprof.Wrapper 即可,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"github.com/gin-gonic/gin"
"github.com/DeanThompson/ginpprof"
)

func main() {
router := gin.Default()

router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})

ginpprof.Wrapper(router)
router.Run(":8080")
}

获取svg

安装依赖

在后面我们会生成调用关系图和火焰图,需要安装 graphviz 软件包
Ubuntu安装graphviz

1
$ sudo apt-get install -y graphviz

mac安装graphviz

1
brew install graphviz

当然,还需要golang的go tool和go-torch(可选)

使用go tool

1
2
3
4
go tool pprof --seconds 5 http://test-server.com/debug/pprof/profile
go tool pprof --seconds 5 http://test-server.com/game/pprof/default
go tool pprof --seconds 5 http://test-server.com/game/pprof/cmdline
go tool pprof --seconds 5 http://test-server.com/game/pprof/symbol

这种情况下获得的图是这样子的
alt text
那么问题来了,可以看个大概,但是还是不够友好,这就引出了go-torch

使用go torch

go-torch是Uber公司开源的一款针对Go语言程序的火焰图生成工具,能收集 stack traces,并把它们整理成火焰图,直观地程序给开发人员。
我们通过go-torch,可以获取到火焰图svg
获取到的svg,拖动到Chrome浏览器即可。

安装go-torch

1
go get -v github.com/uber/go-torch

使用go-torch获取svg

1
go-torch -t 30 -u http://test-server.com -f ./test1.svg

会得到如下所示的结果

1
2
3
> go-torch -t 25 -u http://test-server.com -f ./test1.svg
INFO[14:31:49] Run pprof command: go tool pprof -raw -seconds 25 http://test-server.com/debug/pprof/profile
INFO[14:32:15] Writing svg to ./test1.svg

打开svg如下图所示
alt text

这么看,是不是就可以明白了

火焰图分析

未完待续、、、

xorm

Posted on 2018-12-29 | Visitors:

packets.go:36: unexpected EOF (Invalid Connection)

github.com/go-sql-driver/mysql 连接池中的连接释放问题

使用DB.SetConnMaxLifetime(time.Second)设置连接最大复用时间,3~10秒即可。orm基本上都有相关的设置。

紧箍咒

Posted on 2018-12-26 | Visitors:

大话西游里孙悟空说:

我不戴紧箍救不了她,戴了紧箍爱不了她。

一万年太久只争朝夕,一路走来才发现没有什么是永垂不朽。

我们终于懂得曾经离我们一步之遥的人,一旦错过,之后哪怕化身绝世英雄,身披金甲战衣,脚踏七彩祥云,一跃八千里,也未必追的回来。

redis

Posted on 2018-11-30 | Visitors:

批量删除key

1
redis-cli -h $redistest4 -a Hortor2014 -n 7  keys "cage:*10005:nxf*" | xargs redis-cli -h $redistest4 -a Hortor2014 -n 7 del

encoding

Posted on 2018-11-06 | Visitors:

MD5加密

1
2
3
4
5
func Md5(str string) string {
m := md5.New()
m.Write([]byte(str))
return hex.EncodeToString(m.Sum(nil))
}

修改服务器时间

Posted on 2018-10-31 | Visitors:

修改时间

1
sudo date -s "2018-11-02 17:18:10"

恢复时间

1
sudo ntpdate us.pool.ntp.org

国产凌凌漆

Posted on 2018-10-21 | Visitors:

你以为躲起来就找不到你了吗?

没有用的!

像你这样出色的男人,无论在什么地方,都像漆黑中的萤火虫一样,那样的鲜明,那样的出众。

你那忧郁的眼神,稀嘘的胡喳子,神乎其神的刀法,和那杯Dry Martine,都深深地迷住了我。

不过,虽然这是这样的出色,但是行有行规,无论怎样你要付清昨晚的过夜费呀,叫女人不用给钱吗?

我是那只等爱的狐狸(小王子)

Posted on 2018-10-18 | Visitors:

今天在敲代码的时候,无意间听到了一首音乐《before it gets dark》,第一条评论是这样的:“我是那只等爱的狐狸。”

于是,我找到了这篇文章:

小王子遇见狐狸,是他正在哭泣的时候。小王子因为难过而邀请狐狸和他一起玩,狐狸拒绝了。

它说:我不能和你玩,因为我还没有被驯养。

它说:对我而言,你只不过是个小男孩,象其他千万个小男孩一样。我不需要你。同样你也用不着我。然而,如果你驯养了我,那么我们就互相不可缺少了。对我来说,你就是世界上唯一的了;对你来说,我也将是世界上唯一的了。

狐狸是执着的。对爱的执着和期待。

驯养,就是建立某种关系。时常,在遇到一些人的时候,脑子里会突然闪现出”请驯养我吧”。对爱情,或者友情,都是需要条件的,如果你驯养了我,那么我们就在一起吧。

小王子驯养了那只狐狸。

狐狸告诉他:你驯养了我,那么我的生命将会充满阳光。你的脚步将会变的和其他人不一样。别人的脚步会让我迅速的躲到地下,而你得脚步声,就象音乐一样,召唤我出洞穴。

多美好的感觉,如果你被驯养,你的世界将不再是原来的样子。

当你爱着我,或者当我爱着你的时候,我们的世界,都不会再是原来的样子。我愿意把我的年华送给你当作新年的祝福,如果你愿意收下的话。

我们不离不弃的牵手一生以后,在生命最后的时光里,你告诉我:请驯养我吧!那将是多么美丽的事情。就算生命正离我们远去,我们的世界依旧是原来的样子。因为我们已经是互相不可缺少的了。

小王子最终还是离开了狐狸,小王子要对他的玫瑰负责。

对于狐狸这样的人来说,生命中其实已不是很介意。一定要把什么东西纂在手心。

小王子说:那你还是什么都没有得到吧?

狐狸说:你看到那边的麦田没有,我不吃面包,麦子对我来说一点用也没有。我对麦田无动于衷。但是,你有着金黄色的头发。麦子,是金色的,它会使我想起你。而且,我也会喜欢风吹麦浪的声音。

原来,爱情或者友情。都是不会计较得失的吧。我不在计较过去的或者将来的得失,可能我一直在失去,可是又有谁不曾已经正在或者将要失去些什么呢?从童年的糖果到生命终结时我们的躯体。

驯养,狐狸,一次又一次的教会我。生命,爱情。执着,以及真诚。

生命就是这样子被激励着,鼓动着。

有谁可以象那只狐狸一样,等待爱,认真的有点固执的等待爱。得到以后,欢乐,但是安静的看者小王子离开。

爱的境界吧,让他快乐就好了。小王子的玫瑰,娇气的玫瑰,也许永远都不会有狐狸的胸襟,可是,它仍旧得到了小王子。或者他没有再回的去,可是那朵玫瑰,依旧是幸福的,至少,小王子曾为她作过挡风的屏障,为她作过玻璃的罩子。

至少,小王子在最后要离开狐狸时仍说:我要对我的玫瑰负责。

我觉得揪心。

我感谢狐狸。于是,在我的生命中,多了一种靠”驯养”建立起来的联系—可能是爱情,也可能是友情,但无论如何,我在去追求的时候,会有这样的心态:我相信,到最后,就算他离开,至少我还会有麦子的颜色。

我想去追求,因为我想要得到。

在得到之前,我说我要好好的爱护我所得到的一切,不给他任何的负担。可是得到了以后,欲望象是一条贪婪的蛇,自私,想据为己有。

也许,爱情本就是自私的。

我们可以分享的东西很多很多,可是如果我们遇到了什么不能分享的东西,我们会不会反目成仇呢??

狐狸说:至少,我还有麦子的颜色。金色的麦浪会让我想起你。

确实,拥有过,我的世界就会变的和过去不一样,因为你来过,我就不会一无所有。至少我还有麦田的颜色。

有时候,真的不在介意,是否一定要把一些东西纂在手心。

狐狸一定懂得,小王子是理智的有责任感的,他要对玫瑰负责,毕竟狐狸在遇到小王子的时候,他已经有了玫瑰。

请驯服我吧!

我知道,那是爱的声音。

我是那只等爱的狐狸。

redis编写lua脚本

Posted on 2018-10-17 | Visitors:

由于redis并没有类似mysql或者mongo的乐观锁机制,并发控制成了一个棘手的问题
这块是可以用redis的watch来做,但是如果能实现乐观锁,那就非常方便了

redis使用lua的基础语法

1
2
3
4
5
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

lua可以调用的redis函数

1
2
redis.call()
redis.pcall()

简单例子

1
2
3
4
5
6
7
8
9
local version = redis.call("INCR", KEYS[2])
if version == 1 then
redis.call("EXPIRE", KEYS[2], ARGV[3])
end;

if tostring(version) ~= ARGV[2] then
return {-1, version}
end;
return redis.call("SET", KEYS[1], ARGV[1])

运行方式:

1
redis-cli EVAL "$(cat ./helloWorld.lua)" 3 mykey version1 expire 1 1 100

redis并发控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// SaveAtomic 并发控制save 默认versionExpire为30秒
func (db *RedisDB) SaveAtomic(key string, val interface{}, versionKey string, versionVal int, versionExpire int) (err error) {
if versionExpire == 0 {
versionExpire = 100
}
storeValue, err := db.getStoreValue(val)
if err != nil {
return
}

conn := db.Option.Pool.Get()
defer conn.Close()
if err = conn.Err(); err != nil {
return err
}

script := `
local version = redis.call("INCR", KEYS[2])
if version == 1 then
redis.call("EXPIRE", KEYS[2], ARGV[3])
end;

if tostring(version) ~= ARGV[2] then
return {-1, version}
end;
return redis.call("SET", KEYS[1], ARGV[1])
`
getScript := redis.NewScript(3, script)
res, err := redis.String(getScript.Do(conn, key, versionKey, "expire", storeValue, versionVal, versionExpire))

if err != nil {
utils.Error(err)
return
}
if res == "-1" {
//err = ErrConflict
}redis
return
}

相关文档

Redis 命令参考 · lua 脚本

goland 快捷键

Posted on 2018-10-17 | Visitors:

Mac键盘符号和修饰键说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
⌘ Command
⇧ Shift
⌥ Option
⌃ Control
↩︎ Return/Enter
⌫ Delete
⌦ 向前删除键(Fn+Delete)
↑ 上箭头
↓ 下箭头
← 左箭头
→ 右箭头
⇞ Page Up(Fn+↑)
⇟ Page Down(Fn+↓)
Home Fn + ←
End Fn + →
⇥ 右制表符(Tab键)
⇤ 左制表符(Shift+Tab)
⎋ Escape (Esc)

一、Editing(编辑)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Control + Space 基本的代码补全(补全任何类、方法、变量)
Control + Shift + Space 智能代码补全(过滤器方法列表和变量的预期类型)
Command + Shift + Enter 自动结束代码,行末自动添加分号
Command + P 显示方法的参数信息
Control + J 快速查看文档
Shift + F1 查看外部文档(在某些代码上会触发打开浏览器显示相关文档)
Command + 鼠标放在代码上 显示代码简要信息
Command + F1 在错误或警告处显示具体描述信息
Command + N, Control + Enter, Control + N 生成代码(getter、setter、构造函数、hashCode/equals,toString)
Control + O 覆盖方法(重写父类方法)
Control + I 实现方法(实现接口中的方法)
Command + Option + T 包围代码(使用if..else, try..catch, for, synchronized等包围选中的代码)
Command + / 注释/取消注释与行注释
Command + Option + / 注释/取消注释与块注释
Option + 方向键上 连续选中代码块
Option + 方向键下 减少当前选中的代码块
Control + Shift + Q 显示上下文信息
Option + Enter 显示意向动作和快速修复代码
Command + Option + L 格式化代码
Control + Option + O 优化import
Control + Option + I 自动缩进线
Tab / Shift + Tab 缩进代码 / 反缩进代码
Command + X 剪切当前行或选定的块到剪贴板
Command + C 复制当前行或选定的块到剪贴板
Command + V 从剪贴板粘贴
Command + Shift + V 从最近的缓冲区粘贴
Command + D 复制当前行或选定的块
Command + Delete 删除当前行或选定的块的行
Control + Shift + J 智能的将代码拼接成一行
Command + Enter 智能的拆分拼接的行
Shift + Enter 开始新的一行
Command + Shift + U 大小写切换
Command + Shift + ] / Command + Shift + [ 选择直到代码块结束/开始
Option + Fn + Delete 删除到单词的末尾
Option + Delete 删除到单词的开头
Command + 加号 / Command + 减号 展开 / 折叠代码块
Command + Shift + 加号 展开所以代码块
Command + Shift + 减号 折叠所有代码块
Command + W 关闭活动的编辑器选项卡

二、Search/Replace(查询/替换)

1
2
3
4
5
6
7
8
9
Double Shift 查询任何东西
Command + F 文件内查找
Command + G 查找模式下,向下查找
Command + Shift + G 查找模式下,向上查找
Command + R 文件内替换
Command + Shift + F 全局查找(根据路径)
Command + Shift + R 全局替换(根据路径)
Command + Shift + S 查询结构(Ultimate Edition 版专用,需要在Keymap中设置)
Command + Shift + M 替换结构(Ultimate Edition 版专用,需要在Keymap中设置)

三、Usage Search(使用查询)

1
2
3
Option + F7 / Command + F7 在文件中查找用法 / 在类中查找用法
Command + Shift + F7 在文件中突出显示的用法
Command + Option + F7 显示用法

四、Compile and Run(编译和运行)

1
2
3
4
5
6
7
Command + F9 编译Project
Command + Shift + F9 编译选择的文件、包或模块
Control + Option + R 弹出 Run 的可选择菜单
Control + Option + D 弹出 Debug 的可选择菜单
Control + R 运行
Control + D 调试
Control + Shift + R, Control + Shift + D 从编辑器运行上下文环境配置

五、Debugging(调试)

1
2
3
4
5
6
7
8
9
F8 进入下一步,如果当前行断点是一个方法,则不进入当前方法体内
F7 进入下一步,如果当前行断点是一个方法,则进入当前方法体内,如果该方法体还有方法,则不会进入该内嵌的方法中
Shift + F7 智能步入,断点所在行上有多个方法调用,会弹出进入哪个方法
Shift + F8 跳出
Option + F9 运行到光标处,如果光标前有其他断点会进入到该断点
Option + F8 计算表达式(可以更改变量值使其生效)
Command + Option + R 恢复程序运行,如果该断点下面代码还有断点则停在下一个断点上
Command + F8 切换断点(若光标当前行有断点则取消断点,没有则加上断点)
Command + Shift + F8 查看断点信息

六、Navigation(导航)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Command + O 查找类文件
Command + Shift + O 查找所有类型文件、打开文件、打开目录,打开目录需要在输入的内容前面或后面加一个反斜杠/
Command + Option + O 前往指定的变量 / 方法
Control + 方向键左 / Control + 方向键右 左右切换打开的编辑tab页
F12 返回到前一个工具窗口
Esc 从工具窗口进入代码文件窗口
Shift + Esc 隐藏当前或最后一个活动的窗口,且光标进入代码文件窗口
Command + Shift + F4 关闭活动run/messages/find/... tab
Command + L 在当前文件跳转到某一行的指定处
Command + E 显示最近打开的文件记录列表
Option + 方向键左 / Option + 方向键右 光标跳转到当前单词 / 中文句的左 / 右侧开头位置
Command + Option + 方向键左 / Command + Option + 方向键右 退回 / 前进到上一个操作的地方
Command + Shift + Delete 跳转到最后一个编辑的地方
Option + F1 显示当前文件选择目标弹出层,弹出层中有很多目标可以进行选择(如在代码编辑窗口可以选择显示该文件的Finder)
Command + B / Command + 鼠标点击 进入光标所在的方法/变量的接口或是定义处
Command + Option + B 跳转到实现处,在某个调用的方法名上使用会跳到具体的实现处,可以跳过接口
Option + Space, Command + Y 快速打开光标所在方法、类的定义
Control + Shift + B 跳转到类型声明处
Command + U 前往当前光标所在方法的父类的方法 / 接口定义
Control + 方向键下 / Control + 方向键上 当前光标跳转到当前文件的前一个/后一个方法名位置
Command + ] / Command + [ 移动光标到当前所在代码的花括号开始/结束位置
Command + F12 弹出当前文件结构层,可以在弹出的层上直接输入进行筛选(可用于搜索类中的方法)
Control + H 显示当前类的层次结构
Command + Shift + H 显示方法层次结构
Control + Option + H 显示调用层次结构
F2 / Shift + F2 跳转到下一个/上一个突出错误或警告的位置
F4 / Command + 方向键下 编辑/查看代码源
Option + Home 显示到当前文件的导航条
F3选中文件/文件夹/代码行,添加/取消书签
Option + F3 选中文件/文件夹/代码行,使用助记符添加/取消书签
Control + 0...Control + 9 定位到对应数值的书签位置
Command + F3 显示所有书签

七、Refactoring(重构)

1
2
3
4
5
6
7
8
9
10
11
F5 复制文件到指定目录
F6 移动文件到指定目录
Command + Delete 在文件上为安全删除文件,弹出确认框
Shift + F6 重命名文件
Command + F6 更改签名
Command + Option + N 一致性
Command + Option + M 将选中的代码提取为方法
Command + Option + V 提取变量
Command + Option + F 提取字段
Command + Option + C 提取常量
Command + Option + P 提取参数

八、VCS/Local History(版本控制/本地历史记录)

1
2
3
4
Command + K 提交代码到版本控制器
Command + T 从版本控制器更新代码
Option + Shift + C 查看最近的变更记录
Control + C 快速弹出版本控制器操作面板

九、Live Templates(动态代码模板)

1
2
Command + Option + J 弹出模板选择窗口,将选定的代码使用动态模板包住
Command + J 插入自定义动态代码模板

十、General(通用)

1
2
3
4
5
6
7
8
9
10
11
12
Command + 1...Command + 9 打开相应编号的工具窗口
Command + S 保存所有
Command + Option + Y 同步、刷新
Control + Command + F 切换全屏模式
Command + Shift + F12 切换最大化编辑器
Option + Shift + F 添加到收藏夹
Option + Shift + I 检查当前文件与当前的配置文件
Control + ` 快速切换当前的scheme(切换主题、代码样式等)
Command + , 打开IDEA系统设置
Command + ; 打开项目结构对话框
Shift + Command + A 查找动作(可设置相关选项)
Control + Shift + Tab 编辑窗口标签和工具窗口之间切换(如果在切换的过程加按上delete,则是关闭对应选中的窗口)

十一、Other(一些官方文档上没有体现的快捷键)

1
Command + Shift +8 竖编辑模式
12…7

chimps

63 posts
32 tags
RSS
© 京ICP备19001740号-1 2020 chimps
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4