EN 中文
go-doudou(兜兜)是一个基于gossip协议和OpenAPI3.0规范的去中心化微服务框架。它同时支持单体应用。只支持restful服务。
go get -v -u github.com/unionj-cloud/go-doudou/...@v0.7.2
➜ ~ go-doudou -h
WARN[0000] Error loading .env file: open /Users/.env: no such file or directory
go-doudou works like a scaffolding tool but more than that.
it lets api providers design their apis and help them code less.
it generates openapi 3.0 spec json document for frontend developers or other api consumers to understand what apis there,
consumers can import it into postman to debug and test, or upload it into some code generators to download client sdk.
it provides some useful components and middleware for constructing microservice cluster like service register and discovering,
load balancing and so on. it just begins, more features will come out soon.
Usage:
go-doudou [flags]
go-doudou [command]
Available Commands:
ddl migration tool between database table structure and golang struct
help Help about any command
name bulk add or update struct fields json tag
svc generate or update service
Flags:
-h, --help help for go-doudou
-v, --version version for go-doudou
Use "go-doudou [command] --help" for more information about a command.
➜ ~ go-doudou svc init helloworld
WARN[0000] Error loading .env file: open /Users/.env: no such file or directory
1.16
helloworld
You can ignore the warning now.
➜ helloworld git:(master) ✗ ls -la -h
total 40
drwxr-xr-x 10 wubin1989 staff 320B 8 29 23:27 .
drwxr-xr-x+ 157 wubin1989 staff 4.9K 8 29 23:27 ..
-rw-r--r-- 1 wubin1989 staff 2.0K 8 29 23:22 .env
drwxr-xr-x 5 wubin1989 staff 160B 8 29 23:26 .git
-rw-r--r-- 1 wubin1989 staff 268B 8 29 23:22 .gitignore
drwxr-xr-x 6 wubin1989 staff 192B 8 29 23:27 .idea
-rw-r--r-- 1 wubin1989 staff 707B 8 29 23:22 Dockerfile
-rw-r--r-- 1 wubin1989 staff 442B 8 29 23:22 go.mod
-rw-r--r-- 1 wubin1989 staff 253B 8 29 23:22 svc.go
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:22 vo
GDD_
开头的环境变量详情请阅读Must Know
package service
import (
"context"
"helloworld/vo"
)
type Helloworld interface {
// You can define your service methods as your need. Below is an example.
PageUsers(ctx context.Context, query vo.PageQuery) (code int, data vo.PageRet, err error)
}
go-doudou svc http --handler -c go -o --doc
go mod tidy
Let's see what are generated.
➜ helloworld git:(master) ✗ ls -la -h
total 328
drwxr-xr-x 20 wubin1989 staff 640B 8 31 12:34 .
drwxr-xr-x+ 157 wubin1989 staff 4.9K 8 31 12:36 ..
-rw-r--r-- 1 wubin1989 staff 2.0K 8 29 23:45 .env
drwxr-xr-x 5 wubin1989 staff 160B 8 31 12:36 .git
-rw-r--r-- 1 wubin1989 staff 268B 8 29 23:22 .gitignore
drwxr-xr-x 7 wubin1989 staff 224B 8 31 12:33 .idea
-rw-r--r-- 1 wubin1989 staff 707B 8 29 23:22 Dockerfile
-rwxr-xr-x 1 wubin1989 staff 13K 8 31 12:35 app.log
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 client
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 cmd
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 config
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 db
-rw-r--r-- 1 wubin1989 staff 536B 8 31 12:35 go.mod
-rw-r--r-- 1 wubin1989 staff 115K 8 31 12:35 go.sum
-rwxr-xr-x 1 wubin1989 staff 1.9K 8 31 12:34 helloworld_openapi3.go
-rwxr-xr-x 1 wubin1989 staff 1.8K 8 31 12:34 helloworld_openapi3.json
-rw-r--r-- 1 wubin1989 staff 253B 8 29 23:22 svc.go
-rw-r--r-- 1 wubin1989 staff 413B 8 29 23:44 svcimpl.go
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 transport
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:22 vo
记得先把.env文件里的环境变量GDD_MEM_SEED设为空字符串,因为这是第一个服务节点,它自己就是种子节点。
➜ helloworld git:(master) ✗ go run cmd/main.go
INFO[2021-08-31 21:35:47] Node 192.168.2.20 joined, supplying helloworld service
WARN[2021-08-31 21:35:47] No seed found
INFO[2021-08-31 21:35:47] Memberlist created. Local node is Node 192.168.2.20, providing helloworld service at http://192.168.2.20:6060, memberlist port 50324
_
| __ | | | |
| | \/ _ _| | __| | _
| | _ / |______| / | / _ \ | | | | / _
| / | | | |
| |_ \| (_) | | (_| || (_) || |_| || (_| || (_) || |_| |
\____/ \___/ \__,_| \___/ \__,_| \__,_| \___/ \__,_|
INFO[2021-08-31 21:35:47] ================ Registered Routes ================
INFO[2021-08-31 21:35:47] +-------------+--------+-------------------------+
INFO[2021-08-31 21:35:47] | NAME | METHOD | PATTERN |
INFO[2021-08-31 21:35:47] +-------------+--------+-------------------------+
INFO[2021-08-31 21:35:47] | PageUsers | POST | /page/users |
INFO[2021-08-31 21:35:47] | GetDoc | GET | /go-doudou/doc |
INFO[2021-08-31 21:35:47] | GetOpenAPI | GET | /go-doudou/openapi.json |
INFO[2021-08-31 21:35:47] | Prometheus | GET | /go-doudou/prometheus |
INFO[2021-08-31 21:35:47] | GetRegistry | GET | /go-doudou/registry |
INFO[2021-08-31 21:35:47] +-------------+--------+-------------------------+
INFO[2021-08-31 21:35:47] ===================================================
INFO[2021-08-31 21:35:47] Started in 431.269µs
INFO[2021-08-31 21:35:47] Http server is listening on :6060
➜ helloworld git:(master) ✗ go-doudou svc push -r wubin1989
[+] Building 0.8s (13/13) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:1.13.4-alpine 0.0s
=> [1/8] FROM docker.io/library/golang:1.13.4-alpine 0.0s
=> [internal] load build context 0.7s
=> => transferring context: 22.43MB 0.6s
=> CACHED [2/8] WORKDIR /repo 0.0s
=> CACHED [3/8] ADD go.mod . 0.0s
=> CACHED [4/8] ADD go.sum . 0.0s
=> CACHED [5/8] ADD . ./ 0.0s
=> CACHED [6/8] RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories 0.0s
=> CACHED [7/8] RUN apk add --no-cache bash tzdata 0.0s
=> CACHED [8/8] RUN export GDD_VER=$(go list -mod=vendor -m -f '{{ .Version }}' github.com/unionj-cloud/go-doudou) && CGO_ENABLED 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:00365c58d0410d978aea462ec93323e20d879b15421e8eba29d8a17918660af8 0.0s
=> => naming to docker.io/library/helloworld 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
The push refers to repository [docker.io/wubin1989/helloworld]
d0a9599b03e1: Pushed
c3055fdf1a79: Layer already exists
1c265a7f4c3e: Layer already exists
f567cf5a5cf1: Layer already exists
0b4acd902364: Layer already exists
bbf9670b59e9: Layer already exists
fdd6fb6fca5b: Layer already exists
a17f85ec7605: Layer already exists
2895b872dff5: Layer already exists
eed8c158e67f: Layer already exists
2033402d2275: Layer already exists
77cae8ab23bf: Layer already exists
v20210831125525: digest: sha256:5f75f7b43708d0619555f9bccbf0347e8db65319b83c65251015982ca6d23370 size: 2829
time="2021-08-31 12:55:53" level=info msg="image wubin1989/helloworld:v20210831125525 has been pushed successfully\n"
time="2021-08-31 12:55:53" level=info msg="k8s yaml has been created/updated successfully. execute command 'go-doudou svc deploy' to deploy service helloworld to k8s cluster\n"
然后你会看到生成了两个k8s部署文件。
➜ helloworld git:(master) ✗ ll
total 328
-rw-r--r-- 1 wubin1989 staff 707B 8 29 23:22 Dockerfile
-rwxr-xr-x 1 wubin1989 staff 15K 8 31 12:55 app.log
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 client
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 cmd
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 config
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 db
-rw-r--r-- 1 wubin1989 staff 536B 8 31 12:35 go.mod
-rw-r--r-- 1 wubin1989 staff 115K 8 31 12:35 go.sum
-rw-r--r-- 1 wubin1989 staff 817B 8 31 12:55 helloworld_deployment.yaml
-rwxr-xr-x 1 wubin1989 staff 1.9K 8 31 12:34 helloworld_openapi3.go
-rwxr-xr-x 1 wubin1989 staff 1.8K 8 31 12:34 helloworld_openapi3.json
-rw-r--r-- 1 wubin1989 staff 867B 8 31 12:55 helloworld_statefulset.yaml
-rw-r--r-- 1 wubin1989 staff 253B 8 29 23:22 svc.go
-rw-r--r-- 1 wubin1989 staff 413B 8 29 23:44 svcimpl.go
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:44 transport
drwxr-xr-x 6 wubin1989 staff 192B 8 31 12:55 vendor
drwxr-xr-x 3 wubin1989 staff 96B 8 29 23:22 vo
go-doudou svc deploy
go-doudou svc shutdown
当你在svc.go文件里定义方法(即restful接口)时,有几个需要注意和了解的地方:
go-doudou svc http --handler
,handlerimpl.go里的已有代码不会被覆盖也不会被修改。如果你在svc.go文件里新增了方法,新代码会加到handlerimpl.go文件最后。go-doudou svc http --handler
,handler.go文件会重新生成,所以请不要在里面手动修改或者添加任何代码。go-doudou svc http
, 除了handler.go文件和handlerimpl.go文件,go-doudou会先判断同名文件是否存在,如果不存在才会生成,存在就会跳过。Go-doudou同时支持开发单体应用和微服务应用。
GDD_MODE=micro
:表示开启微服务应用模式GDD_MODE=mono
:表示开启单体应用模式在main方法里有服务注册相关代码。
if ddconfig.GddMode.Load() == "micro" {
node, err := registry.NewNode()
if err != nil {
logrus.Panicln(fmt.Sprintf("%+v", err))
}
logrus.Infof("Memberlist created. Local node is %s\n", node)
}
如果依赖了其他服务,可以参考如下代码:
// service register
node, err := registry.NewNode()
if err != nil {
logrus.Panicln(fmt.Sprintf("%+v", err))
}
logrus.Infof("%s joined cluster\n", node.String())
// 调用NewMemberlistServiceProvider时传入你依赖的服务的服务名,返回该服务的provider
usersvcProvider := ddhttp.NewMemberlistServiceProvider("usersvc", node)
// 注入该provider到该服务的客户端
usersvcClient := client.NewUsersvc(client.WithProvider(usersvcProvider))
// 注入该客户端到你的服务实例
svc := service.NewOrdersvc(conf, conn, usersvcClient)
暂时只有round robin一种负载均衡算法。欢迎贡献代码。
func (m *MemberlistServiceProvider) SelectServer() (string, error) {
nodes, err := m.registry.Discover(m.name)
if err != nil {
return "", errors.Wrap(err, "SelectServer() fail")
}
next := int(atomic.AddUint64(&m.current, uint64(1)) % uint64(len(nodes)))
m.current = uint64(next)
selected := nodes[next]
return selected.BaseUrl(), nil
}
go-doudou用.env文件管理框架用到的环境变量
环境变量
描述
默认值
是否必须
GDD_BANNER
是否在控制台打印banner
off
GDD_BANNER_TEXT
banner文本
Go-doudou
GDD_LOG_LEVEL
日志等级:可能的值有panic, fatal, error, warn, warning, info, debug, trace
info
GDD_LOG_PATH
如果配置文件里没有出现GDD_LOG_PATH这个环境变量,则没有日志文件输出到磁盘
GDD_GRACE_TIMEOUT
优雅关闭的超时时间
15s
GDD_WRITE_TIMEOUT
http服务器的写操作超时时间
15s
GDD_READ_TIMEOUT
http服务器的读操作超时时间
15s
GDD_IDLE_TIMEOUT
http服务器的空闲连接超时时间
60s
GDD_ROUTE_ROOT_PATH
接口请求路径的前缀
""
GDD_SERVICE_NAME
注册服务到集群时的服务名称
Yes
GDD_HOST
http服务器监听地址
""
GDD_PORT
http服务器监听端口
""
GDD_MODE
"mono"表示单体应用,"micro"表示微服务应用
GDD_MANAGE_ENABLE
开启管理端点,如:/go-doudou/doc, /go-doudou/openapi.json, /go-doudou/prometheus和/go-doudou/registry。
false
GDD_MANAGE_USER
管理端点的basic auth校验的用户名
""
GDD_MANAGE_PASS
管理端点的basic auth校验的密码
""
GDD_MEM_SEED
种子节点的地址。如果没有设置或者设置为空字符串,则创建一个新的memberlist集群,供其他节点来加入
""
GDD_MEM_NAME
节点名称。仅用于本地开发和调试。如果没有设置或者值为空字符串,则取服务器的hostname
""
GDD_MEM_HOST
设置memberlist的AdvertiseAddr属性。如果GDD_MEM_HOST的值以点开头,如:.seed-svc-headless.default.svc.cluster.local,则会在前面补上服务器的hostname,如:seed-2.seed-svc-headless.default.svc.cluster.local,用于支持k8s的有状态服务
""
GDD_MEM_PORT
如果没有设置或者值为空字符串,则会设置为一个随机取得的可用端口。推荐自己设置一个端口
""
GDD_MEM_DEAD_TIMEOUT
如果在GDD_MEM_DEAD_TIMEOUT设置的超时时间范围内,没有收到已经判定为dead的节点的复活消息,则会从缓存里把这个节点信息彻底删掉
30
GDD_MEM_SYNC_INTERVAL
每隔GDD_MEM_SYNC_INTERVAL设置的时间,本地节点会随机选择一个远程节点做数据同步
5
GDD_MEM_RECLAIM_TIMEOUT
如果超过GDD_MEM_RECLAIM_TIMEOUT设置的时间,被判定为dead的节点会被具有相同名称但具有不同地址的节点替换掉
3
请参考 go-doudou-guide
可以一把生成或者替换结构体字段的json标签的命令行工具。 请参考文档。
封装了jmoiron/sqlx 的从结构体生成或者更新mysql数据库表结构,或者反过来,从数据库表结构生成结构体的命令行工具。请参考文档。
请参考 go-doudou看板
欢迎通过fork或者提交pr和issue来参与go-doudou项目。 如果你喜欢go-doudou,请记得点个星!
欢迎联系我:
原网址: 访问
创建于: 2021-10-11 09:30:22
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论