1.概述
Go-Kit 是一个面向微服务架构的工具集,旨在简化开发和部署分布式系统。它提供了一组库和工具,用于解决微服务架构中常见的问题,例如服务发现、负载均衡、日志记录、跟踪、错误处理等。
github地址:GitHub – go-kit/kit: A standard library for microservices.

2.代码
新建一个项目,删除自带的gomod文件
在项目下新建一个目录usersvc
这是一个处理user的逻辑
生成一个go mod 文件
go mod init usersvc

在 Go-Kit 中,常见的三层架构模式是指将应用程序拆分为以下三个层次:
- 服务层(Service Layer):服务层是应用程序的最高层,负责定义业务逻辑和处理业务流程。它通常包含了一组接口,定义了服务的方法和操作。服务层的目标是提供高级别的抽象,隐藏底层的实现细节。
- 传输层(Transport Layer):传输层负责处理与外部系统的通信,也就是服务的输入和输出。它可以支持多种传输协议,例如 HTTP、gRPC、消息队列等。传输层将外部请求转发给服务层进行处理,并将服务层的响应返回给调用方。
- 端点层(Endpoint Layer):端点层位于服务层和传输层之间,用于连接两者。它将传输层的请求映射到服务层的方法,并将服务层的响应转换为传输层可理解的格式。端点层还可以处理一些公共的横切关注点,例如认证、日志记录、错误处理等。
新建三个目录

service层
首先先实现一个service,在service包下新建一个service.go
package service
import "errors"
// User 是用户结构体
type User struct {
ID string
Name string
}
// UserService 提供用户管理的服务接口
type UserService interface {
GetUser(id string) (User, error)
PostUser(id string) (User, error)
}
// UserServiceImpl 是 UserService 的具体实现
type UserServiceImpl struct {
}
// GetUser 实现了获取用户的方法
func (s *UserServiceImpl) GetUser(id string) (User, error) {
if id == "" {
return User{}, errors.New("id is empty")
}
// 假设这里会根据 ID 查询数据库或其他存储,返回一个用户对象
// 这里只是一个简单的示例,没有实际的数据库操作
return User{
ID: id,
Name: "Dreams",
}, nil
}
// PostUser 实现了获取用户的方法,是post方法
func (s *UserServiceImpl) PostUser(id string) (User, error) {
if id == "" {
return User{}, errors.New("id is empty")
}
// 假设这里会根据 ID 查询数据库或其他存储,返回一个用户对象
// 这里只是一个简单的示例,没有实际的数据库操作
return User{
ID: id,
Name: "tanjy",
}, nil
}endpoint层
在endpoint包下
使用endpoint
go get github.com/go-kit/kit/endpointGetUserRequest

