github.com/erda-project/erda-infra@v1.0.9/README_zh.md (about)

     1  # Erda Infra
     2  
     3  [![Go Reference](https://pkg.go.dev/badge/github.com/erda-project/erda-infra.svg)](https://pkg.go.dev/github.com/erda-project/erda-infra)
     4  [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
     5  [![codecov](https://codecov.io/gh/erda-project/erda-infra/branch/develop/graph/badge.svg?token=SVROJLY8UK)](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  ![servicehub](./docs/servicehub.jpg)
    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.