github.com/erda-project/erda-infra@v1.0.9/README_zh.md (about) 1 # Erda Infra 2 3 [](https://pkg.go.dev/github.com/erda-project/erda-infra) 4 [](https://www.apache.org/licenses/LICENSE-2.0.html) 5 [](https://codecov.io/gh/erda-project/erda-infra) 6 7 翻译: [English](README.md) | [简体中文](README_zh.md) 8 9 Erda Infra 一套轻量级 Go 微服务框架,包含大量现成的模块和工具,能够快速构建起以模块化驱动的应用程序。 10 11 一些 Go 项目基于该框架进行构建: 12 * [Erda](https://github.com/erda-project/erda) 13 14 ## 特性 15 * 以模块化设计方式来驱动应用系统实现,支持模块可插拔 16 * 统一配置读取,支持默认值、支持从文件、环境变量、命令行参数读取 17 * 统一模块的初始化、启动、关闭 18 * 统一管理模块间的依赖关系 19 * 支持模块间的依赖注入 20 * 包含大量现成的微模块 21 * 支持统一 gRPC 和 HTTP 接口设计、以及拦截器 22 * 提供快速构建模块的脚本 23 * 等等 24 25 ## 概念 26 * Service,服务,表示某个具体的功能 27 * Provider,服务的提供者,提供0个或多个 Service,也可以依赖0个或多个其他 Service,被依赖的 Service 由其他 Provider 提供 28 * ProviderDefine,提供 Provider 相关的元信息,比如:提供 Provider 的构造函数。通过 *servicehub.RegisterProvider* 来注册 Provider 29 * Hub,是所有 Provider 的容器,管理所有已加载的 Provider 的生命周期 30 31 所有已注册的 Provider 通过 一份配置来确定是否 加载,由 Hub 对已加载的 Provider 的进行初始化、启动、关闭等。 32 33  34 35 ## Provider 定义 36 通过实现 *servicehub.ProviderDefine* 接口来定义一个模块,并 通过 *servicehub.RegisterProvider* 函数进行注册。 37 38 但更简单的是通过 *servicehub.Spec* 来描述一个模块,并 通过 *servicehub.Register* 函数进行注册。 39 40 [例子](./base/servicehub/examples) 41 42 ## Quick Start 43 ### 快速创建一个模块 44 **第一步**,创建模块 45 ```sh 46 ➜ gohub init -o helloworld 47 Input Service Provider Name: helloworld 48 ➜ # 以上命令创建了一个模块的模版代码,文件如下: 49 ➜ tree helloworld 50 helloworld 51 ├── provider.go 52 └── provider_test.go 53 ``` 54 55 **第二步**,创建 main.go 56 ```go 57 package main 58 59 import ( 60 "github.com/erda-project/erda-infra/base/servicehub" 61 _ "./helloworld" // your package import path 62 ) 63 64 func main() { 65 servicehub.Run(&servicehub.RunOptions{ 66 Content: ` 67 helloworld: 68 `, 69 }) 70 } 71 ``` 72 73 **第三步**,运行程序 74 ```sh 75 ➜ go run main.go 76 INFO[2021-04-13 13:17:36.416] message: hi module=helloworld 77 INFO[2021-04-13 13:17:36.416] provider helloworld initialized 78 INFO[2021-04-13 13:17:36.416] signals to quit: [hangup interrupt terminated quit] 79 INFO[2021-04-13 13:17:36.426] provider helloworld running ... 80 INFO[2021-04-13 13:17:39.429] do something... module=helloworld 81 ``` 82 [Hello World](./examples/example) \( [helloworld/](./examples/example/helloworld) | [main.go](./examples/example/main.go) \) 83 84 ### 创建 HTTP/gRPC 服务 85 这些服务既可以被远程调用,也可以被本地模块调用。 86 87 **第一步**,在 *.proto 文件中定义协议 (消息结构 和 接口) 88 ```protobuf 89 syntax = "proto3"; 90 91 package erda.infra.example; 92 import "google/api/annotations.proto"; 93 option go_package = "github.com/erda-project/erda-infra/examples/service/protocol/pb"; 94 95 // the greeting service definition. 96 service GreeterService { 97 // say hello 98 rpc SayHello (HelloRequest) returns (HelloResponse) { 99 option (google.api.http) = { 100 get: "/api/greeter/{name}", 101 }; 102 } 103 } 104 105 message HelloRequest { 106 string name = 1; 107 } 108 109 message HelloResponse { 110 bool success = 1; 111 string data = 2; 112 } 113 ``` 114 115 **第二步**,编译生成接口 和 客户端代码 116 ```sh 117 ➜ gohub protoc protocol *.proto 118 ➜ tree 119 . 120 ├── client 121 │ ├── client.go 122 │ └── provider.go 123 ├── greeter.proto 124 └── pb 125 ├── greeter.form.pb.go 126 ├── greeter.http.pb.go 127 ├── greeter.pb.go 128 ├── greeter_grpc.pb.go 129 └── register.services.pb.go 130 ``` 131 132 **第三步**,实现协议接口 133 ```sh 134 ➜ gohub protoc imp *.proto --imp_out=../server/helloworld 135 ➜ tree ../server/helloworld 136 ../server/helloworld 137 ├── greeter.service.go 138 ├── greeter.service_test.go 139 └── provider.go 140 ``` 141 142 **第四步**,创建 main.go 启动程序 143 144 *main.go* 145 ``` 146 package main 147 148 import ( 149 "os" 150 151 "github.com/erda-project/erda-infra/base/servicehub" 152 153 // import all providers 154 _ "github.com/erda-project/erda-infra/examples/service/server/helloworld" 155 _ "github.com/erda-project/erda-infra/providers" 156 ) 157 158 func main() { 159 hub := servicehub.New() 160 hub.Run("server", "server.yaml", os.Args...) 161 } 162 ``` 163 164 *server.yaml* 165 ```yaml 166 # optional 167 http-server: 168 addr: ":8080" 169 grpc-server: 170 addr: ":7070" 171 service-register: 172 # expose services and interface 173 erda.infra.example: 174 ``` 175 176 [Service](./examples/service) \( [Protocol](./examples/service/protocol) | [Implementation](./examples/service/server/helloworld) | [Server](./examples/service/server) | [Caller](./examples/service/caller) | [Client](./examples/service/client) \) 177 178 179 ## 微模块 180 该项目中已经封装了许多可用的模块,在 [providers/](./providers) 目录下可以找到。 181 182 每一个模块下面,都有一个 examples 目录,包含了该模块的使用例子。 183 184 * elasticsearch,对 elasticsearch 客户端的封装,更方便的进行批量数据的写入 185 * etcd,对 etcd 客户端的封装 186 * etcd-mutex,利用 etcd 实现的分布式锁 187 * grpcserver,启动一个 gRPC server 188 * grpcclient,统一管理 gRPC 客户端 189 * health,通过 httpserver 注册一个健康检查的接口 190 * httpserver,提供一个 HTTP server, 支持任意形式的处理函数、拦截器、参数绑定、参数校验等 191 * i18n,提供了国际化的支持,可以统一管理国际化文件、支持模版 192 * kafka,提供了访问 kafka 相关的能力,更方便地去批量消费和推送消息 193 * kubernetes,对 kubernetes 客户端的封装 194 * mysql,对 mysql 客户端的封装 195 * pprof,通过 httpserver 注册一些 pprof 相关的接口 196 * redis,对 redis 客户端的封装 197 * zk-master-election,通过 zookeeper 实现主从选举 198 * zookeeper,对 zookeeper 客户端的封装 199 * cassandra,对 Cassandra 客户端的封装 200 * serviceregister,封装提供统一注册 gRPC 和 HTTP 接口的能力 201 202 # 工具 203 *gohub* 是一个能够帮助您快速构建模块的命令行工具,可以通过如下方式安装: 204 ```sh 205 go get -u github.com/erda-project/erda-infra/tools/gohub 206 ``` 207 208 也可以通过 Docker 容器来使用以下工具: 209 ```sh 210 ➜ docker run --rm -ti -v $(pwd):/go \ 211 registry.cn-hangzhou.aliyuncs.com/dice/erda-tools:1.0 gohub 212 Usage: 213 gohub [flags] 214 gohub [command] 215 216 Available Commands: 217 help Help about any command 218 init Initialize a provider with name 219 pkgpath Print the absolute path of go package 220 protoc ProtoBuf compiler tools 221 tools Tools 222 version Print the version number 223 224 Flags: 225 -h, --help help for gohub 226 227 Use "gohub [command] --help" for more information about a command. 228 ``` 229 230 ## License 231 Erda Infra is under the Apache 2.0 license. See the [LICENSE](/LICENSE) file for details.