endpoint.go 文件的主要目的是定义和实现服务端点(endpoint)。在 Go 语言中,端点是处理特定请求的单个处理程序。
使用端点可以将业务逻辑从传输层(例如 HTTP、gRPC 等)解耦出来,使其更加可重用和可测试。端点充当了服务和传输层之间的桥梁,将传输层的请求转换为服务的输入,并将服务的输出转换为传输层的响应。
在 endpoint.go 中,您可以定义一个或多个端点函数,每个端点函数都接收请求并返回响应。这些端点函数通常需要调用底层的服务方法来执行实际的业务逻辑。
代码如下
package endpoint
import (
"context"
"github.com/go-kit/kit/endpoint"
"usersvc/service"
)
/**
1.GetUser请求
*/
// MakeGetUserEndpoint 创建获取用户的端点
func MakeGetUserEndpoint(svc service.UserServiceImpl) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(GetUserRequest)
user, err := svc.GetUser(req.ID)
if err != nil {
return GetUserResponse{User: service.User{}, Err: err.Error()}, nil
}
return GetUserResponse{User: user, Err: ""}, nil
}
}
// GetUserRequest get请求
type GetUserRequest struct {
ID string `json:"id"`
}
// GetUserResponse get返回
type GetUserResponse struct {
User service.User `json:"user"`
Err string `json:"error,omitempty"`
}
/**
2.PostUser请求
*/
// MakePostUserEndpoint 创建获取用户的端点
func MakePostUserEndpoint(svc service.UserServiceImpl) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(PostUserRequest)
user, err := svc.GetUser(req.ID)
if err != nil {
return PostUserResponse{User: service.User{}, Err: err.Error()}, nil
}
return PostUserResponse{User: user, Err: ""}, nil
}
}
// PostUserRequest post请求
type PostUserRequest struct {
ID string `json:"id"`
}
// PostUserResponse post返回
type PostUserResponse struct {
User service.User `json:"user"`
Err string `json:"error,omitempty"`
}比如上述代码,我们定义了 MakeGetUserEndpoint 函数,它创建了一个获取用户的端点。该函数接受一个 UserService 接口的实例作为参数,并返回一个 endpoint.Endpoint 类型的函数。这个函数会根据传入的GetUserRequest请求调用服务的 GetUser 方法,并将结果转换为响应对象GetUserResponse 。
transport层
接着是transport层的transport.go
gorilla/mux 是一个用于构建 HTTP 服务的 Go 语言路由器和调度器。它扩展了标准库的 net/http 包,提供了更强大和灵活的路由匹配和 URL 构建功能。
导入
go get -u github.com/gorilla/mux

json.NewEncoder 是 Go 语言标准库中的一个函数,用于创建一个新的 JSON 编码器(Encoder)。JSON 编码器可以将数据编码为 JSON 格式,并输出到一个 io.Writer 接口类型的输出流中。
代码如下
- decode**Request方法用来解析用户发送来的数据
- encode**Response方法用来编码给客户发送的数据
package transport
import (
"context"
"encoding/json"
httptransport "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
"log"
"net/http"
"usersvc/endpoint"
"usersvc/service"
)
func decodeGetUserRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request endpoint.GetUserRequest
err := json.NewDecoder(r.Body).Decode(&request)
return request, err
}
func decodePostUserRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request endpoint.PostUserRequest
err := json.NewDecoder(r.Body).Decode(&request)
return request, err
}
// encodeResponse 函数的作用是将响应对象转换为 JSON 格式,并写入到 HTTP 响应中,以便于向客户端返回相应的数据。
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
func UserHandler(svc service.UserServiceImpl) http.Handler {
router := mux.NewRouter()
router.Methods("GET").Path("/getUser").Handler(httptransport.NewServer(
endpoint.MakeGetUserEndpoint(svc),
decodeGetUserRequest,
encodeResponse,
))
router.Methods("POST").Path("/postUser").Handler(httptransport.NewServer(
endpoint.MakePostUserEndpoint(svc),
decodePostUserRequest,
encodeResponse,
))
return router
}
func Run() {
svc := service.UserServiceImpl{}
router := UserHandler(svc)
log.Fatal(http.ListenAndServe(":8082", router))
}router.Methods().Path().Handler() 是 Gorilla Mux 路由器的一种链式调用方法,用于定义路由、HTTP 方法和处理函数之间的映射关系。挺见名知意,Handler() 里面 参数是一个处理 HTTP 请求的函数或处理器。
服务器通过调用 endpoint.MakeGetUserEndpoint(svc) 创建了一个 httptransport.Endpoint,它是 Go Kit 中的另一个组件,用于处理特定的业务逻辑。
在decodeGetUserRequest函数中,我们使用 json.NewDecoder 解码传入的 JSON 请求,并将其转换为 Request 结构体。
在 encodeResponse 函数中,我们使用 json.NewEncoder 将响应数据编码为 JSON,并发送给客户端。
实现好这三个函数,直接传入函数名即可,go语言会自己调用
再写个main.go去调用一下
package main
import "usersvc/transport"
func main() {
transport.Run()
}执行前先,下载完全
go mod tidy
再运行
get请求http://localhost:8082/getUser

post请求http://localhost:8082/postUser



