Hero Image
golang pprof 实战

golang pprof 实战 炸弹程序 package main import ( // 略 _ "net/http/pprof" // 会自动注册 handler 到 http server,方便通过 http 接口获取程序运行采样报告 // 略 ) func main() { // 略 runtime.GOMAXPROCS(1) // 限制 CPU 使用数,避免过载 runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪 runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪 go func() { // 启动一个 http server,注意 pprof 相关的 handler 已经自动注册过了 // /debug/pprof/ if err := http.ListenAndServe(":6060", nil); err != nil { log.Fatal(err) } os.Exit(0) }() // 略 } http://localhost:6060/debug/pprof/ 类型 描述 备注 allocs 内存分配情况的采样信息 可以用浏览器打开,但可读性不高 blocks 阻塞操作情况的采样信息 可以用浏览器打开,但可读性不高 cmdline 显示程序启动命令及参数 可以用浏览器打开,这里会显示 ./go-pprof-practice goroutine 当前所有协程的堆栈信息 可以用浏览器打开,但可读性不高 heap 堆上内存使用情况的采样信息 可以用浏览器打开,但可读性不高 mutex 锁争用情况的采样信息 可以用浏览器打开,但可读性不高 profile CPU 占用情况的采样信息 浏览器打开会下载文件 threadcreate 系统线程创建情况的采样信息 可以用浏览器打开,但可读性不高 trace 程序运行跟踪信息 浏览器打开会下载文件,本文不涉及,可另行参阅《深入浅出 Go trace》 排查 CPU 占用过高

Hero Image
Parse Command Line Arguments in Bash

Parse Command Line Arguments in Bash getopts getopts optstring opt [arg ...] #!/bin/bash while getopts 'abc:h' opt; do case "$opt" in a) echo "Processing option 'a'" ;; b) echo "Processing option 'b'" ;; c) arg="$OPTARG" echo "Processing option 'c' with '${OPTARG}' argument" ;; ?|h) echo "Usage: $(basename $0) [-a] [-b] [-c arg]" exit 1 ;; esac done shift "$(($OPTIND -1))" optstring represents the supported options. The option expects an argument if there is a colon (:) after it. For instance, if option c expects an argument, then it would be represented as c: in the optstring When an option has an associated argument, then getopts stores the argument as a string in the OPTARG shell variable. For instance, the argument passed to option c would be stored in the OPTARG variable. opt contains the parsed option. #!/bin/bash while getopts ':abc:h' opt; do case "$opt" in a) echo "Processing option 'a'" ;; b) echo "Processing option 'b'" ;; c) arg="$OPTARG" echo "Processing option 'c' with '${OPTARG}' argument" ;; h) echo "Usage: $(basename $0) [-a] [-b] [-c arg]" exit 0 ;; :) echo -e "option requires an argument.\nUsage: $(basename $0) [-a] [-b] [-c arg]" exit 1 ;; ?) echo -e "Invalid command option.\nUsage: $(basename $0) [-a] [-b] [-c arg]" exit 1 ;; esac done shift "$(($OPTIND -1))" Note that we’ve updated optstring as well. Now it starts with the colon(:) character, which suppresses the default error message. The getopts function disables error reporting when the OPTERR variable is set to zero. Parsing Long Command-Line Options With getopt #!/bin/bash VALID_ARGS=$(getopt -o abg:d: --long alpha,beta,gamma:,delta: -- "$@") if [[ $? -ne 0 ]]; then exit 1; fi eval set -- "$VALID_ARGS" while [ : ]; do case "$1" in -a | --alpha) echo "Processing 'alpha' option" shift ;; -b | --beta) echo "Processing 'beta' option" shift ;; -g | --gamma) echo "Processing 'gamma' option. Input argument is '$2'" shift 2 ;; -d | --delta) echo "Processing 'delta' option. Input argument is '$2'" shift 2 ;; --) shift; break ;; esac done -o option represents the short command-line options --long option represents the long command-line options

Hero Image
Gin 框架绑定 JSON 参数使用 jsoniter

Gin 框架绑定 JSON 参数使用 jsoniter simple go build -tags=jsoniter ./... custom implement BindingBody interface // github.com/gin-gonic/gin@v1.6.3/binding/binding.go:36 // Binding describes the interface which needs to be implemented for binding the // data present in the request such as JSON request body, query parameters or // the form POST. type Binding interface { Name() string Bind(*http.Request, interface{}) error } // BindingBody adds BindBody method to Binding. BindBody is similar with Bind, // but it reads the body from supplied bytes instead of req.Body. type BindingBody interface { Binding BindBody([]byte, interface{}) error } package custom import ( "bytes" "fmt" "io" "net/http" jsoniter "github.com/json-iterator/go" "github.com/gin-gonic/gin/binding" ) // BindingJSON 替换Gin默认的binding,支持更丰富JSON功能 var BindingJSON = jsonBinding{} // 可以自定义jsoniter配置或者添加插件 var json = jsoniter.ConfigCompatibleWithStandardLibrary type jsonBinding struct{} func (jsonBinding) Name() string { return "json" } func (jsonBinding) Bind(req *http.Request, obj interface{}) error { if req == nil || req.Body == nil { return fmt.Errorf("invalid request") } return decodeJSON(req.Body, obj) } func (jsonBinding) BindBody(body []byte, obj interface{}) error { return decodeJSON(bytes.NewReader(body), obj) } func decodeJSON(r io.Reader, obj interface{}) error { decoder := json.NewDecoder(r) if binding.EnableDecoderUseNumber { decoder.UseNumber() } if binding.EnableDecoderDisallowUnknownFields { decoder.DisallowUnknownFields() } if err := decoder.Decode(obj); err != nil { return err } return validate(obj) } func validate(obj interface{}) error { if binding.Validator == nil { return nil } return binding.Validator.ValidateStruct(obj) } // binding.JSON 替换成自定义的 ctx.ShouldBindWith(ms, binding.JSON) ctx.ShouldBindBodyWith(ms, binding.JSON)