├── .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(`\[(.*?)\]\((.*?)\.md>?\)`).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 | 
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 | 
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 |
--------------------------------------------------------------------------------