Skip to content
/ go-micro-tpl Public template

go micro framework, support grpc http kafka transport mode.

License

Notifications You must be signed in to change notification settings

whyun-com/go-micro-tpl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

f975657 · Aug 19, 2022

History

28 Commits
Aug 19, 2022
Aug 19, 2022
Aug 18, 2022
Aug 17, 2022
Aug 17, 2022
Aug 19, 2022
Aug 17, 2022
Aug 18, 2022
Aug 18, 2022
Aug 18, 2022
Aug 18, 2022
Aug 18, 2022

Repository files navigation

go-micro-tpl

go 语言版的微服务模板项目。

初始化

Windows

项目中使用了包 github.com/confluentinc/confluent-kafka-go , 需要依赖 GCC 进行编译,Windows 下需要安装 mingw 。可以手动下载安装包安装,下载地址为 https://sourceforge.net/projects/mingw-w64/files/latest/download ,安装完后将安装目录下 bin 文件夹添加到环境变量 PATH 中;或者通过 choco 进行安装,命令为 choco install mingw -y

由于项目使用了 Makefile,所以 Windows 下需要使用 gnu make。 可以使用命令 choco install make -y 进行安装;也可以直接下载安装 http://gnuwin32.sourceforge.net/downlinks/make.php ,安装完后将安装目录下 bin 文件夹添加到环境变量 PATH 中。

Linux

如果系统中之前没有安装过 GCC 等编译工具化,需要手动安装一下,以 Ubuntu 为例,安装命令如下:

apt-get install build-essential

配置

环境变量

HTTP_PORT http 监听端口号,不设置,则不开启 HTTP 服务
GRPC_PORT grpc 监听端口,不设置,则不开启 Grpc 服务
KAFKA_STARTUP_DISABLED 是否禁用 kafka,默认启用 kafka ,传 true 则禁用 kafka 监听

配置文件

同时应用需要读取 yaml 格式的配置文件,应用内部会依此从如下路径读取配置文件:环境变量 CONFIG_PATH 指定的路径,默认路径 /etc/micro-config.yaml,如果这两处都没有读取到,应用会自行退出。

当前支持的配置选项:

kafka:
  log:
    brokers: 访问日志 kafka 集群地址,逗号分隔各个broker,例如 1.2.3.4:9092,2.3.4.5:9092
  communication:
    brokers: 通信用 kafka 集群地址,逗号分隔各个broker,例如 1.2.3.4:9092,2.3.4.5:9092
redis:
  hosts:
    - redis 集群地址,逗号分隔各个节点,例如 1.2.3.4:6379,2.3.4.5:6379

构建

make build

构建完成后,会在 bin/ 目录下生成可执行程序 micro 。

运行

运行 bin/micro 会启动应用程序,不过要提前设置好环境变量和配置文件,具体参见配置小节。

测试

make test

构建镜像

代码结构

请求和响应

micro-tpl 提供了 http grpc kafka 三种通信方式,开发者可以根据需要选择其中一种或者几种来使用。

grpc 模式

首先给出一下 protobuf 定义:

syntax = "proto3";
package micro;

message User {
    string user_id = 1;
}
message MessageHeader {
    string msg_type = 1;//消息类型
    uint64 req_ms = 2;//请求触发的时间点
    string req_id = 3;//请求id
    uint32 req_pid = 4;//请求进程id
    string req_ip = 5;//请求者的ip
    map<string,string> extended_fields = 6;//扩展字段
}
message MicroRequest {
    MessageHeader header = 2;
    User user = 3;
    string req_data_json = 4;//请求正文,json 字符串格式
}
message Result {
    uint32 code = 1;
    string msg = 2;
}
message MicroResponse {
    MessageHeader header = 1;
    Result result = 2;//请求结果
    string res_data_json = 3;//响应正文,json 字符串格式
}

service Micro {
    // Sends a greeting
    rpc DoRequest (MicroRequest) returns (MicroResponse) {
    }
}

