├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── content └── 00-golang-std │ ├── 01.工程模版.md │ ├── 02.crypto.md │ ├── 03.net.md │ ├── 04.gomobile.md │ └── README.md ├── go.mod ├── images └── micro-services │ └── change-api-2-go-kit.webp ├── tools ├── build.go ├── build.sh ├── folder_toc.py └── summary_toc.py └── zh ├── 00.1-Golang官方库.md ├── 00.2-依赖管理.md ├── 00.3-文档工具.md ├── 01.1-文本工具.md ├── 01.2-数据结构工具.md ├── 01.3-加密工具.md ├── 01.4-解压工具.md ├── 01.5-反射增强.md ├── 01.7-数据缓存.md ├── 02.1-测试工具.md ├── 03.0-运维工具.md ├── 03.1-定时任务.md ├── 04.0-网络工具.md ├── 04.1-MQTT.md ├── 05.0-脚本化工具.md ├── 05.1-js引擎.md ├── 05.2-lua引擎.md ├── 06.0-应用容器.md ├── 10.0-基础工具.md ├── 10.1-命令行工具.md ├── 10.2-传输工具.md ├── 11.0-序列化工具.md ├── 11.1-SQL映射工具.md ├── 11.2-WebSokcet.md ├── 11.3-解析工具.md ├── 11.4-验证工具.md ├── 11.5-Web模板.md ├── 12.0-微服务工具.md ├── 12.1-持久化工具.md ├── 12.2-连接中间件.md ├── 12.3-认证模块.md ├── 12.4-验证码.md ├── 12.5-服务监控.md ├── 12.6-服务器运行监视工具.md ├── 12.7-分布式锁.md ├── 13.1-图片处理.md ├── 13.2-GUI工具.md ├── 14.1-docker工具.md ├── 16.0-专业数据库.md ├── 20.1-WebApp框架.md ├── README.md └── preface.md /.gitignore: -------------------------------------------------------------------------------- 1 | ### Go template 2 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 3 | *.o 4 | *.a 5 | *.so 6 | 7 | # Folders 8 | _obj 9 | _test 10 | 11 | # Architecture specific extensions/prefixes 12 | *.[568vq] 13 | [568vq].out 14 | 15 | *.cgo1.go 16 | *.cgo2.c 17 | _cgo_defun.c 18 | _cgo_gotypes.go 19 | _cgo_export.* 20 | 21 | _testmain.go 22 | 23 | *.exe 24 | *.test 25 | *.prof 26 | 27 | ### Linux template 28 | *~ 29 | 30 | # temporary files which can be created if a process still has a handle open of a deleted file 31 | .fuse_hidden* 32 | 33 | # KDE directory preferences 34 | .directory 35 | 36 | # Linux trash folder which might appear on any partition or disk 37 | .Trash-* 38 | ### Windows template 39 | # Windows image file caches 40 | Thumbs.db 41 | ehthumbs.db 42 | 43 | # Folder config file 44 | Desktop.ini 45 | 46 | # Recycle Bin used on file shares 47 | $RECYCLE.BIN/ 48 | 49 | # Windows Installer files 50 | *.cab 51 | *.msi 52 | *.msm 53 | *.msp 54 | 55 | # Windows shortcuts 56 | *.lnk 57 | ### OSX template 58 | *.DS_Store 59 | .AppleDouble 60 | .LSOverride 61 | 62 | # Icon must end with two \r 63 | Icon 64 | 65 | # Thumbnails 66 | ._* 67 | 68 | # Files that might appear in the root of a volume 69 | .DocumentRevisions-V100 70 | .fseventsd 71 | .Spotlight-V100 72 | .TemporaryItems 73 | .Trashes 74 | .VolumeIcon.icns 75 | .com.apple.timemachine.donotpresent 76 | 77 | # Directories potentially created on remote AFP share 78 | .AppleDB 79 | .AppleDesktop 80 | Network Trash Folder 81 | Temporary Items 82 | .apdisk 83 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test check clean build dist all 2 | 3 | all: 4 | python ./tools/summary_toc.py . -d 100000 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [TOC] 2 | 3 | # read in gitbook 4 | 5 | [https://sinlov.gitbook.io/golang-open-project/](https://sinlov.gitbook.io/golang-open-project/) 6 | 7 | # golang-open-project 8 | 9 | This repository for collect and classify golang open project 10 | 11 | 这是一个收集各种golang开源项目的索引项目,不断更新,帮助大家快速开发 12 | 13 | 14 | # Multiple Language Versions 15 | 16 | - gitbook change to [variants to share Language](https://docs.gitbook.com/publishing/share/collection-publishing) 17 | 18 | # Serialization 19 | 20 | collect for golang serialization project 21 | 22 | 23 | #License 24 | 25 | --- 26 | 27 | The MIT License (MIT) 28 | 29 | Copyright (c) 2016 sinlovgm@gmail.com 30 | -------------------------------------------------------------------------------- /content/00-golang-std/01.工程模版.md: -------------------------------------------------------------------------------- 1 | # 工程模板 2 | 3 | ## project-layout 工程模板 4 | 5 | https://github.com/golang-standards/project-layout 6 | 7 | 这个工程不用拉下来使用,是告诉标准 golang 工程的结构 8 | -------------------------------------------------------------------------------- /content/00-golang-std/02.crypto.md: -------------------------------------------------------------------------------- 1 | # crypto 2 | 3 | ## crypto 官方加密库 4 | 5 | ```sh 6 | go get -d -v golang.org/x/crypto 7 | ``` 8 | 9 | 使用 -d 参数因为,这个不是一个可构建的目录,是加密工具的合辑 -------------------------------------------------------------------------------- /content/00-golang-std/03.net.md: -------------------------------------------------------------------------------- 1 | # Http 网络通信库 2 | 3 | ## net/http 4 | 5 | ```sh 6 | go get -u -v -x golang.org/x/net/http 7 | ``` 8 | 9 | golang.org国内安装不了,可以使用github下载然后做个软链接 10 | 11 | ```sh 12 | go get -u -v -x github.com/golang/net/http 13 | mkdir $GOPATH/src/golang.org 14 | ln -s $GOPATH/src/github.com $GOPATH/src/golang.org/x 15 | ``` 16 | 17 | 或者去 http://golangtc.com/download/package 下载包解压放到 $GOPATH/src目录下,使用`go install`安装 18 | -------------------------------------------------------------------------------- /content/00-golang-std/04.gomobile.md: -------------------------------------------------------------------------------- 1 | # gomobile 2 | 3 | ## gomobile 移动设备支持 4 | 5 | 移动设备支持库,原理是将go编译至arm or x86 平台,做native开发,或者直接输出native-bind 6 | 7 | ```sh 8 | go get -u -v golang.org/x/mobile/cmd/gomobile 9 | ``` 10 | 11 | need 12 | 13 | - xcode 6.0.+ 14 | - jdk 1.7.+ 15 | - android sdk 16 | - android-ndk-12b 17 | 18 | 使用前需要初始化 `gomobile init` 19 | 20 | ```sh 21 | gomobile help 22 | gomobile bind -target=android -o [outPath] [golangPackageName] 23 | ``` 24 | 25 | - target 设置输出目标平台(ios) -o 选择输出目录 最后一位参数是`golang的包全路径` 26 | -------------------------------------------------------------------------------- /content/00-golang-std/README.md: -------------------------------------------------------------------------------- 1 | # 00-golang-std 2 | 3 | ## 工程模版 4 | 5 | {% content-ref url="01.工程模版.md" %} 6 | [01.工程模版](01.工程模版) 7 | {% endcontent-ref %} 8 | 9 | ## crypto 10 | 11 | {% content-ref url="02.crypto.md" %} 12 | [02.crypto](02.crypto) 13 | {% endcontent-ref %} 14 | 15 | ## 03.net 16 | 17 | {% content-ref url="03.net.md" %} 18 | [03.net.crypto](03.net.crypto) 19 | {% endcontent-ref %} 20 | 21 | ## 04.gomobile 22 | 23 | {% content-ref url="04.gomobile.md" %} 24 | [04.gomobile.crypto](04.gomobile.crypto) 25 | {% endcontent-ref %} -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sinlov/golang-open-project 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /images/micro-services/change-api-2-go-kit.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinlov/golang-open-project/4c8e4ad16bbabe24043b4f35c902ebaf56e735cb/images/micro-services/change-api-2-go-kit.webp -------------------------------------------------------------------------------- /tools/build.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "regexp" 9 | "strings" 10 | 11 | "github.com/fairlyblank/md2min" 12 | ) 13 | 14 | // 定义一个访问者结构体 15 | type Visitor struct{} 16 | 17 | func (self *Visitor) md2html(arg map[string]string) error { 18 | from := arg["from"] 19 | to := arg["to"] 20 | err := filepath.Walk(from+"/", func(path string, f os.FileInfo, err error) error { 21 | if f == nil { 22 | return err 23 | } 24 | if f.IsDir() { 25 | return nil 26 | } 27 | if (f.Mode() & os.ModeSymlink) > 0 { 28 | return nil 29 | } 30 | if !strings.HasSuffix(f.Name(), ".md") { 31 | return nil 32 | } 33 | 34 | file, err := os.Open(path) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | input_byte, _ := ioutil.ReadAll(file) 40 | input := string(input_byte) 41 | input = regexp.MustCompile(`\[(.*?)\]\(?\)`).ReplaceAllString(input, "[$1](<$2.html>)") 42 | 43 | if f.Name() == "README.md" { 44 | input = regexp.MustCompile(`https:\/\/github\.com\/sinlov\/golang-open-project\/blob\/master\/`).ReplaceAllString(input, "") 45 | } 46 | 47 | // 以#开头的行,在#后增加空格 48 | // 以#开头的行, 删除多余的空格 49 | input = FixHeader(input) 50 | 51 | // 删除页面链接 52 | input = RemoveFooterLink(input) 53 | 54 | // remove image suffix 55 | input = RemoveImageLinkSuffix(input) 56 | 57 | var out *os.File 58 | filename := strings.Replace(f.Name(), ".md", ".html", -1) 59 | fmt.Println(to + "/" + filename) 60 | if out, err = os.Create(to + "/" + filename); err != nil { 61 | fmt.Fprintf(os.Stderr, "Error creating %s: %v", f.Name(), err) 62 | os.Exit(-1) 63 | } 64 | defer out.Close() 65 | md := md2min.New("none") 66 | err = md.Parse([]byte(input), out) 67 | if err != nil { 68 | fmt.Fprintln(os.Stderr, "Parsing Error", err) 69 | os.Exit(-1) 70 | } 71 | 72 | return nil 73 | }) 74 | return err 75 | } 76 | 77 | func FixHeader(input string) string { 78 | re_header := regexp.MustCompile(`(?m)^#.+$`) 79 | re_sub := regexp.MustCompile(`^(#+)\s*(.+)$`) 80 | fixer := func(header string) string { 81 | s := re_sub.FindStringSubmatch(header) 82 | return s[1] + " " + s[2] 83 | } 84 | return re_header.ReplaceAllStringFunc(input, fixer) 85 | } 86 | 87 | func RemoveFooterLink(input string) string { 88 | re_footer := regexp.MustCompile(`(?m)^#{2,} links.*?\n(.+\n)*`) 89 | return re_footer.ReplaceAllString(input, "") 90 | } 91 | 92 | func RemoveImageLinkSuffix(input string) string { 93 | re_footer := regexp.MustCompile(`png\?raw=true`) 94 | return re_footer.ReplaceAllString(input, "png") 95 | } 96 | 97 | func main() { 98 | tmp := os.Getenv("TMP") 99 | if tmp == "" { 100 | tmp = "." 101 | } 102 | 103 | workdir := os.Getenv("WORKDIR") 104 | if workdir == "" { 105 | workdir = "." 106 | } 107 | 108 | arg := map[string]string{ 109 | "from": workdir, 110 | "to": tmp, 111 | } 112 | 113 | v := &Visitor{} 114 | err := v.md2html(arg) 115 | if err != nil { 116 | fmt.Printf("filepath.Walk() returned %v\n", err) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /tools/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SED='sed' 4 | 5 | if [ `uname -s` == 'Darwin' ] ; then 6 | SED='gsed' 7 | fi 8 | 9 | bn="`basename $0`" 10 | WORKDIR="$(cd $(dirname $0); pwd -P)" 11 | 12 | # 13 | # Default language: zh 14 | # You can overwrite following variables in config file. 15 | # 16 | MSG_INSTALL_PANDOC_FIRST='请先安装pandoc,然后再次运行' 17 | MSG_SUCCESSFULLY_GENERATED='golang-open-project.epub 已经建立' 18 | MSG_CREATOR='Sinlov' 19 | MSG_DESCRIPTION='一本收集开源的Go 项目的书籍' 20 | MSG_LANGUAGE='zh-CN' 21 | MSG_TITLE='Go Open Project' 22 | [ -e "$WORKDIR/config" ] && . "$WORKDIR/config" 23 | 24 | 25 | TMP=`mktemp -d 2>/dev/null || mktemp -d -t "${bn}"` || exit 1 26 | trap 'rm -rf "$TMP"' 0 1 2 3 15 27 | 28 | 29 | cd "$TMP" 30 | 31 | ( 32 | [ go list github.com/fairlyblank/md2min >/dev/null 2>&1 ] || export GOPATH="$PWD" 33 | go get -u github.com/fairlyblank/md2min 34 | WORKDIR="$WORKDIR" TMP="$TMP" go run "$WORKDIR/build.go" 35 | ) 36 | 37 | if [ ! type -P pandoc >/dev/null 2>&1 ]; then 38 | echo "$MSG_INSTALL_PANDOC_FIRST" 39 | exit 0 40 | fi 41 | 42 | cat <<__METADATA__ > metadata.txt 43 | $MSG_CREATOR 44 | $MSG_DESCRIPTION 45 | $MSG_LANGUAGE 46 | Creative Commons 47 | $MSG_TITLE 48 | __METADATA__ 49 | 50 | mkdir -p $TMP/images 51 | cp -r $WORKDIR/images/* $TMP/images/ 52 | ls [0-9]*.html | xargs $SED -i "s/png?raw=true/png/g" 53 | 54 | pandoc --reference-links -S --toc -f html -t epub --epub-metadata=metadata.txt --epub-cover-image="$WORKDIR/images/cover.png" -o "$WORKDIR/../golang-open-project.epub" `ls [0-9]*.html | sort` 55 | 56 | echo "$MSG_SUCCESSFULLY_GENERATED" 57 | -------------------------------------------------------------------------------- /tools/folder_toc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | ##################################################### 5 | # ghtoc : markdown folder toc generator 6 | # Author : sinlov 7 | # Usage : toc.py 8 | # Date : 2016-10-24 9 | # License : see https://github.com/sinlov/markdown-folder-toc 10 | # Copyright (C) 2016 sinlov 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining 13 | # a copy of this software and associated documentation files (the "Software"), 14 | # to deal in the Software without restriction, including without limitation 15 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 | # and/or sell copies of the Software, and to permit persons to whom the 17 | # Software is furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included 20 | # in all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 24 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | import os 27 | import re 28 | import sys 29 | import optparse 30 | 31 | __author__ = 'sinlov' 32 | 33 | is_verbose = False 34 | top_level = 77 35 | folder_deep = 5 36 | 37 | save_file_name = 'preface.md' 38 | toc_file_name = 'SUMMARY.MD' 39 | 40 | lnk_temp = '%s- [%s](%s#%s)' 41 | path_lnk_temp = '[%s](%s)' 42 | TOC_MARK = '--------------' 43 | REG_TOC_MARK = r'--------------' 44 | REF = '**Folder TOC generated by [sinlov](https://github.com/sinlov/markdown-folder-toc)**' 45 | 46 | hint_help_info = """ 47 | Thanks use Markdown Folder TOC generate 48 | more information see https://github.com/sinlov/markdown-folder-toc 49 | """ 50 | 51 | error_info = """ 52 | Your input error 53 | Usage: 54 | ./folder_toc.py 55 | or input [-h] to see help 56 | """ 57 | 58 | 59 | # def get_cur_dir(): 60 | # global __CUR_DIR 61 | # ret_path = __CUR_DIR 62 | # if sys.platform.system() == 'Windows': 63 | # ret_path = ret_path.decode('gbk') 64 | # return ret_path 65 | # caller_file = inspect.stack()[0][1] 66 | # ret_path = os.path.abspath(os.path.dirname(caller_file)) 67 | # if platform.system() == 'Windows': 68 | # ret_path = ret_path.decode('gbk') 69 | # return ret_path 70 | 71 | 72 | # def get_full_path(filename): 73 | # filename = filename.replace('\\', '/') 74 | # # filename = re.sub('/+', '/', filename) 75 | # if os.path.isabs(filename): 76 | # return filename 77 | # dir_name = get_cur_dir() 78 | # filename = os.path.join(dir_name, filename) 79 | # filename = filename.replace('\\', '/') 80 | # filename = re.sub('/+', '/', filename) 81 | # return filename 82 | 83 | 84 | def print_cli_by_is_verbose(msg=str): 85 | if is_verbose: 86 | print(msg) 87 | 88 | 89 | def auto_move_toc(full): 90 | result = [] 91 | not_toc = True 92 | for line in full: 93 | if re.match(REG_TOC_MARK, line): 94 | not_toc = not not_toc 95 | continue 96 | elif not_toc: 97 | result.append(line) 98 | return result 99 | 100 | 101 | def tr_toc(header, file_name=str): 102 | global lnk_temp 103 | lvl, txt = re.findall(r'^(\d+) (.*)', header)[0] 104 | return lnk_temp % ((int(lvl) - top_level) * ' ', txt, file_name, 105 | re.sub(' ', '-', re.sub(u'[^[\u4e00-\u9fa5_a-zA-Z0-9]+$]', '', txt.lower()))) 106 | 107 | 108 | def generate_file_toc(root=str, root_len=int, f_name=str, save_name=str): 109 | global top_level 110 | lines = [] 111 | with open(os.path.join(root, f_name), 'r') as md_file: 112 | lines = md_file.readlines() 113 | if len(lines) == 0: 114 | print('You file is empty, please check it!') 115 | return 116 | newlines = auto_move_toc(lines) 117 | # remove ``` ``` for line code 118 | code_mark_count = 0 119 | filter_lines = [] 120 | for new_line in newlines: 121 | if re.match(r'(```)+', new_line): 122 | code_mark_count += 1 123 | if re.match(r'#+', new_line) and code_mark_count % 2 == 0: 124 | filter_lines.append(new_line) 125 | file_toc = [e.strip() for e in filter_lines if re.match(r'#+', e)] 126 | 127 | # encode TOC 128 | for i, h in enumerate(file_toc): 129 | ln = len(re.search(r'^#+', h).group(0)) 130 | top_level = ln if ln < top_level else top_level 131 | file_toc[i] = re.sub(r'^#+\s*', str(ln) + ' ', h) 132 | md_path = '' 133 | if root[root_len:]: 134 | md_path = root[root_len:] + '/' + f_name 135 | else: 136 | md_path = f_name 137 | file_toc = [tr_toc(h, md_path) for h in file_toc] 138 | # write in file 139 | with open(save_name, 'a') as f: 140 | file_line = path_lnk_temp % (md_path[:-3], md_path) 141 | # print_cli_by_is_verbose('write file line: %s' % file_line) 142 | f.write('\n' + file_line + '\n\n') 143 | f.write('\n'.join(file_toc) + '\n') 144 | # f.write(''.join(newlines)) 145 | f.write('\n') 146 | 147 | 148 | def generate_markdown_folder(root_path=str): 149 | global folder_deep 150 | if os.path.exists(save_path): 151 | os.remove(save_path) 152 | print("=== Save path ===\nas: " + save_path + '\n') 153 | if folder_deep != 5: 154 | print('folder level change as: ' + str(folder_deep) + '\n') 155 | now_folder_deep = 1 156 | root_len = len(root_path) 157 | for root, dirs, files in os.walk(top=folder_path, topdown=True, followlinks=False): 158 | s_files = sorted(files) 159 | for name in s_files: 160 | abs_name = str(name) 161 | low_name = name.lower() 162 | upper_name = name.upper() 163 | if low_name.endswith(".md") and folder_deep >= now_folder_deep: 164 | if name.upper().endswith('README.MD'): 165 | print_cli_by_is_verbose("Find toc README file at: " + os.path.join(root, abs_name) + ' Pass generate!') 166 | else: 167 | if upper_name.endswith(toc_file_name): 168 | print_cli_by_is_verbose( 169 | "Find toc markdown file at: " + os.path.join(root, abs_name) + ' Pass generate!') 170 | else: 171 | print_cli_by_is_verbose("Find markdown file at: " + os.path.join(root, abs_name)) 172 | generate_file_toc(root, root_len, abs_name, save_path) 173 | 174 | for name in dirs: 175 | now_folder_deep += 1 176 | # print 'folder_deep: ' + str(folder_deep) + ' |now_folder_deep ' + str(now_folder_deep) 177 | with open(save_path, 'a') as f: 178 | f.write('\n' + TOC_MARK) 179 | f.write('\n\n\n') 180 | f.write(REF) 181 | f.write('\n\n') 182 | 183 | 184 | if __name__ == '__main__': 185 | folder_path = '' 186 | if len(sys.argv) < 2: 187 | print(error_info) 188 | exit(1) 189 | parser = optparse.OptionParser('\n%prog ' + '-p \n\tOr %prog \n' + hint_help_info) 190 | parser.add_option('-v', dest='v_verbose', action="store_true", help="see verbose", default=False) 191 | parser.add_option('-p', '--pwd', dest='p_pwd', action="store_true", 192 | help="start pwd folder", default=False) 193 | parser.add_option('-f', '--folder', dest='f_folder', type="string", help="path of folder Default is .", 194 | default=".", metavar=".") 195 | parser.add_option('-d', '--deep', dest='d_deep', type="int", help="folder deep Default 5", 196 | default=5, metavar=5) 197 | parser.add_option('-l', '--level', dest='l_level', type="int", help="top level Default 77", 198 | default=77, metavar=77) 199 | (options, args) = parser.parse_args() 200 | if options.v_verbose: 201 | is_verbose = True 202 | if options.p_pwd: 203 | folder_path = os.getcwd() 204 | if options.d_deep is not None: 205 | folder_deep = options.d_deep 206 | if options.l_level is not None: 207 | top_level = options.l_level 208 | if options.f_folder is not None: 209 | folder_path = options.f_folder 210 | # check args finish 211 | if not os.path.exists(folder_path): 212 | print("Your input Folder is not exist " + folder_path) 213 | exit(-1) 214 | if os.path.isdir(folder_path) < 1: 215 | print("You input " + folder_path + "is not folder") 216 | exit(-2) 217 | # check folder path finish 218 | print('You want generate path \n\tat: ' + str(folder_path)) 219 | save_path = os.path.realpath(folder_path) + "/" + save_file_name 220 | generate_markdown_folder(folder_path) 221 | print('=== folder generate success! ===\nSee at ' + save_path) 222 | -------------------------------------------------------------------------------- /tools/summary_toc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | ##################################################### 5 | # ghtoc : markdown folder toc generator 6 | # Author : sinlov 7 | # Usage : toc.py 8 | # Date : 2016-10-24 9 | # License : see https://github.com/sinlov/markdown-folder-toc 10 | # Copyright (C) 2016 sinlov 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining 13 | # a copy of this software and associated documentation files (the "Software"), 14 | # to deal in the Software without restriction, including without limitation 15 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 | # and/or sell copies of the Software, and to permit persons to whom the 17 | # Software is furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included 20 | # in all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 24 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | 27 | import os 28 | import re 29 | import sys 30 | import optparse 31 | 32 | __author__ = 'sinlov' 33 | 34 | is_verbose = False 35 | 36 | top_level = 77 37 | folder_deep = 5 38 | 39 | save_file_name = 'SUMMARY.md' 40 | toc_file_name = 'PREFACE.MD' 41 | 42 | lnk_temp = '%s- [%s](%s#%s)' 43 | path_lnk_temp = '[%s](%s)' 44 | TOC_MARK = '--------------' 45 | REG_TOC_MARK = r'--------------' 46 | REF = '**Folder TOC generated by [sinlov](https://github.com/sinlov/markdown-folder-toc)**' 47 | 48 | hint_help_info = """ 49 | Thanks use Markdown Summary TOC generate 50 | This tools use for https://www.gitbook.com 51 | more information see https://github.com/sinlov/markdown-folder-toc 52 | """ 53 | 54 | error_info = """ 55 | Your input error 56 | Usage: 57 | ./summary_toc.py 58 | or input [-h] to see help 59 | """ 60 | 61 | 62 | # def get_cur_dir(): 63 | # global __CUR_DIR 64 | # ret_path = __CUR_DIR 65 | # if sys.platform.system() == 'Windows': 66 | # ret_path = ret_path.decode('gbk') 67 | # return ret_path 68 | # caller_file = inspect.stack()[0][1] 69 | # ret_path = os.path.abspath(os.path.dirname(caller_file)) 70 | # if platform.system() == 'Windows': 71 | # ret_path = ret_path.decode('gbk') 72 | # return ret_path 73 | 74 | 75 | # def get_full_path(filename): 76 | # filename = filename.replace('\\', '/') 77 | # # filename = re.sub('/+', '/', filename) 78 | # if os.path.isabs(filename): 79 | # return filename 80 | # dir_name = get_cur_dir() 81 | # filename = os.path.join(dir_name, filename) 82 | # filename = filename.replace('\\', '/') 83 | # filename = re.sub('/+', '/', filename) 84 | # return filename 85 | 86 | def print_cli_by_is_verbose(msg=str): 87 | if is_verbose: 88 | print(msg) 89 | 90 | 91 | def auto_move_toc(full): 92 | result = [] 93 | not_toc = True 94 | for line in full: 95 | if re.match(REG_TOC_MARK, line): 96 | not_toc = not not_toc 97 | continue 98 | elif not_toc: 99 | result.append(line) 100 | return result 101 | 102 | 103 | def tr_toc(header, file_name=str): 104 | global lnk_temp 105 | lvl, txt = re.findall(r'^(\d+) (.*)', header)[0] 106 | return lnk_temp % ((int(lvl) - top_level) * ' ', txt, file_name, 107 | re.sub(' ', '-', re.sub(u'[^[\u4e00-\u9fa5_a-zA-Z0-9]+$]', '', txt.lower()))) 108 | 109 | 110 | def generate_file_toc(root=str, root_len=int, f_name=str, save_name=str): 111 | global top_level 112 | lines = [] 113 | with open(os.path.join(root, f_name), 'r') as file: 114 | lines = file.readlines() 115 | if len(lines) == 0: 116 | print('You file is empty, please check it!') 117 | return 118 | newlines = auto_move_toc(lines) 119 | # remove ``` ``` for line code 120 | code_mark_count = 0 121 | filter_lines = [] 122 | for new_line in newlines: 123 | if re.match(r'(```)+', new_line): 124 | code_mark_count += 1 125 | if re.match(r'#+', new_line) and code_mark_count % 2 == 0: 126 | filter_lines.append(new_line) 127 | file_toc = [e.strip() for e in filter_lines if re.match(r'#+', e)] 128 | 129 | # encode TOC 130 | for i, h in enumerate(file_toc): 131 | ln = len(re.search(r'^#+', h).group(0)) 132 | top_level = ln if ln < top_level else top_level 133 | file_toc[i] = re.sub(r'^#+\s*', str(ln) + ' ', h) 134 | md_path = '' 135 | if root[root_len:]: 136 | md_path = root[root_len:] + '/' + f_name 137 | else: 138 | md_path = f_name 139 | file_toc = [tr_toc(h, md_path) for h in file_toc] 140 | # write in file 141 | with open(save_name, 'a') as f: 142 | # file_line = path_lnk_temp % (md_path[:-3], md_path) 143 | # f.write('\n' + file_line + '\n\n') 144 | f.write('\n'.join(file_toc) + '\n') 145 | # f.write(''.join(newlines)) 146 | f.write('\n') 147 | f.write('\n') 148 | 149 | 150 | def generate_markdown_folder(root_path=str): 151 | global folder_deep 152 | if os.path.exists(save_path): 153 | os.remove(save_path) 154 | print("=== Save path ===\nas: " + save_path + '\n') 155 | if folder_deep != 5: 156 | print('folder level change as: ' + str(folder_deep) + '\n') 157 | now_folder_deep = 1 158 | root_len = len(root_path) 159 | for root, dirs, files in os.walk(top=folder_path, topdown=True, followlinks=True): 160 | s_files = sorted(files) 161 | for name in s_files: 162 | abs_name = str(name) 163 | low_name = name.lower() 164 | upper_name = name.upper() 165 | if low_name.endswith(".md") and folder_deep >= now_folder_deep: 166 | if upper_name.endswith('README.MD'): 167 | print_cli_by_is_verbose( 168 | "Find toc README file at: " + os.path.join(root, abs_name) + ' Pass generate!') 169 | else: 170 | if upper_name.endswith(toc_file_name): 171 | print_cli_by_is_verbose( 172 | "Find toc markdown file at: " + os.path.join(root, abs_name) + ' Pass generate!') 173 | else: 174 | print_cli_by_is_verbose("Find markdown file at: " + os.path.join(root, abs_name)) 175 | generate_file_toc(root, root_len, abs_name, save_path) 176 | for name in dirs: 177 | now_folder_deep += 1 178 | # print 'folder_deep: ' + str(folder_deep) + ' |now_folder_deep ' + str(now_folder_deep) 179 | with open(save_path, 'a') as f: 180 | f.write('\n' + TOC_MARK) 181 | f.write('\n\n\n') 182 | f.write(REF) 183 | f.write('\n\n') 184 | 185 | 186 | if __name__ == '__main__': 187 | folder_path = '' 188 | if len(sys.argv) < 2: 189 | print(error_info) 190 | exit(1) 191 | parser = optparse.OptionParser('\n%prog ' + '-p \n\tOr %prog \n' + hint_help_info) 192 | parser.add_option('-v', dest='v_verbose', action="store_true", help="see verbose", default=False) 193 | parser.add_option('-p', '--pwd', dest='p_pwd', action="store_true", 194 | help="start pwd folder", default=False) 195 | parser.add_option('-f', '--folder', dest='f_folder', type="string", help="path of folder Default is .", 196 | default=".", metavar=".") 197 | parser.add_option('-d', '--deep', dest='d_deep', type="int", help="folder deep Default 5", 198 | default=5, metavar=5) 199 | parser.add_option('-l', '--level', dest='l_level', type="int", help="top level Default 77", 200 | default=77, metavar=77) 201 | (options, args) = parser.parse_args() 202 | if options.v_verbose: 203 | is_verbose = True 204 | if options.p_pwd: 205 | folder_path = os.getcwd() 206 | if options.d_deep is not None: 207 | folder_deep = options.d_deep 208 | if options.l_level is not None: 209 | top_level = options.l_level 210 | if options.f_folder is not None: 211 | folder_path = options.f_folder 212 | # check args finish 213 | if not os.path.exists(folder_path): 214 | print("Your input Folder is not exist " + folder_path) 215 | exit(-1) 216 | if os.path.isdir(folder_path) < 1: 217 | print("You input " + folder_path + "is not folder") 218 | exit(-2) 219 | # check folder path finish 220 | print('You want generate path \n\tat: ' + str(folder_path)) 221 | save_path = os.path.realpath(folder_path) + "/" + save_file_name 222 | generate_markdown_folder(folder_path) 223 | print('=== folder generate success! ===\nSee at ' + save_path) -------------------------------------------------------------------------------- /zh/00.1-Golang官方库.md: -------------------------------------------------------------------------------- 1 | # Golang 官方库 2 | 3 | ## project-layout 工程模板 4 | 5 | https://github.com/golang-standards/project-layout 6 | 7 | 这个工程不用拉下来使用,是告诉标准 golang 工程的结构 8 | 9 | ## crypto 官方加密库 10 | 11 | ```sh 12 | go get -d -v golang.org/x/crypto 13 | ``` 14 | 15 | 使用 -d 参数因为,这个不是一个可构建的目录,是加密工具的合辑 16 | 17 | ## Http 网络通信库 18 | 19 | ```sh 20 | go get -u -v -x golang.org/x/net/http 21 | ``` 22 | 23 | golang.org国内安装不了,可以使用github下载然后做个软链接 24 | 25 | ```sh 26 | go get -u -v -x github.com/golang/net/http 27 | mkdir $GOPATH/src/golang.org 28 | ln -s $GOPATH/src/github.com $GOPATH/src/golang.org/x 29 | ``` 30 | 31 | 或者去 http://golangtc.com/download/package 下载包解压放到 $GOPATH/src目录下,使用`go install`安装 32 | 33 | ## gomobile 移动设备支持 34 | 35 | 移动设备支持库,原理是将go编译至arm or x86 平台,做native开发,或者直接输出native-bind 36 | 37 | ```sh 38 | go get -u -v golang.org/x/mobile/cmd/gomobile 39 | ``` 40 | 41 | need 42 | 43 | - xcode 6.0.+ 44 | - jdk 1.7.+ 45 | - android sdk 46 | - android-ndk-12b 47 | 48 | 使用前需要初始化 `gomobile init` 49 | 50 | ```sh 51 | gomobile help 52 | gomobile bind -target=android -o [outPath] [golangPackageName] 53 | ``` 54 | 55 | - target 设置输出目标平台(ios) -o 选择输出目录 最后一位参数是`golang的包全路径` 56 | -------------------------------------------------------------------------------- /zh/00.2-依赖管理.md: -------------------------------------------------------------------------------- 1 | # 依赖管理 2 | 3 | ## gmchart 4 | 5 | go mod graph 可视化工具 6 | 7 | - [https://github.com/PaulXu-cn/go-mod-graph-chart](https://github.com/PaulXu-cn/go-mod-graph-chart) 8 | 9 | ```bash 10 | $ go install github.com/PaulXu-cn/go-mod-graph-chart/gmchart@latest 11 | ``` 12 | - usage 13 | 14 | ```bash 15 | $ cd goProject 16 | $ go mod graph | gmchart 17 | # change port 18 | $ go mod graph | gmchart -port 50306 19 | ``` 20 | 21 | ## dep 22 | 23 | golang 官方依赖管理工具 24 | 25 | `dep 需要在Go 1.7及更高的版本中使用` 26 | 27 | 官方地址 https://github.com/golang/dep 28 | 29 | ```sh 30 | go get -v -u github.com/golang/dep/cmd/dep 31 | ``` 32 | 33 | > 后面版本的 golang 会带有这个工具,类似 go get,就不需要自行安装了 34 | 35 | 使用 36 | 37 | - 初始化 38 | 39 | ```sh 40 | dep init 41 | # 输出日志 42 | dep init -v 43 | ``` 44 | 45 | > 生成两个文件 `Gopkg.lock`、`Gopkg.toml`和一个目录`vendor` 46 | 47 | 依赖管理 48 | 49 | ```sh 50 | # 依赖管理帮助 51 | dep help ensure 52 | # 添加一条依赖 53 | dep ensure -add github.com/bitly/go-simplejson 54 | dep ensure -add github.com/bitly/go-simplejson@=0.4.3 55 | # 添加后一定记住执行 确保 同步 56 | dep ensure 57 | # 如果想排查依赖问题 58 | dep ensure -v 59 | ``` 60 | 61 | - 更新依赖 62 | 63 | ```sh 64 | dep ensure -update -v 65 | ``` 66 | 67 | ## tools/godep 68 | 69 | https://github.com/tools/godep 70 | 71 | ```sh 72 | go get -u -v github.com/tools/godep 73 | ``` 74 | 75 | *使用 godep 管理,请升级 go 版本到 1.6 以上* 76 | 77 | - 获取最新依赖 78 | 79 | ```sh 80 | godep restore 81 | ``` 82 | 83 | - 保存或者更新依赖 84 | 85 | ```sh 86 | godep save 87 | ``` 88 | 89 | 使用注意,不要手动修改工程目录下的 `Godeps` 目录 90 | 因为 godep 使用 [vendor](https://github.com/golang/go/commit/183cc0cd41f06f83cb7a2490a499e3f9101befff) 91 | 所以请提交 `vendor`文件夹 92 | 93 | > v79 版本及以前的版本 如果工程根目录有 `Godeps` 文件目录,将不会生成 `vendor` 文件夹 94 | -------------------------------------------------------------------------------- /zh/00.3-文档工具.md: -------------------------------------------------------------------------------- 1 | # 文档工具 2 | 3 | ## gowalker.org 在线文档生成 4 | 5 | https://gowalker.org/ 6 | 7 | - [github page https://github.com/Unknwon/gowalker](https://github.com/Unknwon/gowalker) 8 | 9 | -------------------------------------------------------------------------------- /zh/01.1-文本工具.md: -------------------------------------------------------------------------------- 1 | # 文本工具 2 | 3 | 这里存放的是各种文本操作开源库 4 | 5 | ## Markdown 转换器 6 | 7 | ### fairlyblank/md2min 8 | 9 | https://github.com/fairlyblank/md2min 10 | 11 | 工程为markdown文本转换为html的工具 12 | 13 | 此工程依赖[shurcooL/sanitized_anchor_name](https://github.com/shurcooL/sanitized_anchor_name) 14 | 15 | install 16 | ------- 17 | 18 | ```sh 19 | go get -u github.com/shurcooL/sanitized_anchor_name 20 | go get -u - v github.com/fairlyblank/md2min 21 | ``` 22 | 23 | If you want to build standalone execution: 24 | 25 | ```sh 26 | cd $(GOPATH)/github.com/fairlyblank/md2min/main 27 | go build -o md2min 28 | ``` 29 | 30 | usage 31 | ----- 32 | 33 | As standalone execution: 34 | 35 | Usage: md2min [-nav=h2] name.md 36 | name.md: markdown file name 37 | -nav="none": navigate level ["none", "h1", "h2", "h3", "h4", "h5", "h6"] 38 | 39 | As package, please review [main.go](https://github.com/fairlyblank/md2min/blob/master/main/main.go). 40 | 41 | 42 | ### russross/blackfriday markdown 转换器 43 | 44 | https://github.com/russross/blackfriday 45 | 46 | ```sh 47 | go get github.com/russross/blackfriday 48 | ``` 49 | 50 | 如果想在命令行中使用 51 | 52 | ```sh 53 | go get github.com/russross/blackfriday-tool 54 | ``` 55 | 使用方法 56 | 57 | ```sh 58 | blackfriday-tool -toc -page README.md README.html 59 | ``` 60 | 61 | 更多使用或者定制见项目详细说明 62 | 63 | ## tealeg/xlsx xlsx工具 64 | 65 | ```sh 66 | go get -v github.com/tealeg/xlsx 67 | ``` 68 | 69 | [源码地址](https://github.com/tealeg/xlsx) 70 | 71 | 用法 72 | 73 | ```golang 74 | var ( 75 | excel_file_path string = "./test.xlsx" 76 | file_result map[int]map[int]map[int]string = make(map[int]map[int]map[int]string) 77 | sheet_result map[int]map[int]string = make(map[int]map[int]string) 78 | ) 79 | 80 | //open excel file 81 | f, err := xlsx.OpenFile(excel_file_path) 82 | if err != nil { 83 | log.Println(err.Error()) 84 | } 85 | 86 | //range full of sheet 87 | for sheet_key, sheet := range f.Sheets { 88 | // range row 89 | for key, row := range sheet.Rows { 90 | row_result := make(map[int]string) 91 | // range cell 92 | for k, cell := range row.Cells { 93 | row_result[k] = cell.Value 94 | } 95 | // if not emty for add 96 | if !php.Empty(row_result) { 97 | sheet_result[key] = row_result 98 | } 99 | } 100 | // if not empty for add sheet 101 | if !php.Empty(sheet_result) { 102 | file_result[sheet_key] = sheet_result 103 | } 104 | 105 | } 106 | 107 | // print result of table 108 | for _, sheet := range file_result { 109 | for k, _ := range sheet { 110 | 111 | log.Printf("%d=%v\n", k, sheet[k]) 112 | } 113 | 114 | } 115 | ``` 116 | ## swaggo/swag swaggerAPI生成器 117 | 118 | [源码地址](https://github.com/swaggo/swag) 119 | 120 | ```bash 121 | $ go get -u -v github.com/swaggo/swag/cmd/swag 122 | $ swag --help 123 | ``` 124 | 125 | 实际使用时因为网络环境,可以这么安装 126 | 127 | ```bash 128 | $ mkdir -p $GOPATH/src/github.com/swaggo 129 | $ cd $GOPATH/src/github.com/swaggo 130 | $ git clone https://github.com/swaggo/swag 131 | $ cd swag/cmd/swag/ 132 | $ go install -v 133 | ``` 134 | 135 | - 在 gin 工程中使用 136 | 137 | ```bash 138 | # 安装 gin-swagger 139 | $v go get -u -v github.com/swaggo/gin-swagger 140 | # 网络不好用这个 141 | $ cd $GOPATH/src/github.com/swaggo 142 | $ git clone https://github.com/swaggo/gin-swagger 143 | # 模板 144 | $ go get -v github.com/alecthomas/template 145 | ``` 146 | 147 | 在代码中 `router.go` 中添加 swagger 路由 148 | 149 | ```golang 150 | import ( 151 | "github.com/gin-gonic/gin" 152 | "github.com/swaggo/gin-swagger" 153 | "github.com/swaggo/gin-swagger/swaggerFiles" 154 | 155 | _ "xxxxxx/docs" // docs is generated by Swag CLI, you have to import it. 156 | ) 157 | 158 | func Load(g *gin.Engine, mw ...gin.HandlerFunc) *gin.Engine { 159 | // Middlewares. 160 | g.Use(gin.Recovery()) 161 | g.Use(middleware.NoCache) 162 | g.Use(middleware.Options) 163 | g.Use(middleware.Secure) 164 | g.Use(mw...) 165 | // swagger api docs 166 | //noinspection GoTypesCompatibility 167 | g.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) 168 | return g 169 | } 170 | ``` 171 | 172 | > 注意 xxxxxx/docs 为当前工程编译的目录,可以在这里或者格式化后引用 173 | 174 | [注释格式官方说明文档](https://swaggo.github.io/swaggo.io/declarative_comments_format/) 175 | 176 | 编写 API 文档注释,在程序的入口处 177 | 178 | ```golang 179 | // @title Swagger Example API 180 | // @version 1.0 181 | // @description This is a sample server celler server. 182 | // @termsOfService http://swagger.io/terms/ 183 | 184 | // @contact.name API Support 185 | // @contact.url http://www.swagger.io/support 186 | // @contact.email support@swagger.io 187 | 188 | // @license.name Apache 2.0 189 | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html 190 | 191 | // @host 127.0.0.1:8080 192 | // @BasePath /v1 193 | func main() { 194 | } 195 | ``` 196 | 197 | - host 会影响测试 198 | - BasePath 是API 版本更换的标识,会拼装到接口里面 199 | 200 | 编写 API 接口注释,Swagger 中需要将相应的注释或注解编写到方法上,再利用生成器自动生成说明文件 201 | 202 | 比如用户的 user.go 新建用户的接口 203 | 204 | ```golang 205 | // @Summary Add new user to the database 206 | // @Description Add a new user 207 | // @Tags user 208 | // @Accept json 209 | // @Produce json 210 | // @Param user body user.CreateRequest true "Create a new user" 211 | // @Success 200 {object} user.CreateResponse "{"code":0,"message":"OK","data":{"username":"kong"}}" 212 | // @Router /user [post] 213 | func Create(c *gin.Context) { 214 | ... 215 | } 216 | ``` 217 | 218 | - 然后在工程中编译接口文档 219 | 220 | ```bash 221 | # 在具体工程中 222 | $ cd [project path] 223 | $ swag init 224 | ``` 225 | 226 | > 注意,默认编译会占用文件夹 `docs`, 并且要求在路由中添加引用 -------------------------------------------------------------------------------- /zh/01.2-数据结构工具.md: -------------------------------------------------------------------------------- 1 | # 数据结构工具 2 | 3 | ## 安全map orcaman/concurrent-map 4 | 5 | ```sh 6 | go get -v github.com/orcaman/concurrent-map 7 | ``` 8 | 9 | 相比 golang 1.9 以后提供的 `sync.Map` 只适用于不断追加的 map 10 | 11 | 如果是删除,修改频繁的场景,可以用更多的内存来提高性能,就可以使用这个安全map 12 | 13 | ```golang 14 | import ( 15 | cmap "github.com/orcaman/concurrent-map" 16 | ) 17 | 18 | func use(){ 19 | // Create a new map. 20 | m := cmap.New() 21 | 22 | // Sets item within map, sets "bar" under key "foo" 23 | m.Set("foo", "bar") 24 | 25 | // Retrieve item from map. 26 | if tmp, ok := m.Get("foo"); ok { 27 | bar := tmp.(string) 28 | } 29 | // Removes item under key "foo" 30 | m.Remove("foo") 31 | } 32 | 33 | ``` 34 | 35 | https://github.com/orcaman/concurrent-map 36 | 37 | ## 跳表数据结构 mtchavez/skiplist 38 | 39 | https://github.com/mtchavez/skiplist 40 | 41 | ```golang 42 | go get -u github.com/mtchavez/skiplist 43 | ``` 44 | 45 | 文档 46 | 47 | http://godoc.org/github.com/mtchavez/skiplist 48 | 49 | 50 | ## UUID 生成 go.uuid 51 | 52 | https://github.com/satori/go.uuid 53 | 54 | ```sh 55 | go get github.com/satori/go.uuid 56 | ``` 57 | 58 | ```golang 59 | import ( 60 | "fmt" 61 | "github.com/satori/go.uuid" 62 | ) 63 | 64 | func main() { 65 | // Creating UUID Version 4 66 | u1 := uuid.NewV4() 67 | fmt.Printf("UUIDv4: %s\n", u1) 68 | 69 | // Parsing UUID from string input 70 | u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 71 | if err != nil { 72 | fmt.Printf("Something gone wrong: %s", err) 73 | } 74 | fmt.Printf("Successfully parsed: %s", u2) 75 | } 76 | ``` 77 | 78 | ## spf13/viper 配置解决方案 79 | 80 | ```sh 81 | go get github.com/spf13/viper 82 | # dep 83 | dep ensure -add github.com/spf13/viper 84 | ``` 85 | 86 | [github https://github.com/spf13/viper](https://github.com/spf13/viper) 87 | 88 | - 设置默认值 89 | - 可以读取如下格式的配置文件:JSON、TOML、YAML、HCL 90 | - 监控配置文件改动,并热加载配置文件 91 | - 从环境变量读取配置 92 | - 从远程配置中心读取配置(etcd/consul),并监控变动 93 | - 从命令行 flag 读取配置 94 | - 从缓存中读取配置 95 | - 支持直接设置配置项的值 96 | 97 | 配置读取顺序 98 | 99 | - `viper.Set()` 所设置的值 100 | - 命令行 flag 101 | - 环境变量 102 | - 配置文件 103 | - 配置中心:`etcd/consul` 104 | - 默认值 105 | -------------------------------------------------------------------------------- /zh/01.3-加密工具.md: -------------------------------------------------------------------------------- 1 | # 加密工具 2 | 3 | ## sinlov/fastEncryptDecode 4 | 5 | https://github.com/sinlov/fastEncryptDecode 6 | 7 | 支持 `Utf8-Unicode` `Base64UrlSafeEncode` `AES CBC PKCS7` `AES ECB PKCS5` 加密工具 8 | 9 | 使用参见测试代码 10 | 11 | https://github.com/sinlov/fastEncryptDecode/blob/master/fastEnDeCode_test.go 12 | 13 | 其中包括 byte2Uint 比特数组和数字类型的转换 14 | 15 | https://github.com/sinlov/fastEncryptDecode/blob/master/fastEnDeCode_test.go#L50 16 | -------------------------------------------------------------------------------- /zh/01.4-解压工具.md: -------------------------------------------------------------------------------- 1 | # 解压工具 2 | 3 | ## mholt/archiver 混合解压工具 4 | 5 | 支持 `.zip, .tar, .tar.gz, .tar.bz2, .tar.xz, .tar.lz4, .tar.sz, and .rar (open-only)` 6 | 7 | ```sh 8 | go get -v github.com/mholt/archiver 9 | ``` 10 | 11 | 基础使用 12 | 13 | ```golang 14 | import "github.com/mholt/archiver" 15 | 16 | func makeZip(out string, inputFiles []string){ 17 | err := archiver.Zip.Make(out, inputFiles) 18 | if err != nil { 19 | fmt.printf("zip error %v\n", err) 20 | } 21 | } 22 | 23 | func openZip(outFolder string, zipFile string){ 24 | err := archiver.Zip.Open(zipFile, outFolder) 25 | if err != nil { 26 | fmt.printf("zip error %v\n", err) 27 | } 28 | } 29 | ``` 30 | 31 | 更多使用见 https://github.com/mholt/archiver -------------------------------------------------------------------------------- /zh/01.5-反射增强.md: -------------------------------------------------------------------------------- 1 | # 反射增强 2 | 3 | ## github.com/modern-go/reflect2 反射增强库 4 | 5 | [https://github.com/modern-go/reflect2](https://github.com/modern-go/reflect2) 6 | 7 | ```bash 8 | GO111MODULE=on go mod edit -require=github.com/modern-go/reflect2@ 9 | GO111MODULE=on go mod download 10 | GO111MODULE=on go mod vendor 11 | ``` 12 | - by name 13 | 14 | ```golang 15 | import( 16 | "github.com/modern-go/reflect2" 17 | ) 18 | // given package is github.com/your/awesome-package 19 | type MyStruct struct { 20 | // ... 21 | } 22 | 23 | // will return the type 24 | reflect2.TypeByName("awesome-package.MyStruct") 25 | // however, if the type has not been used 26 | // it will be eliminated by compiler, so we can not get it in runtime 27 | 28 | // get/set interface{} 29 | valType := reflect2.TypeOf(1) 30 | i := 1 31 | j := 10 32 | valType.Set(&i, &j) 33 | 34 | // get/set unsafe.Pointer 35 | valType := reflect2.TypeOf(1) 36 | i := 1 37 | j := 10 38 | valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j)) 39 | ``` -------------------------------------------------------------------------------- /zh/01.7-数据缓存.md: -------------------------------------------------------------------------------- 1 | # 数据缓存 2 | 3 | 4 | ## github.com/muesli/cache2gogo 简单内存库 5 | 6 | [https://github.com/muesli/cache2go](https://github.com/muesli/cache2go) 7 | 8 | - 内存库,支持 kv 模式,其中 key 必须为 string, value 为任意 9 | - 支持 TTL 10 | - 支持回调,观察缓存变化 11 | 12 | ```bash 13 | GO111MODULE=on go mod edit -require=github.com/muesli/cache2go 14 | GO111MODULE=on go mod download 15 | GO111MODULE=on go mod vendor 16 | ``` 17 | 18 | - 官方样例 https://github.com/muesli/cache2go/tree/master/examples 19 | 20 | ## github.com/eko/gocache 多模式缓存库 21 | 22 | [github.com/eko/gocache](https://github.com/eko/gocache) 23 | 24 | 支持: 25 | - 内存缓存, 支持多种模式 26 | - 自实现内存缓存,支持 TTL 27 | - 性能基准 https://github.com/eko/gocache#benchmarks 28 | 29 | 内存缓存模式: 30 | - 普通模式 https://github.com/eko/gocache#memcache 31 | - 大缓存模式 https://github.com/eko/gocache#memory-using-bigcache 32 | - 高压缩模式 https://github.com/eko/gocache#memory-using-ristretto 33 | - redis 外缓存 https://github.com/eko/gocache#redis 34 | - 缓存代理 https://github.com/eko/gocache#a-marshaler-wrapper 35 | 36 | ```bash 37 | GO111MODULE=on go mod edit -require=github.com/eko/gocache 38 | GO111MODULE=on go mod download 39 | GO111MODULE=on go mod vendor 40 | ``` 41 | 42 | ## github.com/philippgille/gokv kv缓存库 43 | 44 | - [github.com/philippgille/gokv](https://github.com/philippgille/gokv) 45 | 46 | Simple key-value store abstraction and implementations for Go 47 | 48 | more use see https://github.com/philippgille/gokv#usage 49 | 50 | - [document faster https://gowalker.org/github.com/philippgille/gokv](https://gowalker.org/github.com/philippgille/gokv) -------------------------------------------------------------------------------- /zh/02.1-测试工具.md: -------------------------------------------------------------------------------- 1 | # 测试工具 2 | 3 | ## Pallinder/go-randomdata 随机数据生成器 4 | 5 | 类似 faker 一样,可以作为生产随机数据的工具 6 | 7 | https://github.com/Pallinder/go-randomdata 8 | 安装 9 | 10 | ```sh 11 | go get -v github.com/Pallinder/go-randomdata 12 | dep ensure -add github.com/Pallinder/go-randomdata 13 | ``` 14 | 15 | 使用方法 16 | 17 | ```golang 18 | import ( 19 | "fmt" 20 | "github.com/Pallinder/go-randomdata" 21 | ) 22 | func main() { 23 | // Print a random silly name 24 | fmt.Println(randomdata.SillyName()) 25 | // Print a male title 26 | fmt.Println(randomdata.Title(randomdata.Male)) 27 | // Print a female title 28 | fmt.Println(randomdata.Title(randomdata.Female)) 29 | // Print a title with random gender 30 | fmt.Println(randomdata.Title(randomdata.RandomGender)) 31 | // Print a male first name 32 | fmt.Println(randomdata.FirstName(randomdata.Male)) 33 | // Print a female first name 34 | fmt.Println(randomdata.FirstName(randomdata.Female)) 35 | // Print a last name 36 | fmt.Println(randomdata.LastName()) 37 | // Print a male name 38 | fmt.Println(randomdata.FullName(randomdata.Male)) 39 | // Print a female name 40 | fmt.Println(randomdata.FullName(randomdata.Female)) 41 | // Print a name with random gender 42 | fmt.Println(randomdata.FullName(randomdata.RandomGender)) 43 | // Print an email 44 | fmt.Println(randomdata.Email()) 45 | // Print a country with full text representation 46 | fmt.Println(randomdata.Country(randomdata.FullCountry)) 47 | // Print a country using ISO 3166-1 alpha-2 48 | fmt.Println(randomdata.Country(randomdata.TwoCharCountry)) 49 | // Print a country using ISO 3166-1 alpha-3 50 | fmt.Println(randomdata.Country(randomdata.ThreeCharCountry)) 51 | // Print a currency using ISO 4217 52 | fmt.Println(randomdata.Currency()) 53 | // Print the name of a random city 54 | fmt.Println(randomdata.City()) 55 | // Print the name of a random american state 56 | fmt.Println(randomdata.State(randomdata.Large)) 57 | // Print the name of a random american state using two chars 58 | fmt.Println(randomdata.State(randomdata.Small)) 59 | // Print an american sounding street name 60 | fmt.Println(randomdata.Street()) 61 | // Print an american sounding address 62 | fmt.Println(randomdata.Address()) 63 | // Print a random number >= 10 and < 20 64 | fmt.Println(randomdata.Number(10, 20)) 65 | // Print a number >= 0 and < 20 66 | fmt.Println(randomdata.Number(20)) 67 | // Print a random float >= 0 and < 20 with decimal point 3 68 | fmt.Println(randomdata.Decimal(0, 20, 3)) 69 | // Print a random float >= 10 and < 20 70 | fmt.Println(randomdata.Decimal(10, 20)) 71 | // Print a random float >= 0 and < 20 72 | fmt.Println(randomdata.Decimal(20)) 73 | // Print a bool 74 | fmt.Println(randomdata.Boolean()) 75 | // Print a paragraph 76 | fmt.Println(randomdata.Paragraph()) 77 | // Print a postal code 78 | fmt.Println(randomdata.PostalCode("SE")) 79 | // Print a set of 2 random numbers as a string 80 | fmt.Println(randomdata.StringNumber(2, "-")) 81 | // Print a set of 2 random 3-Digits numbers as a string 82 | fmt.Println(randomdata.StringNumberExt(2, "-", 3)) 83 | // Print a random string sampled from a list of strings 84 | fmt.Println(randomdata.StringSample("my string 1", "my string 2", "my string 3")) 85 | // Print a valid random IPv4 address 86 | fmt.Println(randomdata.IpV4Address()) 87 | // Print a valid random IPv6 address 88 | fmt.Println(randomdata.IpV6Address()) 89 | // Print a browser's user agent string 90 | fmt.Println(randomdata.UserAgentString()) 91 | // Print a day 92 | fmt.Println(randomdata.Day()) 93 | // Print a month 94 | fmt.Println(randomdata.Month()) 95 | // Print full date like Monday 22 Aug 2016 96 | fmt.Println(randomdata.FullDate()) 97 | // Print full date <= Monday 22 Aug 2016 98 | fmt.Println(randomdata.FullDateInRange("2016-08-22")) 99 | // Print full date >= Monday 01 Aug 2016 and <= Monday 22 Aug 2016 100 | fmt.Println(randomdata.FullDateInRange("2016-08-01", "2016-08-22")) 101 | // Print phone number according to e.164 102 | fmt.Println(randomdata.PhoneNumber()) 103 | // Get a complete and randomised profile of data generally used for users 104 | // There are many fields in the profile to use check the Profile struct definition in fullprofile.go 105 | profile := randomdata.GenerateProfile(randomdata.Male | randomdata.Female | randomdata.RandomGender) 106 | fmt.Printf("The new profile's username is: %s and password (md5): %s\n", profile.Login.Username, profile.Login.Md5) 107 | } 108 | ``` 109 | 110 | ## gostub 测试打桩工具 111 | 112 | - 安装 113 | 114 | ```sh 115 | go get -v github.com/prashantv/gostub 116 | dep ensure -add github.com/prashantv/gostub 117 | ``` 118 | 119 | https://github.com/prashantv/gostub 120 | 121 | - 使用 122 | 123 | ```golang 124 | import ( 125 | "testing" 126 | . "github.com/prashantv/gostub" 127 | ) 128 | 129 | var ( 130 | MYSQLUSER string 131 | MYSQLPASSWORD string 132 | MYSQLADDR string 133 | MYSQLPORT int 134 | DATABASENAME string 135 | ) 136 | 137 | func TestStubs(t *testing.T){ 138 | stubs := New() 139 | stubs.Stub(&MYSQLUSER, "root") 140 | stubs.Stub(&MYSQLPASSWORD, "root") 141 | stubs.Stub(&MYSQLADDR, "127.0.0.1") 142 | stubs.Stub(&MYSQLPORT, 3306) 143 | stubs.Stub(&DATABASENAME, "mysql") 144 | defer stubs.Reset() 145 | ) 146 | ``` 147 | 148 | ## golang/mock/gomock mock模拟 149 | 150 | 通过mockgen 工具,会根据接口定义来生成接口测试用的文件 151 | 152 | 配合 gostub 对mock程序的行为进行打桩,然后就可以用来测试 153 | 154 | - 安装 155 | 156 | ```sh 157 | go get github.com/golang/mock/gomock 158 | go install github.com/golang/mock/mockgen 159 | ``` 160 | 161 | https://github.com/golang/mock 162 | 163 | - 使用 164 | 165 | ```sh 166 | mockgen -source user.go > mock_user.go 167 | ``` 168 | 169 | 就会生成对应的需要测试的 mock 文件 170 | 171 | ## codesenberg/bombardier http1/2 压测工具 172 | 173 | - [https://github.com/codesenberg/bombardier](https://github.com/codesenberg/bombardier) 174 | 175 | ```bash 176 | go install github.com/codesenberg/bombardier@latest 177 | 178 | bombardier -c 125 -n 10000000 http://localhost:8080 179 | ``` 180 | 181 | ## smartystreets/goconvey 测试用例统计 182 | 183 | 非常好用的三方测试覆盖统计工具 184 | 185 | http://goconvey.co/ 186 | https://github.com/smartystreets/goconvey 187 | 188 | ```sh 189 | go get -v github.com/smartystreets/goconvey 190 | ``` 191 | 192 | 编译后,使用命令行工具在工程目录下运行 193 | 194 | ```sh 195 | goconvey 196 | ``` 197 | -------------------------------------------------------------------------------- /zh/03.0-运维工具.md: -------------------------------------------------------------------------------- 1 | # 运维工具 2 | 3 | ## 服务器运维 4 | 5 | ### 平滑重启 github.com/fvbock/endless 6 | 7 | [https://github.com/fvbock/endless](https://github.com/fvbock/endless) 8 | 9 | Go服务器的平滑重启(替代http.ListenAndServe) 10 | 11 | ```go 12 | import "github.com/fvbock/endless" 13 | 14 | err := endless.ListenAndServe("localhost:4242", handler) 15 | ``` 16 | 17 | 如果要保存实际的pid文件,可以像这样更改 `BeforeBegin` 钩子 18 | 19 | ```go 20 | server := endless.NewServer("localhost:4242", handler) 21 | server.BeforeBegin = func(add string) { 22 | log.Printf("Actual pid is %d", syscall.Getpid()) 23 | // save it somehow 24 | } 25 | err := server.ListenAndServe() 26 | ``` 27 | 28 | ### goagain 零下线时间式重启 29 | 30 | ```sh 31 | go get -v github.com/rcrowley/goagain 32 | ``` 33 | 34 | 35 | 类似nginx平滑重启 36 | 37 | goagain会监控2个系统信号,一个为SIGTERM,接收到这个信号,程序就停止运行 38 | 39 | 另一个信号为SIGUSR2,接收到这个信号的行为是,当前进程,也就是父进程会新建一个子进程, 40 | 然后把父进程的pid保存到一个名为 `GOAGAIN_PPID` 的环境变量; 41 | 子进程启动的时候会检索 `GOAGAIN_PPID` 这个变量,来判断程序是否要重启,通过这个变量来关闭父进程,来达到平滑重启的效果 42 | 43 | [项目地址 https://github.com/rcrowley/goagain](https://github.com/rcrowley/goagain) 44 | 45 | ### caddy 跨平台HTTP/2服务代理 46 | 47 | https://github.com/mholt/caddy 48 | 49 | 支持全部平台,可以部署各种服务,反向代理 50 | 51 | [官方文档 caddyserver/docs](https://caddyserver.com/docs) 52 | 53 | docker-compose 部署 [https://hub.docker.com/r/zzrot/alpine-caddy/](https://hub.docker.com/r/zzrot/alpine-caddy/) 54 | docker-php 支持部署 [https://hub.docker.com/r/abiosoft/caddy/](https://hub.docker.com/r/abiosoft/caddy/) 55 | 56 | 57 | -------------------------------------------------------------------------------- /zh/03.1-定时任务.md: -------------------------------------------------------------------------------- 1 | # 定时任务 2 | 3 | ## antlabs/timer 定时器-基于5级时间轮 4 | 5 | - [https://github.com/antlabs/timer](https://github.com/antlabs/timer) 6 | 7 | ```bash 8 | $ go list -m -mod=readonly -versions github.com/antlabs/timer 9 | $ go mod edit -require=github.com/antlabs/timer@v0.0.5 10 | ``` 11 | 12 | - usage once 13 | 14 | ```go 15 | import ( 16 | "github.com/antlabs/timer" 17 | "fmt" 18 | ) 19 | 20 | func main() { 21 | tm := timer.NewTimer() 22 | 23 | tm.AfterFunc(1*time.Second, func() { 24 | fmt.Printf("after\n") 25 | }) 26 | 27 | tm.AfterFunc(10*time.Second, func() { 28 | fmt.Printf("after\n") 29 | }) 30 | tm.Run() 31 | } 32 | ``` 33 | 34 | - Schedule 35 | 36 | ```go 37 | import ( 38 | "github.com/antlabs/timer" 39 | "log" 40 | ) 41 | 42 | func main() { 43 | tm := timer.NewTimer() 44 | 45 | tm.ScheduleFunc(1*time.Second, func() { 46 | fmt.Printf("schedule\n") 47 | }) 48 | 49 | tm.Run() 50 | // cancel 51 | tm.Stop() 52 | } 53 | ``` 54 | 55 | ## go版本cron github.com/robfig/cron 56 | 57 | [https://github.com/robfig/cron](https://github.com/robfig/cron) 58 | 59 | ```go 60 | import "github.com/robfig/cron/v3" 61 | 62 | func test(){ 63 | fmt.Printf("test=%d\n",ttt) 64 | ttt++ 65 | } 66 | 67 | func main(){ 68 | c := cron.New() 69 | 70 | c.AddFunc("0/5 * * * * ?", func() { log.Info("Every hour on the half hour") }) 71 | c.AddFunc("0/5 * * * * ?", test)//5秒执行一次,12×5=60,所以一共执行12次 72 | 73 | c.Start() 74 | } 75 | ``` 76 | 77 | Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义 78 | ``` 79 | Seconds Minutes Hours DayofMonth Month DayofWeek Year 80 | // or 81 | Seconds Minutes Hours DayofMonth Month DayofWeek 82 | ``` 83 | 每一个域可出现的字符如下: 84 | ``` 85 | Seconds: 可出现 ", - * /" 四个字符,有效范围为0-59的整数 86 | Minutes: 可出现 ", - * /" 四个字符,有效范围为0-59的整数 87 | Hours: 可出现 ", - * /" 四个字符,有效范围为0-23的整数 88 | DayofMonth: 可出现 ", - * / ? L W C" 八个字符,有效范围为0-31的整数 89 | Month: 可出现 ", - * /" 四个字符,有效范围为1-12的整数或JAN-DEc 90 | DayofWeek: 可出现 ", - * / ? L C #" 四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推 91 | Year: 可出现 ", - * /" 四个字符,有效范围为1970-2099年 92 | ``` 93 | 每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是: 94 | 95 | 1. `*` : 表示匹配该域的任意值,假如在Minutes域使用*, 即表示每分钟都会触发事件。 96 | 1. `?` : 只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和 DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。 97 | 1. `-` : 表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 98 | 1. `/` : 表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次. 99 | 1. `,` : 表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。 100 | 1. `L` : 表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。 101 | 1. `W` : 表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一 到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 102 | 1. `LW` : 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 103 | 1. `#` : 用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。 104 | 105 | Cron表达式几个简单范例: 106 | ``` 107 | 每隔5秒执行一次:*/5 * * * * ? 108 | 每隔1分钟执行一次:0 */1 * * * ? 109 | 每天23点执行一次:0 0 23 * * ? 110 | 每天凌晨1点执行一次:0 0 1 * * ? 111 | 每月1号凌晨1点执行一次:0 0 1 1 * ? 112 | 每月最后一天23点执行一次:0 0 23 L * ? 113 | 每周星期天凌晨1点实行一次:0 0 1 ? * L 114 | 在26分、29分、33分执行一次:0 26,29,33 * * * ? 115 | 每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ? 116 | ``` -------------------------------------------------------------------------------- /zh/04.0-网络工具.md: -------------------------------------------------------------------------------- 1 | # http客户端 2 | 3 | ## carlmjohnson/requests 客户端 4 | 5 | - [https://github.com/carlmjohnson/requests](https://github.com/carlmjohnson/requests) 6 | 7 | ```bash 8 | $ go list -m -mod=readonly -versions github.com/carlmjohnson/requests 9 | $ go mod edit -require=github.com/carlmjohnson/requests@v0.23.1 10 | ``` 11 | 12 | - v0.x.x only use golang.org/x/net 13 | - POST a JSON object and parse the response 14 | 15 | ```go 16 | var res placeholder 17 | req := placeholder{ 18 | Title: "foo", 19 | Body: "baz", 20 | UserID: 1, 21 | } 22 | err := requests. 23 | URL("/posts"). 24 | Host("jsonplaceholder.typicode.com"). 25 | BodyJSON(&req). 26 | ToJSON(&res). 27 | Fetch(ctx) 28 | // net/http equivalent left as an exercise for the reader 29 | ``` 30 | 31 | - [more document see](https://pkg.go.dev/github.com/carlmjohnson/requests#readme-http-requests-for-gophers) 32 | 33 | ## monaco-io/request 客户端 34 | 35 | - [https://github.com/monaco-io/request](https://github.com/monaco-io/request) 36 | 37 | ```bash 38 | $ go list -m -mod=readonly -versions github.com/monaco-io/request 39 | $ go mod edit -require=github.com/monaco-io/request@v1.0.15 40 | ``` 41 | 42 | - v1.x.x depend golang.org/x/net github.com/kr/text gopkg.in/yaml.v2 43 | - support Methods: OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT 44 | - e.g. POST with local files 45 | - support Timeout 46 | 47 | ```go 48 | package main 49 | 50 | import ( 51 | "github.com/monaco-io/request" 52 | ) 53 | 54 | func main() { 55 | c := request.Client{ 56 | URL: "https://google.com", 57 | Method: "POST", 58 | Query: map[string]string{"hello": "world"}, 59 | MultipartForm: MultipartForm{ 60 | Fields: map[string]string{"a": "1"}, 61 | Files: []string{"doc.txt"}, 62 | }, 63 | } 64 | resp := c.Send().Scan(&result) 65 | ... 66 | ``` 67 | 68 | - more doc see [pkg.go.dev](https://pkg.go.dev/github.com/monaco-io/request#section-documentation) 69 | 70 | ## parnurzeal/gorequest 客户端 71 | 72 | - https://github.com/parnurzeal/gorequest 73 | 74 | 非常好用简单的客户端 75 | 76 | ```sh 77 | go get -v github.com/parnurzeal/gorequest 78 | ``` 79 | - version `0.2.15` 80 | 81 | - method support `GET DELETE, HEAD, POST, PUT, PATCH` 82 | - support JSON 83 | - support Callback 84 | - support Timeout 85 | - support Retry 86 | - support Multipart/Form-Data 87 | - support Proxy 88 | - supprot Basic Authentication 89 | 90 | ```golang 91 | request := gorequest.New() 92 | resp, body, errs := request.Get("http://example.com"). 93 | RedirectPolicy(redirectPolicyFunc). 94 | Set("If-None-Match", `W/"wyzzy"`). 95 | End() 96 | 97 | requestJson := gorequest.New() 98 | resp, body, errs := requestJson.Post("http://example.com"). 99 | Set("Notes","gorequst is coming!"). 100 | Send(`{"name":"backy", "species":"dog"}`). 101 | End() 102 | ``` 103 | 104 | ## github.com/tomsteele/blacksheepwall 域名搜索工具 105 | 106 | [https://github.com/tomsteele/blacksheepwall](https://github.com/tomsteele/blacksheepwall) 107 | 108 | ```bash 109 | go get -v github.com/tomsteele/blacksheepwall 110 | ``` 111 | 112 | blacksheepwall是一款由Go语言编写的域名信息搜集工具 ,你也可以在你的工具中将它作为一个独立软件包来使用 -------------------------------------------------------------------------------- /zh/04.1-MQTT.md: -------------------------------------------------------------------------------- 1 | # MQTT 协议 2 | 3 | ## surgemq/surgemq MQTT服务端客户端 4 | 5 | ```sh 6 | go get -v github.com/surgemq/surgemq 7 | ``` 8 | 9 | more info see [https://github.com/surgemq/surgemq](https://github.com/surgemq/surgemq) 10 | 11 | - server 12 | 13 | ```golang 14 | // Create a new server 15 | svr := &service.Server{ 16 | KeepAlive: 300, // seconds 17 | ConnectTimeout: 2, // seconds 18 | SessionsProvider: "mem", // keeps sessions in memory 19 | Authenticator: "mockSuccess", // always succeed 20 | TopicsProvider: "mem", // keeps topic subscriptions in memory 21 | } 22 | 23 | // Listen and serve connections at localhost:1883 24 | svr.ListenAndServe("tcp://:1883") 25 | ``` 26 | 27 | - client 28 | 29 | ```golang 30 | // Instantiates a new Client 31 | c := &Client{} 32 | 33 | // Creates a new MQTT CONNECT message and sets the proper parameters 34 | msg := message.NewConnectMessage() 35 | msg.SetWillQos(1) 36 | msg.SetVersion(4) 37 | msg.SetCleanSession(true) 38 | msg.SetClientId([]byte("surgemq")) 39 | msg.SetKeepAlive(10) 40 | msg.SetWillTopic([]byte("will")) 41 | msg.SetWillMessage([]byte("send me home")) 42 | msg.SetUsername([]byte("surgemq")) 43 | msg.SetPassword([]byte("verysecret")) 44 | 45 | // Connects to the remote server at 127.0.0.1 port 1883 46 | c.Connect("tcp://127.0.0.1:1883", msg) 47 | ``` -------------------------------------------------------------------------------- /zh/05.0-脚本化工具.md: -------------------------------------------------------------------------------- 1 | # 脚本化工具 2 | 3 | ## 像shell一样使用go github.com/bitfield/script 4 | 5 | [https://github.com/bitfield/script](https://github.com/bitfield/script) 6 | 7 | ```bash 8 | $ go list -m -mod=readonly -versions github.com/bitfield/script | awk '{print $NF}' 9 | # v0.14.0 10 | $ go mod edit -require='github.com/bitfield/script@v0.14.0' 11 | ``` 12 | 13 | - Everything is a pipe 14 | 15 | use is a pipe 16 | 17 | ```go 18 | var q script.Pipe 19 | q = p.Match("Error") 20 | // or can load file 21 | var q script.Pipe 22 | q = script.File("test.txt").Match("Error") 23 | 24 | // get result 25 | result, err := q.String() 26 | if err != nil { 27 | log.Fatalf("oh no: %v", err) 28 | } 29 | fmt.Println(result) 30 | 31 | // Handling errors 32 | numLines, err := script.File("doesnt_exist.txt").CountLines() 33 | fmt.Println(numLines) 34 | // Output: 0 35 | if err != nil { 36 | log.Fatal(err) 37 | } 38 | // Output: open doesnt_exist.txt: no such file or directory 39 | ``` 40 | 41 | Closing pipes 42 | 43 | The data source associated with a pipe will be automatically closed once it is read completely. Therefore, calling any sink method which reads the pipe to completion (such as String()) will close its data source. The only case in which you need to call Close() on a pipe is when you don't read from it, or you don't read it to completion. 44 | 45 | If the pipe was created from something that doesn't need to be closed, such as a string, then calling Close() simply does nothing. 46 | 47 | This is implemented using a type called ReadAutoCloser, which takes an io.Reader and wraps it so that: 48 | 49 | 1. it is always safe to close (if it's not a closable resource, it will be wrapped in an ioutil.NopCloser to make it one), and 50 | 2. it is closed automatically once read to completion (specifically, once the Read() call on it returns io.EOF). 51 | 52 | It is your responsibility to close a pipe if you do not read it to completion. -------------------------------------------------------------------------------- /zh/05.1-js引擎.md: -------------------------------------------------------------------------------- 1 | # js-引擎 2 | 3 | ## js 解析执行环境 github.com/robertkrimen/otto 4 | 5 | [https://github.com/robertkrimen/otto](https://github.com/robertkrimen/otto) 6 | 7 | ```go 8 | import ( 9 | "github.com/robertkrimen/otto" 10 | ) 11 | 12 | vm := otto.New() 13 | // vm run 14 | vm.Run(` 15 | abc = 2 + 2; 16 | console.log("The value of abc is " + abc); // 4 17 | `) 18 | 19 | // get out of VM 20 | if value, err := vm.Get("abc"); err == nil { 21 | if value_int, err := value.ToInteger(); err == nil { 22 | fmt.Printf("", value_int, err) 23 | } 24 | } 25 | ``` 26 | 27 | ## js 执行引擎 rogchap.com/v8go 28 | 29 | [https://github.com/rogchap/v8go](https://github.com/rogchap/v8go) 30 | 31 | ```go 32 | import "rogchap.com/v8go" 33 | 34 | ctx, _ := v8go.NewContext(nil) // creates a new V8 context with a new Isolate aka VM 35 | ctx.RunScript("const add = (a, b) => a + b", "math.js") // executes a script on the global context 36 | ctx.RunScript("const result = add(3, 4)", "main.js") // any functions previously added to the context can be called 37 | val, _ := ctx.RunScript("result", "value.js") // return a value in JavaScript back to Go 38 | fmt.Printf("addition result: %s", val) 39 | ``` -------------------------------------------------------------------------------- /zh/05.2-lua引擎.md: -------------------------------------------------------------------------------- 1 | # lua 引擎 2 | 3 | ## lua编译运行引擎 github.com/yuin/gopher-lua 4 | 5 | [https://github.com/yuin/gopher-lua](https://github.com/yuin/gopher-lua) 6 | 7 | GopherLua is a Lua5.1 VM and compiler written in Go. 8 | GopherLua has a same goal with Lua: Be a scripting language with extensible semantics. 9 | -------------------------------------------------------------------------------- /zh/06.0-应用容器.md: -------------------------------------------------------------------------------- 1 | # 应用容器 2 | 3 | ## php应用APP容器 github.com/spiral/roadrunner 4 | 5 | - [https://github.com/spiral/roadrunner](https://github.com/spiral/roadrunner) 6 | - [https://roadrunner.dev/](https://roadrunner.dev/) 7 | 8 | 高性能PHP应用程序服务器,负载平衡器和进程管理器。 9 | 10 | - 支持 PHP-7 11 | - 支持 HTTPS and HTTP/2 12 | - 无依赖部署 13 | 14 | 核心依赖 go 库 [https://github.com/spiral/goridge](https://github.com/spiral/goridge) -------------------------------------------------------------------------------- /zh/10.0-基础工具.md: -------------------------------------------------------------------------------- 1 | # 基础工具 2 | 3 | 基础工具,是在编写golang过程中用到的各种工具 4 | 5 | # 编程辅助 6 | 7 | ## 语法提示器 gocode 8 | 9 | ```sh 10 | go get -u -v github.com/nsf/gocode 11 | ``` 12 | 13 | # 日志工具 14 | 15 | ## log4go 16 | 17 | [项目地址](https://github.com/alecthomas/log4go) 18 | 19 | - 安装 20 | 21 | ```sh 22 | go get -u -v github.com/alecthomas/log4go 23 | ``` 24 | 25 | - 基础使用 26 | 27 | 28 | 29 | ```go 30 | import ( 31 | l4g "github.com/alecthomas/log4go" 32 | ) 33 | 34 | // output in console, level debug 35 | l4g.AddFilter("stdout", l4g.DEBUG, l4g.NewConsoleLogWriter()) 36 | // log file output 37 | l4g.AddFilter("file", l4g.DEBUG, l4g.NewFileLogWriter("my.log", false)) 38 | l4g.Debug("your log in there") 39 | // use log.xml to Config log 40 | //l4g.LoadConfiguration("log.xml") 41 | // you must use this when main run over, unless your app run at anytime 42 | defer l4g.Close() 43 | ``` 44 | 45 | If you want setting your log file please use `log.xml` like this 46 | 47 | ```xml 48 | 49 | 50 | stdout 51 | console 52 | 53 | DEBUG 54 | 55 | 56 | file 57 | file 58 | FINEST 59 | my.log 60 | 71 | [%D %T] [%L] (%S) %M 72 | false 73 | 0M 74 | 0K 75 | true 76 | 77 | 78 | xmllog 79 | xml 80 | TRACE 81 | trace.xml 82 | true 83 | 100M 84 | 6K 85 | false 86 | 87 | 88 | donotopen 89 | socket 90 | FINEST 91 | 192.168.0.73:12124 92 | udp 93 | 94 | 95 | ``` 96 | 97 | 98 | # 测试工具 99 | 100 | ## github.com/cweill/gotests 测试模板生成工具 101 | 102 | ```sh 103 | go get -u -v github.com/cweill/gotests/... 104 | ``` 105 | 106 | [项目地址](https://github.com/cweill/gotests) 107 | 108 | 常用命令 109 | 110 | ```sh 111 | gotests -all -w gofile.go 112 | ``` 113 | 114 | ## github.com/bmizerany/assert assert 单元测试工具 115 | 116 | [项目地址](https://github.com/bmizerany/assert) 117 | 118 | - 安装 119 | 120 | ```sh 121 | go get -u github.com/bmizerany/assert 122 | ``` 123 | 124 | ### 使用方法 125 | 126 | 建立需要测试的类对应后缀 `类_test.go` 文件 127 | 128 | ```go 129 | package my_test 130 | 131 | import ( 132 | "testing" 133 | "github.com/bmizerany/assert" 134 | ) 135 | 136 | func TestAsserts(t *testing.T) { 137 | p1 := Point{1, 1} 138 | p2 := Point{2, 1} 139 | assert.Equal(t, p1, p2) 140 | } 141 | ``` 142 | 143 | 这样就可以直接运行对应这个单元测试的用例了,具体使用请查看github中的样例 144 | 145 | > 要求一定有`t *testing.T` 146 | 147 | ### 运行测试 148 | 149 | - 基准通过测试 150 | 151 | ```go 152 | go test -v 153 | # 指定哪个包被测试 154 | go test my_test -v 155 | # 指定哪一个子用例被测试 例如 TestAsserts 156 | go test -run TestAsserts 157 | ``` 158 | 159 | > 这里如果出现找不到包,请检查你的GOPATH路径 160 | 161 | - 性能测试 162 | 163 | ```go 164 | go test -test.bench=".*" 165 | ``` 166 | 167 | # 字符集转换工具 168 | 169 | ## axgle/mahonia 字符集转换工具 170 | 171 | character-set support 172 | 173 | - utf-8, latin-1, UTF-16LE, UTF-16BE, UTF-16 174 | - ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-7, ISO-8859-9 175 | - ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16 176 | - macintosh 177 | - windows-874, windows-1250, windows-1251, windows-1252, windows-1253 178 | - windows-1254, windows-1255, windows-1256, windows-1257, windows-1258 179 | - KOI8-R, KOI8-U 180 | - big5 181 | - gbk, gb18030 182 | - SJIS 183 | - EUC-JP 184 | 185 | https://github.com/axgle/mahonia 186 | 187 | ```golang 188 | go -u -v get github.com/axgle/mahonia 189 | ``` 190 | 191 | example 192 | 193 | ```golang 194 | package main 195 | import "fmt" 196 | import "github.com/axgle/mahonia" 197 | func main(){ 198 | enc:=mahonia.NewEncoder("gbk") 199 | //converts a string from UTF-8 to gbk encoding. 200 | fmt.Println(enc.ConvertString("hello,世界")) 201 | } 202 | ``` 203 | 204 | # Go GUI IDE 205 | 206 | ## andlabs/ui 207 | 208 | https://github.com/andlabs/ui 209 | 210 | 完全用Go编写的一个Golang IDE GUI程序,可以在各个系统中运行 211 | -------------------------------------------------------------------------------- /zh/10.1-命令行工具.md: -------------------------------------------------------------------------------- 1 | # 命令行工具 2 | 3 | ## urfave/cli 命令行 4 | 5 | 6 | 7 | ```sh 8 | go get github.com/urfave/cli 9 | ``` 10 | 11 | 这个命令行可以生成目标 cli 12 | 13 | ```go 14 | func main() { 15 | app := cli.NewApp() 16 | app.Name = "greet" 17 | app.Usage = "fight the loneliness!" 18 | app.Action = func(c *cli.Context) error { 19 | fmt.Println("Hello friend!") 20 | return nil 21 | } 22 | 23 | app.Run(os.Args) 24 | } 25 | ``` 26 | 27 | 也可以支持参数,标识等等,具体查看文档 28 | 29 | ## commander-cli/commander 30 | 31 | Test your command line interfaces on windows, linux and osx and nodes viá ssh and docker 32 | 33 | - [https://github.com/commander-cli/commander](https://github.com/commander-cli/commander) 34 | 35 | ```bash 36 | # Execute a specific suite 37 | $ ./commander test /tmp/test.yaml 38 | ``` 39 | 40 | this project is for use of [https://github.com/urfave/cli](https://github.com/urfave/cli) 41 | 42 | ## logrusorgru/aurora 输出命令行着色 43 | 44 | Ultimate ANSI colors for Golang. The package supports Printf/Sprintf 45 | 46 | - [https://github.com/logrusorgru/aurora](https://github.com/logrusorgru/aurora) 47 | 48 | 49 | ## commander-cli/cmd 全平台命令行执行 50 | 51 | execute shell commands on linux, darwin and windows. 52 | 53 | - [https://github.com/commander-cli/cmd](https://github.com/commander-cli/cmd) 54 | 55 | ```bash 56 | $ go mod edit -require=github.com/commander-cli/cmd@v1.3.0 57 | ``` 58 | 59 | - usage 60 | 61 | ```go 62 | c := cmd.NewCommand("echo hello") 63 | 64 | err := c.Execute() 65 | if err != nil { 66 | panic(err.Error()) 67 | } 68 | 69 | fmt.Println(c.Stdout()) 70 | fmt.Println(c.Stderr()) 71 | ``` 72 | 73 | ## mkideal/cli 简单命令行 74 | 75 | 76 | 77 | ```sh 78 | go get -u -v github.com/mkideal/cli 79 | ``` 80 | 81 | 使用文档见 82 | 83 | ## fsouza/go-dockerclient docker 客户端 84 | 85 | 86 | 87 | ```sh 88 | go get -u -v github.com/fsouza/go-dockerclient 89 | ``` 90 | 91 | docker 的go语言客户端,官方工具 92 | 93 | ## 富交互命令行工具 github.com/rivo/tview 94 | 95 | - [https://github.com/rivo/tview](https://github.com/rivo/tview) 96 | 97 | 效果图 98 | ![Screenshot](https://raw.githubusercontent.com/rivo/tview/master/tview.gif) 99 | 100 | Documentation [https://godoc.org/github.com/rivo/tview](https://godoc.org/github.com/rivo/tview) 101 | 102 | 103 | ## shirou/gopsutil 进程工具 104 | 105 | ```sh 106 | go get -v github.com/shirou/gopsutil 107 | ``` 108 | 109 | 进展状态监控工具 110 | 111 | https://github.com/shirou/gopsutil 112 | 113 | -------------------------------------------------------------------------------- /zh/10.2-传输工具.md: -------------------------------------------------------------------------------- 1 | # 传输工具 2 | 3 | ## jlaffaye/ftp FTP传输工具 4 | 5 | ```sh 6 | go get -u -v github.com/jlaffaye/ftp 7 | ``` 8 | 9 | - Use 10 | 11 | ```golang 12 | c, err := DialTimeout("localhost:21", 5*time.Second) 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | err = c.Login("anonymous", "anonymous") 17 | if err != nil { 18 | t.Fatal(err) 19 | } 20 | _, err = c.List(".") 21 | err = c.MakeDir("") 22 | ... 23 | ``` 24 | 25 | https://github.com/jlaffaye/ftp 26 | -------------------------------------------------------------------------------- /zh/11.0-序列化工具.md: -------------------------------------------------------------------------------- 1 | # 序列化工具 2 | 3 | 序列化是编程过程中,必然出现的一个操作,无论是序列化还是反序列化 4 | 5 | 常见的序列化有 转二进制 转xml 转json 等等 6 | 7 | # 多向序列化 8 | 9 | ## hcl2json 10 | 11 | - [https://github.com/pbar1/hcl2json](https://github.com/pbar1/hcl2json) 12 | 13 | ```bash 14 | docker run --rm pbar1/hcl2json -- --help 15 | ``` 16 | 17 | ## github.com/sclevine/yj 18 | 19 | - [yj](https://github.com/sclevine/yj) 20 | 21 | ```bash 22 | $ brew install yj 23 | ``` 24 | 25 | ## toml 26 | 27 | - [https://github.com/pelletier/go-toml#tools](https://github.com/pelletier/go-toml#tools) 28 | 29 | ```bash 30 | go install github.com/pelletier/go-toml/cmd/tomll 31 | tomll --help 32 | 33 | go install github.com/pelletier/go-toml/cmd/tomljson 34 | tomljson --help 35 | 36 | go install github.com/pelletier/go-toml/cmd/jsontoml 37 | jsontoml --help 38 | ``` 39 | 40 | ## json 序列化 41 | 42 | ### json2go 43 | 44 | [mohae/json2go](https://github.com/mohae/json2go) 45 | 46 | ```sh 47 | go get -u -v github.com/mohae/json2go/cmd/json2go 48 | # json to go 49 | $ go install github.com/mohae/json2go/cmd/json2go@latest 50 | $ json2go -h 51 | ``` 52 | 53 | 一款 json 转换成 golang struct 工具,支持复杂对象转换,安装后配置环境变量可以使用 54 | 55 | ```sh 56 | # 查看帮助 57 | json2go -h 58 | # 直接通过api转换为 golang struct 59 | curl -s https://api.github.com/repos/mohae/json2go | json2go -o example/github.go -w -a -n repo 60 | # 通过json 文件转换为 golang struct 61 | json2go -m -i hockey.json -o hockey.go 62 | # 生成golang struct 同时配置ymal 63 | json2go -m -i hockey.json -o hockey.go -n team -s player -t yaml -t db 64 | ``` 65 | 66 | 使用说明查看文档 https://github.com/mohae/json2go/blob/master/cmd/json2go/README.md 67 | 68 | ### tidwall/gjson 支持单个快速解析 json 69 | 70 | - [https://github.com/tidwall/gjson](https://github.com/tidwall/gjson) 71 | 72 | ```bash 73 | $ go mod edit -require=github.com/tidwall/gjson@v1.14.1 74 | ``` 75 | 76 | - simple useage 77 | 78 | ```go 79 | package main 80 | 81 | import "github.com/tidwall/gjson" 82 | 83 | const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}` 84 | 85 | func main() { 86 | value := gjson.Get(json, "name.last") 87 | println(value.String()) 88 | } 89 | ``` 90 | 91 | ### gig-simplejson 92 | 93 | [go-simplejson](https://github.com/bitly/go-simplejson) 94 | 95 | ```sh 96 | go get -u github.com/bitly/go-simplejson 97 | ``` 98 | 99 | [使用文档](http://godoc.org/github.com/bitly/go-simplejson) 100 | 101 | ### buger/jsonparser 102 | 103 | [buger/jsonparser](https://github.com/buger/jsonparser) 104 | 105 | - 功能试验中,不建议生产使用 106 | 107 | ### donnie4w/json4g 108 | 109 | [donnie4w/json4g](https://github.com/donnie4w/json4g) 110 | 111 | golang 的 json处理库 112 | json4g 提供了json的简便处理方法 113 | 具体操作请参考 测试类 https://github.com/donnie4w/json4g/blob/master/json4g_test.go 114 | 115 | 116 | ### gojson 117 | 118 | [ChimeraCoder/gojson](https://github.com/ChimeraCoder/gojson) 119 | 120 | ```sh 121 | go get -u github.com/ChimeraCoder/gojson/gojson 122 | ``` 123 | 124 | 同样作为序列化工具可以将json数据转化为 golang struct 这个库的风格是下划线分割 125 | 126 | 使用说明文档 https://github.com/ChimeraCoder/gojson/blob/master/README.md 127 | 128 | ### dutchcoders/XMLGen 129 | 130 | [dutchcoders/XMLGen](https://github.com/dutchcoders/XMLGen) 131 | 132 | ```sh 133 | brew tap dutchcoders/homebrew-xmlgen 134 | brew install xmlgen 135 | ``` 136 | 137 | 用于将XML流解析成Golang的模板对象 138 | 139 | ```sh 140 | Usage of xmlgen: 141 | -dump="NUL": Dump tree structure to file. 142 | -normalize=true: Squash arrays of struct and determine primitive array type. 143 | -title=true: Convert identifiers to title case, treating '_' and '-' as word boundaries. 144 | ``` 145 | 146 | ## msgpack 序列化 147 | 148 | ### shamaton/msgpackgen 149 | 150 | - [https://github.com/shamaton/msgpackgen](https://github.com/shamaton/msgpackgen) 151 | 152 | ```bash 153 | $ go install github.com/shamaton/msgpackgen@v0.3.0 154 | $ msgpackgen -h 155 | ``` 156 | 157 | ### shamaton/msgpack 158 | 159 | - [https://github.com/shamaton/msgpack](https://github.com/shamaton/msgpack) 160 | 161 | ```bash 162 | $ go list -m -mod=readonly -versions github.com/shamaton/msgpack/v2 163 | $ go mod edit -require=github.com/shamaton/msgpack/v2@v2.1.1 164 | ``` 165 | 166 | - usage 167 | 168 | ```go 169 | package main 170 | 171 | import ( 172 | "github.com/shamaton/msgpack/v2" 173 | ) 174 | 175 | func main() { 176 | type Struct struct { 177 | String string 178 | } 179 | v := Struct{String: "msgpack"} 180 | 181 | d, err := msgpack.Marshal(v) 182 | if err != nil { 183 | panic(err) 184 | } 185 | r := Struct{} 186 | err = msgpack.Unmarshal(d, &r) 187 | if err != nil { 188 | panic(err) 189 | } 190 | } 191 | ``` 192 | 193 | ## yaml 194 | 195 | ### PrasadG193/yaml2go 196 | 197 | - [https://github.com/PrasadG193/yaml2go](https://github.com/PrasadG193/yaml2go) 198 | 199 | ```bash 200 | # yaml to go 201 | $ go get -u github.com/PrasadG193/yaml2go 202 | $ go build -o yaml2go github.com/PrasadG193/yaml2go/cmd/cli 203 | $ mv yaml2go ~/go/bin 204 | 205 | $ yaml2go --help 206 | yaml2go converts YAML specs to Go type definitions 207 | 208 | Usage: 209 | yaml2go < /path/to/yamlspec.yaml 210 | 211 | Examples: 212 | yaml2go < test/example1.yaml 213 | yaml2go < test/example1.yaml > example1.go 214 | ``` 215 | 216 | ## FlatBuffer 217 | 218 | ### google/flatbuffers 219 | 220 | https://github.com/google/flatbuffers 221 | 222 | ```sh 223 | go get -u -v github.com/google/flatbuffers/go 224 | ``` 225 | 226 | #### install FlatBuffers by binary 227 | 228 | - OS X 229 | 230 | ```sh 231 | brew install flatbuffers 232 | ``` 233 | 234 | - windows 235 | 236 | https://github.com/google/flatbuffers/releases 237 | 238 | [FlatBuffers-1.3.0](https://github.com/google/flatbuffers/releases/download/v1.3.0/flatc_windows_exe.zip) 239 | 240 | - Linux 241 | 242 | ```sh 243 | git clone https://github.com/google/flatbuffers.git 244 | cd flatbuffers 245 | cmake -G "Unix Makefiles" 246 | make 247 | ``` 248 | 249 | and use `./flatc` 250 | 251 | #### install FlatBuffers by build 252 | 253 | ```sh 254 | git clone https://github.com/google/flatbuffers.git 255 | cd flatbuffers 256 | ``` 257 | 258 | - for you platform 259 | 260 | ```sh 261 | cmake -G "Unix Makefiles" 262 | cmake -G "Visual Studio 10" 263 | cmake -G "Xcode" 264 | ``` 265 | 266 | -then get build out 267 | 268 | 269 | #### Use document 270 | 271 | http://google.github.io/flatbuffers/md__go_usage.html 272 | 273 | 274 | 275 | ## iso8583 276 | 277 | - wiki of iso8583 https://en.wikipedia.org/wiki/ISO_8583 278 | 279 | ```sh 280 | go get -v github.com/ideazxy/iso8583 281 | ``` 282 | 283 | more use see https://github.com/ideazxy/iso8583 284 | 285 | -------------------------------------------------------------------------------- /zh/11.1-SQL映射工具.md: -------------------------------------------------------------------------------- 1 | # SQL映射工具 2 | 3 | ## github.com/jmoiron/sqlx SQL增强 4 | 5 | [https://github.com/jmoiron/sqlx](https://github.com/jmoiron/sqlx) 6 | 7 | ```bash 8 | # see version of repo 9 | $ git ls-remote -q https://github.com/jmoiron/sqlx.git 10 | # see versions golang can use 11 | $ go list -v -m -versions github.com/jmoiron/sqlx 12 | # use go mod 13 | $ go mod edit -require=$(go list -m -mod=readonly -versions github.com/jmoiron/sqlx | awk '{print $1 "@" $NF}') 14 | $ go mod vendor 15 | ``` 16 | 17 | - 增强SQL使用 18 | 19 | 官方例子 20 | [https://github.com/jmoiron/sqlx/blob/master/sqlx_test.go](https://github.com/jmoiron/sqlx/blob/master/sqlx_test.go) 21 | 22 | 23 | ## github.com/Masterminds/squirrel SQL生成 24 | 25 | [https://github.com/Masterminds/squirrel](https://github.com/Masterminds/squirrel) 26 | 27 | ```bash 28 | # see version of repo 29 | $ git ls-remote -q https://github.com/Masterminds/squirrel.git 30 | # see versions golang can use 31 | $ go list -v -m -versions github.com/Masterminds/squirrel 32 | # use go mod 33 | $ go mod edit -require=$(go list -m -mod=readonly -versions github.com/Masterminds/squirrel | awk '{print $1 "@" $NF}') 34 | $ go mod vendor 35 | ``` 36 | 37 | - 生成器ORM还是要复杂 38 | - 比裸写SQL不容易出SQL注入问题 39 | - 如果使用 Values 绑定 struct ,这个库使用反射 40 | 41 | 这个库配合 sqlx 可以制作非常方便的生成器 42 | 43 | ```go 44 | var db *sqlx.DB 45 | 46 | // Insert table app_info 47 | func InsertAppInfo(p AppInfo) (int64, error) { 48 | now := time.Now() 49 | 50 | sql, args, err := squirrel.Insert("app_info").Columns( 51 | "created_at", "modify_at", "app", "operator_id", "tag", "content", "comment_count", 52 | ).Values(now, now, p.App, p.OperatorID, p.Tag, p.Content, p.CommentCount).ToSql() 53 | if err != nil { 54 | return 0, err 55 | } 56 | 57 | return db.MustExec(sql, args...).LastInsertId() 58 | } 59 | ``` 60 | 61 | ## xorm ORM 映射 62 | 63 | [xormplus/xorm](go get -u github.com/xormplus/xorm) 64 | 65 | xorm 是一个简单而强大的 Go 语言 ORM 库,通过它可以使数据库操作非常简便。 66 | 基于原版 xorm 的定制增强版本,为 xorm 提供类似 ibatis 的配置文件及动态 SQL 支持,支持 AcitveRecord 操作 67 | 68 | 使用说明文档 https://github.com/xormplus/xorm/blob/master/README.md 69 | 70 | 这个活用可以作为注入检查工具 71 | 72 | ### xorm 辅助工具 73 | 74 | [xormplus/tools](https://github.com/xormplus/tools) 75 | 76 | - xorm 的辅助工具,工具目前主要提供 xorm 的 SqlMap 配置文件和 SqlTemplate 模板批量加密功能,Json 转 Struct 功能,Xml 转 Struct 功能。 77 | - 目前支持 AES,DES,3DES,RSA 四种加密算法。其中 AES,DES,3DES 并非标准实现,有内置补足 key,与[https://github.com/xormplus/xorm](https://github.com/xormplus/xorm) 库中的解密算法对应。 78 | - 工具使用[Sciter](http://sciter.com/)的 Golang 绑定库 [sciter](https://github.com/oskca/sciter) 开发。由于主要是试用 Sciter,所以逻辑相关的代码组织的并不是很规整,例如有些方法明显可以抽成接口方式。 79 | 80 | ![](http://i.imgur.com/YxI3QE3.png) 81 | 82 | 83 | ### go-gorm/soft_delete 84 | 85 | [go-gorm/soft_delete](https://github.com/go-gorm/soft_delete) 86 | 87 | gorm 的软删除插件 88 | 89 | - [对 gorm 的软删除](https://gorm.io/docs/delete.html#Soft-Delete) 增强 90 | - 软删除 时间戳/Integer格式 兼容秒值/毫秒值 -------------------------------------------------------------------------------- /zh/11.2-WebSokcet.md: -------------------------------------------------------------------------------- 1 | # WebSokcet 2 | 3 | ## gorilla/websocket 4 | 5 | ```sh 6 | go get -u -v github.com/gorilla/websocket 7 | ``` 8 | 9 | 特性 10 | 11 | - 支持接收分段消息 12 | - 可发送关闭消息 13 | - 支持心跳消息 14 | - 支持获取消息数据类型 15 | - 可限制收到的最大消息长度 16 | - 支持io.Reader读取消息 17 | - 支持io.WriteCloser写消息 18 | 19 | 仓库地址 20 | 21 | https://github.com/gorilla/websocket 22 | 23 | 使用范例 24 | 25 | https://github.com/gorilla/websocket/tree/master/examples 26 | 27 | 附录 WebSocket 协议规范 https://tools.ietf.org/html/rfc6455 28 | -------------------------------------------------------------------------------- /zh/11.3-解析工具.md: -------------------------------------------------------------------------------- 1 | # 解析工具 2 | 3 | ## goquery html 解析 4 | 5 | [github.com/PuerkitoBio/goquery](https://github.com/PuerkitoBio/goquery) 6 | 7 | ```sh 8 | go get -u -v github.com/PuerkitoBio/goquery 9 | ``` 10 | 11 | 测试运行 12 | 13 | ```sh 14 | $ cd $GOPATH/src/github.com/PuerkitoBio/goquery 15 | $ go test -bench=".*" 16 | ``` 17 | 18 | 基础使用 19 | 20 | ```golang 21 | func ExampleScrape() { 22 | doc, err := goquery.NewDocument("http://metalsucks.net") 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | 27 | // Find the review items 28 | doc.Find(".sidebar-reviews article .content-block").Each(func(i int, s *goquery.Selection) { 29 | // For each item found, get the band and title 30 | band := s.Find("a").Text() 31 | title := s.Find("i").Text() 32 | fmt.Printf("Review %d: %s - %s\n", i, band, title) 33 | }) 34 | } 35 | ``` 36 | 37 | 完全使用文档见 https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks 38 | 39 | ## tinydom XML-DOM 解析 40 | 41 | ```sh 42 | go get -u -v github.com/tinyhubs/tinydom 43 | ``` 44 | 45 | 使用方法见 https://tinyhubs.github.io/tinydom/ 46 | -------------------------------------------------------------------------------- /zh/11.4-验证工具.md: -------------------------------------------------------------------------------- 1 | # 验证工具 2 | 3 | ## gookit/validate 基于反射的参数验证 4 | 5 | [https://github.com/gookit/validate](https://github.com/gookit/validate) 6 | 7 | Go通用的数据验证与过滤库,使用简单,内置大部分常用验证、过滤器,支持自定义验证器、自定义消息、字段翻译 8 | 9 | ```bash 10 | GO111MODULE=on go mod edit -require=github.com/gookit/validate@v1.1.3 11 | GO111MODULE=on go mod download 12 | GO111MODULE=on go mod vendor 13 | ``` 14 | 15 | - use 16 | 17 | ```golang 18 | import ( 19 | "github.com/gookit/validate" 20 | ) 21 | 22 | // UserForm struct 23 | type UserForm struct { 24 | Name string `validate:"required|minLen:7"` 25 | Email string `validate:"email"` 26 | Age int `validate:"required|int|min:1|max:99"` 27 | CreateAt int `validate:"min:1"` 28 | Safe int `validate:"-"` 29 | UpdateAt time.Time `validate:"required"` 30 | Code string `validate:"customValidator"` 31 | } 32 | 33 | // CustomValidator custom validator in the source struct. 34 | func (f UserForm) CustomValidator(val string) bool { 35 | return len(val) == 4 36 | } 37 | 38 | // Messages you can custom validator error messages. 39 | func (f UserForm) Messages() map[string]string { 40 | return validate.MS{ 41 | "required": "oh! the {field} is required", 42 | "Name.required": "message for special field", 43 | } 44 | } 45 | 46 | // Translates you can custom field translates. 47 | func (f UserForm) Translates() map[string]string { 48 | return validate.MS{ 49 | "Name": "User Name", 50 | "Email": "User Email", 51 | } 52 | } 53 | 54 | func Test_UserForm(t t *testing.T){ 55 | u := &UserForm{ 56 | Name: "inhere", 57 | } 58 | v := validate.Struct(u) 59 | 60 | if v.Validate() { // validate ok 61 | // do something ... 62 | } else { 63 | fmt.Println(v.Errors) // all error messages 64 | fmt.Println(v.Errors.One()) // returns a random error message text 65 | fmt.Println(v.Errors.Field("Name")) // returns error messages of the field 66 | } 67 | } 68 | 69 | ``` -------------------------------------------------------------------------------- /zh/11.5-Web模板.md: -------------------------------------------------------------------------------- 1 | # Web模板 2 | 3 | ## flosch/pongo2 Django风格模板 4 | 5 | Django-syntax like templating-language 6 | 7 | - [github https://github.com/flosch/pongo2](https://github.com/flosch/pongo2) 8 | -------------------------------------------------------------------------------- /zh/12.0-微服务工具.md: -------------------------------------------------------------------------------- 1 | # 微服务工具 2 | 3 | ## RPC服务 4 | 5 | ### 可插拔的RPC服务 go-micro 6 | 7 | 项目地址 https://github.com/micro/go-micro 8 | 9 | - 介绍 10 | 基于微服务库的可插拔 RPC,为编写分布式应用程序提供基本构件。它是[Micro](https://github.com/micro/micro)工具包的一部分,支持 Proto-RPC 和 JSON-RPC 的请求/响应协议,默认设置Consul为探索 11 | 12 | 使用时先安装 [InstallConsul](https://www.consul.io/intro/getting-started/install.html) 13 | 14 | - 特点 15 | 16 | |特征|包|内置插件|描述| 17 | |---|---|---|---| 18 | |Discovery|[Registry](https://godoc.org/github.com/micro/go-micro/registry)|consul|用来沟通的一种定位服务方式| 19 | |Client|[Client](https://godoc.org/github.com/micro/go-micro/client)|rpc|用来将RPC请求变成服务| 20 | |Codec|[Codec](https://godoc.org/github.com/micro/go-micro/codec)|proto,json|对请求进行编码/解码处理| 21 | |Balancer|[Selector](https://godoc.org/github.com/micro/go-micro/selector)|random|服务节点过滤和池| 22 | |Server|[Server](https://godoc.org/github.com/micro/go-micro/server)|rpc|监听和服务器的RPC请求| 23 | |Pub/Sub|[Broker](https://godoc.org/github.com/micro/go-micro/broker)|http|发布和订阅事件| 24 | |ransport|[Transport](https://godoc.org/github.com/micro/go-micro/transport)|http|服务之间的通信机制| 25 | 26 | - 必备条件 27 | 需要一个服务发现机制来解决服务的名称到地址的映射,默认设置Consul为探索。 28 | Discovery是可插拔的,你可以使用 kubernetes, zookeeper 等 29 | 30 | ```sh 31 | # 运行Consul 32 | consul agent -dev -advertise=127.0.0.1 33 | # 运行go-micro 34 | go run examples/service/main.go 35 | # 测试服务 36 | go run examples/service/main.go --client 37 | ``` 38 | 39 | - 使用示例项目 40 | 41 | |项目|描述| 42 | |---|---| 43 | |[greeter](https://github.com/micro/micro/tree/master/examples/greeter)|greeter 服务(包括 Go、Ruby、Python )| 44 | |[geo-srv](https://github.com/micro/geo-srv)|使用 hailocab/go-geoindex 进行地理位置跟踪服务| 45 | |[geo-api](https://github.com/micro/geo-api)|为地理位置跟踪和搜索提供的 HTTP API 处理程序| 46 | |[geocode-srv](https://github.com/micro/geocode-srv)|使用 Google Geocoding API 提供地理编码服务| 47 | |[hailo-srv](https://github.com/micro/hailo-srv)|一种用于hailo出租车服务开发者的api服务| 48 | |[place-srv](https://github.com/micro/place-srv)|存储和检索地点的微服务| 49 | |[slack-srv](https://github.com/micro/slack-srv)|将Slack机器人的API当成一个go-micro 的RPC服务| 50 | |[twitter-srv](https://github.com/micro/twitter-srv)|一种用于Twitter的API微服务| 51 | |[user-srv](https://github.com/micro/user-srv)|一种为用户管理和认证提供的微服务| 52 | 53 | ## go-kit 54 | 55 | https://github.com/go-kit/kit 56 | 57 | 组件化,可扩展微服务工具集,非常适合领域驱动的微服务 58 | 59 | go-kit 分为 三层 60 | 61 | - Transport层 传输协议相关 62 | - Endpoint层 负责request/response格式的转换,以及公用拦截器相关的逻辑 63 | - Service层 专注于业务逻辑 64 | 65 | > endpoint层提供了很多公用的拦截器,如log,metric,tracing,circuitbreaker,rate-limiter 66 | 67 | 如果已有项目的模版是分为三层:router,service和dao 68 | 且之前的代码中router层不能包含任何业务逻辑 69 | 集成到go-kit也分为三层,可以根据每层职责的不同进行重新组合,从上到下依次为:transport层,endpoint层,service层,dao层 70 | 71 | 72 | 73 | 74 | > 当然你如果哪天因为某种原因,不想再继续使用go-kit这套东西,直接將endpoint层和Transport层移除即可 75 | 76 | 集成过程必须满足 77 | 78 | - 单一职责原则 79 | - 开放封闭原则 80 | - 依赖倒置原则 81 | - 接口隔离原则 82 | 83 | -------------------------------------------------------------------------------- /zh/12.1-持久化工具.md: -------------------------------------------------------------------------------- 1 | # 持久化工具 2 | 3 | ## mongo-driver/mongo mongo官方驱动 4 | 5 | [项目地址](https://github.com/mongodb/mongo-go-driver) 6 | 7 | 使用要求 8 | 9 | - Go 1.10 or higher 10 | - MongoDB 2.6 and higher 11 | 12 | ```bash 13 | dep ensure -v -add "go.mongodb.org/mongo-driver/mongo@~1.0.0" 14 | ``` 15 | 16 | 17 | 18 | ## yiigo golang 辅助库 19 | 20 | 支持 MySQL PostgreSQL mongo redis gomail toml sqlx zap 这些涉及持久化的工具 21 | 22 | [项目地址](https://github.com/iiinsomnia/yiigo/tree/v3) 23 | 24 | - 支持多 [MySQL](https://github.com/go-sql-driver/mysql) 连接 25 | - 支持多 [PostgreSQL](https://github.com/lib/pq) 连接 26 | - 支持多 [mongo](https://github.com/mongodb/mongo-go-driver) 连接 27 | - 支持多 [redis](https://github.com/gomodule/redigo) 连接 28 | - 支持 [gomail](https://github.com/go-gomail/gomail) 邮件发送 29 | - 支持 [toml](https://github.com/pelletier/go-toml) 文件配置 30 | - 采用 [sqlx](https://github.com/jmoiron/sqlx) 处理SQL查询 31 | - 采用 [zap](https://github.com/uber-go/zap) 日志记录 32 | 33 | [文档地址](https://godoc.org/github.com/iiinsomnia/yiigo) 34 | 35 | ## kiteq 多种持久化方案的mq框架 36 | 37 | [项目地址](https://github.com/blackbeans/kiteq) 38 | 39 | 介绍 40 | 41 | - 基于zk/etcd维护发送方、订阅方、broker订阅发送关系、支持水平、垂直方面的扩展 42 | - 基于与topic以及第二级messageType订阅消息 43 | - 基于mysql、文件存储方式多重持久层消息存储 44 | - 保证可靠异步投递 45 | - 支持两阶段提交分布式事务 46 | - 自定义group内的Topic级别的流控措施,保护订阅方安全 47 | - kiteserver的流量保护 48 | 49 | 概念 50 | 51 | - Binding:订阅关系,描述订阅某种消息类型的数据结构 52 | - Consumer : 消息的消费方 53 | - Producer : 消息的发送方 54 | - Topic: 消息的主题比如 Trade则为消息主题,一般可以定义为某种业务类型 55 | - MessageType: 第二级别的消息类型,比如Trade下存在支付成功的pay-succ-200的消息类型 56 | 57 | ### Use 58 | 59 | - 编译安装 60 | 61 | ```sh 62 | get clone git@github.com:blackbeans/kiteq.git 63 | cd kiteq 64 | build.sh 65 | ``` 66 | 67 | 安装装Zookeeper:省略(或者安装etcd) 68 | 69 | 修改文件 `kiteq.sh` 70 | 71 | ```sh 72 | ./kiteq -clusterName=集群名称 -configPath=配置文件路径 73 | ./kiteq -bind=172.30.3.124:13800 -pport=13801 -db="mock://kiteq" -topics=trade,feed -zkhost=localhost:2181 74 | ``` 75 | 76 | -bind //绑定本地IP:Port 77 | -pport //pprof的Http端口 78 | -db //存储的协议地址 mock:// 启动mock模式 mysql:// mmap:// 79 | -topics //本机可以处理的topics列表逗号分隔 80 | -zkhost //zk的地址 81 | 82 | 文件样例见[conf/cluster.toml](https://raw.githubusercontent.com/blackbeans/kiteq/master/conf/cluster.toml) 83 | 84 | - 使用 85 | 86 | go客户端使用 87 | 88 | KiteQClient需要实现消息监听器 89 | 90 | ```golang 91 | type IListener interface { 92 | //接受投递消息的回调 93 | OnMessage(msg *protocol.StringMessage) bool 94 | //接收事务回调 95 | // 除非明确提交成功、其余都为不成功 96 | // 有异常或者返回值为false均为不提交 97 | OnMessageCheck(tx *protocol.TxResponse) error 98 | } 99 | ``` 100 | 101 | 启动Producer 102 | 103 | ```golang 104 | producer := client.NewKiteQClient(${zkhost}, ${groupId}, ${password}, &defualtListener{}) 105 | producer.SetTopics([]string{"trade"}) 106 | producer.Start() 107 | //构建消息 108 | msg := &protocol.StringMessage{} 109 | msg.Header = &protocol.Header{ 110 | MessageId: proto.String(store.MessageId()), 111 | Topic: proto.String("trade"), 112 | MessageType: proto.String("pay-succ"), 113 | ExpiredTime: proto.Int64(time.Now().Unix()), 114 | DeliveryLimit: proto.Int32(-1), 115 | GroupId: proto.String("go-kite-test"), 116 | Commit: proto.Bool(true)} 117 | msg.Body = proto.String("echo") 118 | //发送消息 119 | producer.SendStringMessage(msg) 120 | ``` 121 | 122 | 123 | 启动Consumer 124 | 125 | ```golang 126 | consumer:= client.NewKiteQClient(${zkhost}, ${groupId}, ${password}, &defualtListener{}) 127 | consumer.SetBindings([]*binding.Binding{ 128 | binding.Bind_Direct("s-mts-test", "trade", "pay-succ", 1000, true), 129 | }) 130 | consumer.Start() 131 | ``` 132 | 133 | ## blackbeans/flume-bridge flume的go语言客户端 134 | 135 | 使用redis作为缓存,zk作为服务发现,作为分布式的内容,协议使用thrift 136 | 137 | use redis queue integration thrift 138 | Server lookup use zk 139 | 140 | https://github.com/blackbeans/flume-bridge 141 | -------------------------------------------------------------------------------- /zh/12.2-连接中间件.md: -------------------------------------------------------------------------------- 1 | # 连接中间件 2 | 3 | ## Apache Kafka 连接中间件 Shopify/sarama 4 | 5 | https://github.com/Shopify/sarama 6 | 7 | - 最低支持 Kafka version 0.8 8 | - MIT-licensed 9 | 10 | - 支持 ConsumerGroup 11 | 12 | 需要版本在 v1.19.0 以上即可,版本信息 13 | https://github.com/Shopify/sarama/releases/tag/v1.19.0 -------------------------------------------------------------------------------- /zh/12.3-认证模块.md: -------------------------------------------------------------------------------- 1 | # 认证模块 2 | 3 | ## 认证服务 4 | 5 | ### github.com/casbin/casbin casbin 授权库 6 | 7 | https://github.com/casbin/casbin 8 | 9 | supports access control models like ACL, RBAC, ABAC 10 | 11 | - doc https://casbin.org/docs/en/overview 12 | 13 | - Tutorials https://casbin.org/docs/en/tutorials 14 | 15 | ## oauth2.0 模块 16 | 17 | http://oauth.net/ 18 | 19 | golang 相关优秀实现 20 | 21 | - golang/oauth2 https://github.com/golang/oauth2 22 | - martini-contrib/oauth2 https://github.com/martini-contrib/oauth2 23 | - go-macaron/oauth2 https://github.com/go-macaron/oauth2 24 | 25 | 其中,golang/oauth2 是官方实现 26 | 27 | ```sh 28 | go get -v golang.org/x/oauth2 29 | ``` 30 | 31 | 另外2个依赖 32 | 33 | - [martini](https://github.com/go-martini/martini) 34 | - [macaron](https://github.com/go-macaron/macaron) 35 | 36 | ## jwt-go 37 | 38 | JSON Web Token 工具库,支持模式有 HMAC SHA, RSA, RSA-PSS, and ECDSA 39 | 40 | https://github.com/dgrijalva/jwt-go 41 | 42 | 可用于开放认证,提供CLI工具 43 | https://github.com/dgrijalva/jwt-go/tree/master/cmd/jwt 44 | 45 | ### jwt-go error 46 | 47 | ```sh 48 | type jwt.Claims does not support indexing 49 | ``` 50 | 51 | beacuse api change [migration-guide-from-v2---v3](https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md#migration-guide-from-v2---v3) 52 | 53 | ```sh 54 | if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { 55 | claims := token.Claims.(jwt.MapClaims) 56 | fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) 57 | } 58 | ``` 59 | 60 | 61 | -------------------------------------------------------------------------------- /zh/12.4-验证码.md: -------------------------------------------------------------------------------- 1 | # 验证码 2 | 3 | ## dchest/captcha 图片声音验证模块 4 | 5 | https://github.com/dchest/captcha 6 | 7 | ```sh 8 | go get -u -v github.com/dchest/captcha 9 | ``` 10 | 11 | 你可以使用官方的函数 ,这里演示的是beego中的使用 12 | 13 | https://github.com/astaxie/beego/blob/master/utils/captcha 14 | 15 | ```golang 16 | cpt = captcha.NewWithFilter("/captcha/", store) 17 | value, err := cpt.CreateCaptcha() 18 | imgUrl := fmt.Sprintf("YouHost/%s%s.png", c.URLPrefix,value) 19 | fmt.Printf("Inmage url is %v\n", imgUrl) 20 | ``` 21 | -------------------------------------------------------------------------------- /zh/12.5-服务监控.md: -------------------------------------------------------------------------------- 1 | # 服务监控 2 | 3 | ## opentracing-go 分布式链路追踪 4 | 5 | [github.com/opentracing/opentracing-go](https://github.com/opentracing/opentracing-go) 6 | 7 | 官方页面 http://opentracing.io 8 | 9 | 10 | ## Jaeger 链路追踪 11 | 12 | [jaegertracing/jaeger](https://github.com/jaegertracing/jaeger) 13 | 14 | - 基于 Opentracing 规范 15 | - 更适合基于 docker kubernetes 的服务管理 16 | - 提供多语言的 SDK 接入,非常方便监控链路状态 17 | 18 | 简单demo可以直接这样运行 19 | 20 | ```bash 21 | docker run -d --name jaeger \ 22 | -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ 23 | -p 5775:5775/udp \ 24 | -p 6831:6831/udp \ 25 | -p 6832:6832/udp \ 26 | -p 5778:5778 \ 27 | -p 16686:16686 \ 28 | -p 14268:14268 \ 29 | -p 9411:9411 \ 30 | jaegertracing/all-in-one:latest 31 | ``` 32 | 33 | 访问 http://localhost:16686就能看到 jaeger的数据查询页 -------------------------------------------------------------------------------- /zh/12.6-服务器运行监视工具.md: -------------------------------------------------------------------------------- 1 | # 服务器运行监视工具 2 | 3 | ## divan/expvarmon 可视化监视服务运行状态工具 4 | 5 | ```golang 6 | go get -u -v github.com/divan/expvarmon 7 | ``` 8 | 9 | https://github.com/divan/expvarmon 10 | 11 | ## hashicorp/consul 微服务调度控制工具 12 | 13 | linux 安装 14 | 15 | ```sh 16 | $ mkdir -p $GOPATH/src/github.com/hashicorp 17 | $ cd $GOPATH/src/github.com/hashicorp 18 | $ git clone https://github.com/hashicorp/consul.git 19 | $ cd consul 20 | $ make 21 | ``` 22 | 23 | 使用 24 | 25 | ```sh 26 | $ $GOPATH/bin/consul 27 | ``` 28 | 29 | https://github.com/hashicorp/consul 30 | 31 | 完整文档 32 | 33 | https://www.consul.io/docs 34 | 35 | ## prometheus/prometheus 服务器系统状态监视工具 36 | 37 | 持续更新的工具,直接使用监视服务器本身状态 38 | 39 | 官方站点 https://prometheus.io/ 40 | 41 | - use docker 42 | 43 | ```sh 44 | docker run --name prometheus -d -p 127.0.0.1:9090:9090 quay.io/prometheus/prometheus 45 | ``` 46 | 47 | - build local 48 | 49 | ```sh 50 | $ mkdir -p $GOPATH/src/github.com/prometheus 51 | $ cd $GOPATH/src/github.com/prometheus 52 | $ git clone https://github.com/prometheus/prometheus.git 53 | $ cd prometheus 54 | $ make build 55 | $ ./prometheus -config.file=your_config.yml 56 | ``` 57 | 58 | https://github.com/prometheus/prometheus 59 | 60 | ## influxdata/telegraf 服务监视报警工具 61 | 62 | - plugin more and more 63 | 64 | https://github.com/influxdata/telegraf 65 | 66 | ## mackerelio/mackerel-agent 服务监视工具 67 | 68 | ```sh 69 | go get -d github.com/mackerelio/mackerel-agent 70 | go build -o build/mackerel-agent \ 71 | -ldflags="\ 72 | -X github.com/mackerelio/mackerel-agent/version.GITCOMMIT `git rev-parse --short HEAD` \ 73 | -X github.com/mackerelio/mackerel-agent/version.VERSION `git describe --tags --abbrev=0 | sed 's/^v//' | sed 's/\+.*$$//'` " \ 74 | github.com/mackerelio/mackerel-agent 75 | ./build/mackerel-agent -conf=mackerel-agent.conf 76 | ``` 77 | 78 | https://github.com/mackerelio/mackerel-agent 79 | 80 | ## cloudinsight/cloudinsight-agent 服务监视报警工具 81 | 82 | ```sh 83 | go get -d github.com/cloudinsight/cloudinsight-agent 84 | cd $GOPAH/src/github.com/cloudinsight/cloudinsight-agent 85 | make build 86 | ``` 87 | 88 | https://github.com/cloudinsight/cloudinsight-agent 89 | 90 | ## fgeller/kt kafka 监控命令行工具 91 | 92 | install as binary 93 | 94 | ```sh 95 | # most os 96 | $ go get -u github.com/fgeller/kt 97 | # macOS 98 | $ brew tap fgeller/tap 99 | $ brew install kt 100 | ``` 101 | 102 | usage: 103 | 104 | ```sh 105 | $ kt -help 106 | kt is a tool for Kafka. 107 | 108 | Usage: 109 | 110 | kt command [arguments] 111 | 112 | The commands are: 113 | 114 | consume consume messages. 115 | produce produce messages. 116 | topic topic information. 117 | group consumer group information and modification. 118 | admin basic cluster administration. 119 | 120 | Use "kt [command] -help" for for information about the command. 121 | ``` 122 | 123 | https://github.com/fgeller/kt 124 | -------------------------------------------------------------------------------- /zh/12.7-分布式锁.md: -------------------------------------------------------------------------------- 1 | # 分布式锁 2 | 3 | ## github.com/go-redsync/redsync 4 | 5 | Distributed mutual exclusion lock using Redis for Go 6 | 7 | 为直接封装了 Redis官方分布式锁的实现 Redlock 8 | 支持2种驱动 [Redigo](https://github.com/gomodule/redigo) 或者 [Go-redis](https://github.com/go-redis/redis) 9 | 10 | 注意 11 | 12 | 1. red-lock 得你单独拎出1台以上的相互独立的redis出来,也就是它们间没有任务联系。 13 | 14 | > 这有点尴尬,所以redis去实现分布式锁你最好再想个兜底的,比如说用 mysql 多版本再原子性的控制一下(之所以说mysql是因为一般的项目都有mysql+redis) 15 | 16 | 2. 这个包里面的 lock 并不像我们 go源码里面的 17 | 18 | ```go 19 | m :=sync.Mutex{} 20 | m.Lock() 21 | ``` 22 | 它在尝试一定抢锁次数之后会返回err,业务里面记得根据err做对应处理! 23 | 24 | - [https://github.com/go-redsync/redsync](https://github.com/go-redsync/redsync) 25 | 26 | ```bash 27 | $ go list -mod=readonly -m -versions github.com/go-redsync/redsync/v4 28 | $ go mod edit -require=github.com/go-redsync/redsync/v4@v4.0.4 29 | ``` 30 | 31 | - usage 32 | 33 | ```go 34 | package main 35 | 36 | import ( 37 | goredislib "github.com/go-redis/redis/v8" 38 | "github.com/go-redsync/redsync/v4" 39 | "github.com/go-redsync/redsync/v4/redis/goredis/v8" 40 | ) 41 | 42 | func main() { 43 | // Create a pool with go-redis (or redigo) which is the pool redisync will 44 | // use while communicating with Redis. This can also be any pool that 45 | // implements the `redis.Pool` interface. 46 | client := goredislib.NewClient(&goredislib.Options{ 47 | Addr: "localhost:6379", 48 | }) 49 | pool := goredis.NewPool(client) // or, pool := redigo.NewPool(...) 50 | 51 | // Create an instance of redisync to be used to obtain a mutual exclusion 52 | // lock. 53 | rs := redsync.New(pool) 54 | 55 | // Obtain a new mutex by using the same name for all instances wanting the 56 | // same lock. 57 | mutexname := "my-global-mutex" 58 | mutex := rs.NewMutex(mutexname) 59 | 60 | // Obtain a lock for our given mutex. After this is successful, no one else 61 | // can obtain the same lock (the same mutex name) until we unlock it. 62 | if err := mutex.Lock(); err != nil { 63 | panic(err) 64 | } 65 | 66 | // Do your work that requires the lock. 67 | 68 | // Release the lock so other processes or threads can obtain a lock. 69 | if ok, err := mutex.Unlock(); !ok || err != nil { 70 | panic("unlock failed") 71 | } 72 | } 73 | ``` -------------------------------------------------------------------------------- /zh/13.1-图片处理.md: -------------------------------------------------------------------------------- 1 | # 图片处理 2 | 3 | ## QRCode 4 | 5 | ### skip2/go-qrcode QRCode create 6 | 7 | https://github.com/skip2/go-qrcode 8 | 9 | ```golang 10 | go get -u -v github.com/skip2/go-qrcode 11 | ``` 12 | 13 | - Create a PNG image 14 | 15 | ```golang 16 | var png []byte 17 | png, err := qrcode.Encode("you want qrcode", qrcode.Medium, 256) 18 | ``` 19 | 20 | - Create a PNG image and write to a file 21 | 22 | ```golang 23 | err := qrcode.WriteFile("you want qrcode", qrcode.Medium, 256, "qr.png") 24 | ``` 25 | 26 | ### shezadkhan137/go-qrcode wrapper around zbar 27 | 28 | https://github.com/shezadkhan137/go-qrcode 29 | 30 | need install zbar 31 | 32 | - OSX 33 | 34 | ```sh 35 | brew install zbar 36 | ``` 37 | 38 | - ubuntu 39 | 40 | ```sh 41 | sudo apt-get install libzbar-dev 42 | ``` 43 | 44 | - yum 45 | 46 | download http://zbar.sourceforge.net/download.html 47 | python-zbar https://pypi.python.org/pypi/zbar 48 | 49 | ```sh 50 | yum install pdftk ImageMagick ImageMagick-devel ghostscript python-imaging python-devel 51 | cd zbar 52 | ./configure --without-gtk --without-qt 53 | make && make install 54 | cd pip-zbar 55 | python setup.py install 56 | ``` 57 | 58 | ```golang 59 | go get -u -v github.com/shezadkhan137/go-qrcode/qrcode 60 | ``` 61 | 62 | - use 63 | 64 | ```golang 65 | results, err := qrcode.GetDataFromPNG("path/to/image.png") 66 | if err != nil { 67 | panic(err) 68 | } 69 | for _, result := range results{ 70 | fmt.Printf("Symbol Type: %s, Data %s", result.SymbolType, result.Data ) 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /zh/13.2-GUI工具.md: -------------------------------------------------------------------------------- 1 | # GUI 工具 2 | 3 | ## walk Golang的图形编辑框架 4 | 5 | https://github.com/lxn/walk 6 | 7 | ```golang 8 | go get -u -v github.com/lxn/walk 9 | ``` 10 | 11 | - 最低支持版本 go 1.1.x 12 | - manifest支持,类似[rsrc](https://github.com/akavel/rsrc) 13 | - 大量例子,介绍如何绘制GUI布局和绑定数据和事件 14 | 15 | ## grafana/grafana 在线编辑器 16 | 17 | Grafana 是 [Graphite](http://graphiteapp.org/) 和 [InfluxDB](http://influxdb.org/) 仪表盘和图形编辑器 18 | 19 | 同时支持 [OpenTSDB](http://opentsdb.net/) 20 | 21 | 详细见 22 | 23 | https://github.com/grafana/grafana 24 | -------------------------------------------------------------------------------- /zh/14.1-docker工具.md: -------------------------------------------------------------------------------- 1 | # docker 工具 2 | 3 | ## fsouza/go-dockerclient docker客户端 4 | 5 | https://github.com/fsouza/go-dockerclient 6 | 7 | ```sh 8 | go get -u -v github.com/fsouza/go-dockerclient 9 | ``` 10 | 11 | http://docs.docker.com/engine/reference/api/docker_remote_api/ 12 | 13 | e.g. 14 | 15 | ```golang 16 | func main() { 17 | endpoint := "unix:///var/run/docker.sock" 18 | client, err := docker.NewClient(endpoint) 19 | if err != nil { 20 | panic(err) 21 | } 22 | imgs, err := client.ListImages(docker.ListImagesOptions{All: false}) 23 | if err != nil { 24 | panic(err) 25 | } 26 | for _, img := range imgs { 27 | fmt.Println("ID: ", img.ID) 28 | fmt.Println("RepoTags: ", img.RepoTags) 29 | fmt.Println("Created: ", img.Created) 30 | fmt.Println("Size: ", img.Size) 31 | fmt.Println("VirtualSize: ", img.VirtualSize) 32 | fmt.Println("ParentId: ", img.ParentID) 33 | } 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /zh/16.0-专业数据库.md: -------------------------------------------------------------------------------- 1 | # 专业数据库 2 | 3 | > for fun DB-Engines Ranking https://db-engines.com/en/ranking 4 | 5 | ## influxdata/influxdb 监控级时序数据库 6 | 7 | 官方站点 https://influxdata.com/ 8 | github https://github.com/influxdata/influxdb 9 | 10 | 提供 HTTP-API 的集中型 时序数据库 11 | 时候聚合型,实时监控,高写入的场景 12 | 13 | > 开源版只能单节点部署,故如果你有分布式的需求,不要使用这个数据库 14 | 15 | ## tidwall/tile38 GIS 地理信息时序数据库 16 | 17 | 官方站点 http://tile38.com/ 协议 MIT 18 | 19 | https://github.com/tidwall/tile38 20 | 21 | 用于基于 GIS 的时序数据处理,支持 HTTP websockets 调用 22 | 提供大量语言客户端 23 | 24 | Tile38 uses the [Redis RESP](http://redis.io/topics/protocol) protocol natively. Therefore most clients that support basic Redis commands will in turn support Tile38. Below are a few of the popular clients. 25 | 26 | - C: [hiredis](https://github.com/redis/hiredis) 27 | - C#: [StackExchange.Redis](https://github.com/StackExchange/StackExchange.Redis) 28 | - C++: [redox](https://github.com/hmartiro/redox) 29 | - Clojure: [carmine](https://github.com/ptaoussanis/carmine) 30 | - Common Lisp: [CL-Redis](https://github.com/vseloved/cl-redis) 31 | - Erlang: [Eredis](https://github.com/wooga/eredis) 32 | - Go: [go-redis](https://github.com/go-redis/redis) ([example code](https://github.com/tidwall/tile38/wiki/Go-example-(go-redis))) 33 | - Go: [redigo](https://github.com/gomodule/redigo) ([example code](https://github.com/tidwall/tile38/wiki/Go-example-(redigo))) 34 | - Haskell: [hedis](https://github.com/informatikr/hedis) 35 | - Java: [lettuce](https://github.com/mp911de/lettuce) ([example code](https://github.com/tidwall/tile38/wiki/Java-example-(lettuce))) 36 | - Node.js: [node-tile38](https://github.com/phulst/node-tile38) ([example code](https://github.com/tidwall/tile38/wiki/Node.js-example-(node-tile38))) 37 | - Node.js: [node_redis](https://github.com/NodeRedis/node_redis) ([example code](https://github.com/tidwall/tile38/wiki/Node.js-example-(node-redis))) 38 | - Perl: [perl-redis](https://github.com/PerlRedis/perl-redis) 39 | - PHP: [tinyredisclient](https://github.com/ptrofimov/tinyredisclient) ([example code](https://github.com/tidwall/tile38/wiki/PHP-example-(tinyredisclient))) 40 | - PHP: [phpredis](https://github.com/phpredis/phpredis) 41 | - Python: [redis-py](https://github.com/andymccurdy/redis-py) ([example code](https://github.com/tidwall/tile38/wiki/Python-example)) 42 | - Ruby: [redic](https://github.com/amakawa/redic) ([example code](https://github.com/tidwall/tile38/wiki/Ruby-example-(redic))) 43 | - Ruby: [redis-rb](https://github.com/redis/redis-rb) ([example code](https://github.com/tidwall/tile38/wiki/Ruby-example-(redis-rb))) 44 | - Rust: [redis-rs](https://github.com/mitsuhiko/redis-rs) 45 | - Scala: [scala-redis](https://github.com/debasishg/scala-redis) 46 | - Swift: [Redbird](https://github.com/czechboy0/Redbird) 47 | -------------------------------------------------------------------------------- /zh/20.1-WebApp框架.md: -------------------------------------------------------------------------------- 1 | # WebApp框架 2 | 3 | ## devfeel/dotweb 带模板的WenApp框架 4 | 5 | - [github https://github.com/devfeel/dotweb](https://github.com/devfeel/dotweb) 6 | -------------------------------------------------------------------------------- /zh/README.md: -------------------------------------------------------------------------------- 1 | # golang-open-project 2 | 3 | 这是一个收集各种golang开源项目的索引项目,不断更新,帮助大家快速开发 4 | 5 | 书籍源码在 https://github.com/sinlov/golang-open-project 6 | -------------------------------------------------------------------------------- /zh/preface.md: -------------------------------------------------------------------------------- 1 | 2 | [00.1-Golang官方库](00.1-Golang官方库.md) 3 | 4 | - [Golang 官方库](00.1-Golang官方库.md#golang-官方库) 5 | - [project-layout 工程模板](00.1-Golang官方库.md#project-layout-工程模板) 6 | - [crypto 官方加密库](00.1-Golang官方库.md#crypto-官方加密库) 7 | - [Http 网络通信库](00.1-Golang官方库.md#http-网络通信库) 8 | - [gomobile 移动设备支持](00.1-Golang官方库.md#gomobile-移动设备支持) 9 | 10 | 11 | [00.2-依赖管理](00.2-依赖管理.md) 12 | 13 | - [依赖管理](00.2-依赖管理.md#依赖管理) 14 | - [gmchart](00.2-依赖管理.md#gmchart) 15 | - [dep](00.2-依赖管理.md#dep) 16 | - [tools/godep](00.2-依赖管理.md#tools/godep) 17 | 18 | 19 | [00.3-文档工具](00.3-文档工具.md) 20 | 21 | - [文档工具](00.3-文档工具.md#文档工具) 22 | - [gowalker.org 在线文档生成](00.3-文档工具.md#gowalker.org-在线文档生成) 23 | 24 | 25 | [01.1-文本工具](01.1-文本工具.md) 26 | 27 | - [文本工具](01.1-文本工具.md#文本工具) 28 | - [Markdown 转换器](01.1-文本工具.md#markdown-转换器) 29 | - [fairlyblank/md2min](01.1-文本工具.md#fairlyblank/md2min) 30 | - [russross/blackfriday markdown 转换器](01.1-文本工具.md#russross/blackfriday-markdown-转换器) 31 | - [tealeg/xlsx xlsx工具](01.1-文本工具.md#tealeg/xlsx-xlsx工具) 32 | - [swaggo/swag swaggerAPI生成器](01.1-文本工具.md#swaggo/swag-swaggerapi生成器) 33 | 34 | 35 | [01.2-数据结构工具](01.2-数据结构工具.md) 36 | 37 | - [数据结构工具](01.2-数据结构工具.md#数据结构工具) 38 | - [安全map orcaman/concurrent-map](01.2-数据结构工具.md#安全map-orcaman/concurrent-map) 39 | - [跳表数据结构 mtchavez/skiplist](01.2-数据结构工具.md#跳表数据结构-mtchavez/skiplist) 40 | - [UUID 生成 go.uuid](01.2-数据结构工具.md#uuid-生成-go.uuid) 41 | - [spf13/viper 配置解决方案](01.2-数据结构工具.md#spf13/viper-配置解决方案) 42 | 43 | 44 | [01.3-加密工具](01.3-加密工具.md) 45 | 46 | - [加密工具](01.3-加密工具.md#加密工具) 47 | - [sinlov/fastEncryptDecode](01.3-加密工具.md#sinlov/fastencryptdecode) 48 | 49 | 50 | [01.4-解压工具](01.4-解压工具.md) 51 | 52 | - [解压工具](01.4-解压工具.md#解压工具) 53 | - [mholt/archiver 混合解压工具](01.4-解压工具.md#mholt/archiver-混合解压工具) 54 | 55 | 56 | [01.5-反射增强](01.5-反射增强.md) 57 | 58 | - [反射增强](01.5-反射增强.md#反射增强) 59 | - [github.com/modern-go/reflect2 反射增强库](01.5-反射增强.md#github.com/modern-go/reflect2-反射增强库) 60 | 61 | 62 | [01.7-数据缓存](01.7-数据缓存.md) 63 | 64 | - [数据缓存](01.7-数据缓存.md#数据缓存) 65 | - [github.com/muesli/cache2gogo 简单内存库](01.7-数据缓存.md#github.com/muesli/cache2gogo-简单内存库) 66 | - [github.com/eko/gocache 多模式缓存库](01.7-数据缓存.md#github.com/eko/gocache-多模式缓存库) 67 | - [github.com/philippgille/gokv kv缓存库](01.7-数据缓存.md#github.com/philippgille/gokv-kv缓存库) 68 | 69 | 70 | [02.1-测试工具](02.1-测试工具.md) 71 | 72 | - [测试工具](02.1-测试工具.md#测试工具) 73 | - [Pallinder/go-randomdata 随机数据生成器](02.1-测试工具.md#pallinder/go-randomdata-随机数据生成器) 74 | - [gostub 测试打桩工具](02.1-测试工具.md#gostub-测试打桩工具) 75 | - [golang/mock/gomock mock模拟](02.1-测试工具.md#golang/mock/gomock-mock模拟) 76 | - [codesenberg/bombardier http1/2 压测工具](02.1-测试工具.md#codesenberg/bombardier-http1/2-压测工具) 77 | - [smartystreets/goconvey 测试用例统计](02.1-测试工具.md#smartystreets/goconvey-测试用例统计) 78 | 79 | 80 | [03.0-运维工具](03.0-运维工具.md) 81 | 82 | - [运维工具](03.0-运维工具.md#运维工具) 83 | - [服务器运维](03.0-运维工具.md#服务器运维) 84 | - [平滑重启 github.com/fvbock/endless](03.0-运维工具.md#平滑重启-github.com/fvbock/endless) 85 | - [goagain 零下线时间式重启](03.0-运维工具.md#goagain-零下线时间式重启) 86 | - [caddy 跨平台HTTP/2服务代理](03.0-运维工具.md#caddy-跨平台http/2服务代理) 87 | 88 | 89 | [03.1-定时任务](03.1-定时任务.md) 90 | 91 | - [定时任务](03.1-定时任务.md#定时任务) 92 | - [antlabs/timer 定时器-基于5级时间轮](03.1-定时任务.md#antlabs/timer-定时器-基于5级时间轮) 93 | - [go版本cron github.com/robfig/cron](03.1-定时任务.md#go版本cron-github.com/robfig/cron) 94 | 95 | 96 | [04.0-网络工具](04.0-网络工具.md) 97 | 98 | - [http客户端](04.0-网络工具.md#http客户端) 99 | - [parnurzeal/gorequest客户端](04.0-网络工具.md#parnurzeal/gorequest客户端) 100 | - [github.com/tomsteele/blacksheepwall 域名搜索工具](04.0-网络工具.md#github.com/tomsteele/blacksheepwall-域名搜索工具) 101 | 102 | 103 | [04.1-MQTT](04.1-MQTT.md) 104 | 105 | - [MQTT 协议](04.1-MQTT.md#mqtt-协议) 106 | - [surgemq/surgemq MQTT服务端客户端](04.1-MQTT.md#surgemq/surgemq-mqtt服务端客户端) 107 | 108 | 109 | [05.0-脚本化工具](05.0-脚本化工具.md) 110 | 111 | - [脚本化工具](05.0-脚本化工具.md#脚本化工具) 112 | - [像shell一样使用go github.com/bitfield/script](05.0-脚本化工具.md#像shell一样使用go-github.com/bitfield/script) 113 | 114 | 115 | [05.1-js引擎](05.1-js引擎.md) 116 | 117 | - [js-引擎](05.1-js引擎.md#js-引擎) 118 | - [js 解析执行环境 github.com/robertkrimen/otto](05.1-js引擎.md#js-解析执行环境-github.com/robertkrimen/otto) 119 | - [js 执行引擎 rogchap.com/v8go](05.1-js引擎.md#js-执行引擎-rogchap.com/v8go) 120 | 121 | 122 | [05.2-lua引擎](05.2-lua引擎.md) 123 | 124 | - [lua 引擎](05.2-lua引擎.md#lua-引擎) 125 | - [lua编译运行引擎 github.com/yuin/gopher-lua](05.2-lua引擎.md#lua编译运行引擎-github.com/yuin/gopher-lua) 126 | 127 | 128 | [06.0-应用容器](06.0-应用容器.md) 129 | 130 | - [应用容器](06.0-应用容器.md#应用容器) 131 | - [php应用APP容器 github.com/spiral/roadrunner](06.0-应用容器.md#php应用app容器-github.com/spiral/roadrunner) 132 | 133 | 134 | [10.0-基础工具](10.0-基础工具.md) 135 | 136 | - [基础工具](10.0-基础工具.md#基础工具) 137 | - [编程辅助](10.0-基础工具.md#编程辅助) 138 | - [语法提示器 gocode](10.0-基础工具.md#语法提示器-gocode) 139 | - [日志工具](10.0-基础工具.md#日志工具) 140 | - [log4go](10.0-基础工具.md#log4go) 141 | - [测试工具](10.0-基础工具.md#测试工具) 142 | - [github.com/cweill/gotests 测试模板生成工具](10.0-基础工具.md#github.com/cweill/gotests-测试模板生成工具) 143 | - [github.com/bmizerany/assert assert 单元测试工具](10.0-基础工具.md#github.com/bmizerany/assert-assert-单元测试工具) 144 | - [使用方法](10.0-基础工具.md#使用方法) 145 | - [运行测试](10.0-基础工具.md#运行测试) 146 | - [字符集转换工具](10.0-基础工具.md#字符集转换工具) 147 | - [axgle/mahonia 字符集转换工具](10.0-基础工具.md#axgle/mahonia-字符集转换工具) 148 | - [Go GUI IDE](10.0-基础工具.md#go-gui-ide) 149 | - [andlabs/ui](10.0-基础工具.md#andlabs/ui) 150 | 151 | 152 | [10.1-命令行工具](10.1-命令行工具.md) 153 | 154 | - [命令行工具](10.1-命令行工具.md#命令行工具) 155 | - [urfave/cli 命令行](10.1-命令行工具.md#urfave/cli-命令行) 156 | - [commander-cli/commander](10.1-命令行工具.md#commander-cli/commander) 157 | - [logrusorgru/aurora 输出命令行着色](10.1-命令行工具.md#logrusorgru/aurora-输出命令行着色) 158 | - [commander-cli/cmd 全平台命令行执行](10.1-命令行工具.md#commander-cli/cmd-全平台命令行执行) 159 | - [mkideal/cli 简单命令行](10.1-命令行工具.md#mkideal/cli-简单命令行) 160 | - [fsouza/go-dockerclient docker 客户端](10.1-命令行工具.md#fsouza/go-dockerclient-docker-客户端) 161 | - [富交互命令行工具 github.com/rivo/tview](10.1-命令行工具.md#富交互命令行工具-github.com/rivo/tview) 162 | - [shirou/gopsutil 进程工具](10.1-命令行工具.md#shirou/gopsutil-进程工具) 163 | 164 | 165 | [10.2-传输工具](10.2-传输工具.md) 166 | 167 | - [传输工具](10.2-传输工具.md#传输工具) 168 | - [jlaffaye/ftp FTP传输工具](10.2-传输工具.md#jlaffaye/ftp-ftp传输工具) 169 | 170 | 171 | [11.0-序列化工具](11.0-序列化工具.md) 172 | 173 | - [序列化工具](11.0-序列化工具.md#序列化工具) 174 | - [多向序列化](11.0-序列化工具.md#多向序列化) 175 | - [hcl2json](11.0-序列化工具.md#hcl2json) 176 | - [github.com/sclevine/yj](11.0-序列化工具.md#github.com/sclevine/yj) 177 | - [toml](11.0-序列化工具.md#toml) 178 | - [json 序列化](11.0-序列化工具.md#json-序列化) 179 | - [tidwall/gjson 支持单个快速解析 json](11.0-序列化工具.md#tidwall/gjson-支持单个快速解析-json) 180 | - [gig-simplejson](11.0-序列化工具.md#gig-simplejson) 181 | - [buger/jsonparser](11.0-序列化工具.md#buger/jsonparser) 182 | - [json2go](11.0-序列化工具.md#json2go) 183 | - [donnie4w/json4g](11.0-序列化工具.md#donnie4w/json4g) 184 | - [gojson](11.0-序列化工具.md#gojson) 185 | - [dutchcoders/XMLGen](11.0-序列化工具.md#dutchcoders/xmlgen) 186 | - [FlatBuffer](11.0-序列化工具.md#flatbuffer) 187 | - [install FlatBuffers by binary](11.0-序列化工具.md#install-flatbuffers-by-binary) 188 | - [install FlatBuffers by build](11.0-序列化工具.md#install-flatbuffers-by-build) 189 | - [Use document](11.0-序列化工具.md#use-document) 190 | - [iso8583](11.0-序列化工具.md#iso8583) 191 | 192 | 193 | [11.1-SQL映射工具](11.1-SQL映射工具.md) 194 | 195 | - [SQL映射工具](11.1-SQL映射工具.md#sql映射工具) 196 | - [github.com/jmoiron/sqlx SQL增强](11.1-SQL映射工具.md#github.com/jmoiron/sqlx-sql增强) 197 | - [github.com/Masterminds/squirrel SQL生成](11.1-SQL映射工具.md#github.com/masterminds/squirrel-sql生成) 198 | - [xorm ORM 映射](11.1-SQL映射工具.md#xorm-orm-映射) 199 | - [xorm 辅助工具](11.1-SQL映射工具.md#xorm-辅助工具) 200 | 201 | 202 | [11.2-WebSokcet](11.2-WebSokcet.md) 203 | 204 | - [WebSokcet](11.2-WebSokcet.md#websokcet) 205 | - [gorilla/websocket](11.2-WebSokcet.md#gorilla/websocket) 206 | 207 | 208 | [11.3-解析工具](11.3-解析工具.md) 209 | 210 | - [解析工具](11.3-解析工具.md#解析工具) 211 | - [goquery html 解析](11.3-解析工具.md#goquery-html-解析) 212 | - [tinydom XML-DOM 解析](11.3-解析工具.md#tinydom-xml-dom-解析) 213 | 214 | 215 | [11.4-验证工具](11.4-验证工具.md) 216 | 217 | - [验证工具](11.4-验证工具.md#验证工具) 218 | - [gookit/validate 基于反射的参数验证](11.4-验证工具.md#gookit/validate-基于反射的参数验证) 219 | 220 | 221 | [11.5-Web模板](11.5-Web模板.md) 222 | 223 | - [Web模板](11.5-Web模板.md#web模板) 224 | - [flosch/pongo2 Django风格模板](11.5-Web模板.md#flosch/pongo2-django风格模板) 225 | 226 | 227 | [12.0-微服务工具](12.0-微服务工具.md) 228 | 229 | - [微服务工具](12.0-微服务工具.md#微服务工具) 230 | - [RPC服务](12.0-微服务工具.md#rpc服务) 231 | - [可插拔的RPC服务 go-micro](12.0-微服务工具.md#可插拔的rpc服务-go-micro) 232 | - [go-kit](12.0-微服务工具.md#go-kit) 233 | 234 | 235 | [12.1-持久化工具](12.1-持久化工具.md) 236 | 237 | - [持久化工具](12.1-持久化工具.md#持久化工具) 238 | - [mongo-driver/mongo mongo官方驱动](12.1-持久化工具.md#mongo-driver/mongo-mongo官方驱动) 239 | - [yiigo golang 辅助库](12.1-持久化工具.md#yiigo-golang-辅助库) 240 | - [kiteq 多种持久化方案的mq框架](12.1-持久化工具.md#kiteq-多种持久化方案的mq框架) 241 | - [Use](12.1-持久化工具.md#use) 242 | - [blackbeans/flume-bridge flume的go语言客户端](12.1-持久化工具.md#blackbeans/flume-bridge-flume的go语言客户端) 243 | 244 | 245 | [12.2-连接中间件](12.2-连接中间件.md) 246 | 247 | - [连接中间件](12.2-连接中间件.md#连接中间件) 248 | - [Apache Kafka 连接中间件 Shopify/sarama](12.2-连接中间件.md#apache-kafka-连接中间件-shopify/sarama) 249 | 250 | 251 | [12.3-认证模块](12.3-认证模块.md) 252 | 253 | - [认证模块](12.3-认证模块.md#认证模块) 254 | - [认证服务](12.3-认证模块.md#认证服务) 255 | - [github.com/casbin/casbin casbin 授权库](12.3-认证模块.md#github.com/casbin/casbin-casbin-授权库) 256 | - [oauth2.0 模块](12.3-认证模块.md#oauth2.0-模块) 257 | - [jwt-go](12.3-认证模块.md#jwt-go) 258 | - [jwt-go error](12.3-认证模块.md#jwt-go-error) 259 | 260 | 261 | [12.4-验证码](12.4-验证码.md) 262 | 263 | - [验证码](12.4-验证码.md#验证码) 264 | - [dchest/captcha 图片声音验证模块](12.4-验证码.md#dchest/captcha-图片声音验证模块) 265 | 266 | 267 | [12.5-服务监控](12.5-服务监控.md) 268 | 269 | - [服务监控](12.5-服务监控.md#服务监控) 270 | - [opentracing-go 分布式链路追踪](12.5-服务监控.md#opentracing-go-分布式链路追踪) 271 | - [Jaeger 链路追踪](12.5-服务监控.md#jaeger-链路追踪) 272 | 273 | 274 | [12.6-服务器运行监视工具](12.6-服务器运行监视工具.md) 275 | 276 | - [服务器运行监视工具](12.6-服务器运行监视工具.md#服务器运行监视工具) 277 | - [divan/expvarmon 可视化监视服务运行状态工具](12.6-服务器运行监视工具.md#divan/expvarmon-可视化监视服务运行状态工具) 278 | - [hashicorp/consul 微服务调度控制工具](12.6-服务器运行监视工具.md#hashicorp/consul-微服务调度控制工具) 279 | - [prometheus/prometheus 服务器系统状态监视工具](12.6-服务器运行监视工具.md#prometheus/prometheus-服务器系统状态监视工具) 280 | - [influxdata/telegraf 服务监视报警工具](12.6-服务器运行监视工具.md#influxdata/telegraf-服务监视报警工具) 281 | - [mackerelio/mackerel-agent 服务监视工具](12.6-服务器运行监视工具.md#mackerelio/mackerel-agent-服务监视工具) 282 | - [cloudinsight/cloudinsight-agent 服务监视报警工具](12.6-服务器运行监视工具.md#cloudinsight/cloudinsight-agent-服务监视报警工具) 283 | - [fgeller/kt kafka 监控命令行工具](12.6-服务器运行监视工具.md#fgeller/kt-kafka-监控命令行工具) 284 | 285 | 286 | [12.7-分布式锁](12.7-分布式锁.md) 287 | 288 | - [分布式锁](12.7-分布式锁.md#分布式锁) 289 | - [github.com/go-redsync/redsync](12.7-分布式锁.md#github.com/go-redsync/redsync) 290 | 291 | 292 | [13.1-图片处理](13.1-图片处理.md) 293 | 294 | - [图片处理](13.1-图片处理.md#图片处理) 295 | - [QRCode](13.1-图片处理.md#qrcode) 296 | - [skip2/go-qrcode QRCode create](13.1-图片处理.md#skip2/go-qrcode-qrcode-create) 297 | - [shezadkhan137/go-qrcode wrapper around zbar](13.1-图片处理.md#shezadkhan137/go-qrcode-wrapper-around-zbar) 298 | 299 | 300 | [13.2-GUI工具](13.2-GUI工具.md) 301 | 302 | - [GUI 工具](13.2-GUI工具.md#gui-工具) 303 | - [walk Golang的图形编辑框架](13.2-GUI工具.md#walk-golang的图形编辑框架) 304 | - [grafana/grafana 在线编辑器](13.2-GUI工具.md#grafana/grafana-在线编辑器) 305 | 306 | 307 | [14.1-docker工具](14.1-docker工具.md) 308 | 309 | - [docker 工具](14.1-docker工具.md#docker-工具) 310 | - [fsouza/go-dockerclient docker客户端](14.1-docker工具.md#fsouza/go-dockerclient-docker客户端) 311 | 312 | 313 | [16.0-专业数据库](16.0-专业数据库.md) 314 | 315 | - [专业数据库](16.0-专业数据库.md#专业数据库) 316 | - [influxdata/influxdb 监控级时序数据库](16.0-专业数据库.md#influxdata/influxdb-监控级时序数据库) 317 | - [tidwall/tile38 GIS 地理信息时序数据库](16.0-专业数据库.md#tidwall/tile38-gis-地理信息时序数据库) 318 | 319 | 320 | [20.1-WebApp框架](20.1-WebApp框架.md) 321 | 322 | - [WebApp框架](20.1-WebApp框架.md#webapp框架) 323 | - [devfeel/dotweb 带模板的WenApp框架](20.1-WebApp框架.md#devfeel/dotweb-带模板的wenapp框架) 324 | 325 | 326 | -------------- 327 | 328 | 329 | **Folder TOC generated by [sinlov](https://github.com/sinlov/markdown-folder-toc)** 330 | 331 | --------------------------------------------------------------------------------