请求体 MicroRequest 分为三部分: 头信息 用户信息请求正文。其中 头信息 中的 msg_type 被服务端用来做路径映射使用,如果不存在当前 msg_type 对应的路由信息,则代表当前请求不被支持。虽然整个数据结构使用的 protobuf 来定义,但是这里依然把 请求正文 字段设计为 JSON 字符串格式 ,而不是纯 protobuf 对象,这样新增请求消息类型时,客户端和服务端不用修改 protobuf 文件定义,显得更加灵活。

响应体 MicroResponse 分为三部分:头信息 请求结果 响应正文。其中 头信息 中除了 msg_type 字段之外,其他字段和其匹配的请求体中的 头信息 中的值保持一致。

kafka 模式

kafka 模式下消费者得到的数据包中的 value 字段是一个 JSON 字符串,其数据结构和 grpc 的请求消息体格式类似:

{
    user: Object,
    header: Object,
    req_data: Object
}

其中 header 属性和 user 属性的类型 和 protobuf 中定义的一致,由于 kafka 模式下消息正文本身就是一个 JSON,所以 req_data 的类型不是字符串而是 JSON Object。

kafka 模式没响应正文数据包,因为这个模式的设计初衷是用来承载异步消息处理,适合请求者发送完请求后,不关心处理结果的场景。如果当前请求处理出错,可以使用报警信息来提示相关人员。

http 模式

http 模式使用 POST JSON 的方式提交请求数据,JSON 的格式和 kafka 模式是相同的,同时为了方便后端服务进行路由,每个请求都需要携带请求头 message-msg-type,其值为 JSON 数据中的 header.msg_type 字段值。

路由

服务器端

服务器端路由位于文件 src/route/route.go 中,其格式定义为以 header.msg_type 为 key,以 reqcontext.ServiceConfig 为 value。下面是一个示例:

var RouteMap = map[string]reqcontext.ServiceConfig{
	"demo_get": {Service: service.DemoGet},
}

上述代码指示,对于请求类型为 demo_get 的请求使用函数 service.DemoGet 进行处理。

通信协议

虽然目前仅支持 grpc kafka http 三种通信协议,但是如果想增加新的通信协议的话,需要根据使用的驱动情况做分别处理。

显式返回请求数据

第三方协议的驱动需要显式拿到处理后的结果,在驱动内部做发送,则需要做如下处理:

首先在 src/filter 文件夹下,写一个当前新增协议的解析处理文件,假设命名为 xx_filter.go,在其中暴漏一个如下函数:

// XXRequest XXResponse 分别为当前协议特定的请求和响应数据结构
func DoXXFilter(in *XXRequest) (*XXResponse, error) {
    //在里面实现从 XXRequest 到 reqcontext.RequestPacket 的转化,以方便用来调用路由函数,
    //调用完路由函数后,将得到 reqcontext.MicroResponse 结构再转化为 XXResponse 进行返回。
}

调用驱动暴漏的发送函数

在 src/filter 中,新增一个文件,假设命名为 xx_filter.go,然后在其中实现如下函数:

// XXRequest XXResponse 分别为当前协议特定的请求和响应数据结构
func DoXXFilter(in *XXRequest) {
    //在里面实现从 XXRequest 到 reqcontext.RequestPacket 的转化,以方便用来调用路由函数,
    //并根据 reqcontext.RequestPacket 对象初始化一个 reqcontextXX 对象,
    //将 reqcontext.RequestPacket 对象和  reqcontextXX 对象传入路由函数
}

上述伪代码中的 reqcontextXX 需要继承自 src\reqcontext\request_context.go 下的 BaseContext 结构体,且实现接口 ContextInterface 中的 doErrordoSuccess 两个函数。

打点

访问日志

为了让服务的数据更好的做追踪,代码中设计了访问日志写入逻辑,写入的字段定义参见代码 src\reqcontext\access_log.go 中的 AccessLog 结构。

LICENSE

MIT

TODO

  • 配置项更改时动态感知到
  • 错误码定义
  • docker 镜像构建
  • 数据库使用示例

About

go micro framework, support grpc http kafka transport mode.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published