-

【基础工具】Docker使用

+

【基础工具】Docker基础功能

- Last updated on January 19, 2024 pm + Last updated on January 27, 2024 pm

@@ -511,7 +511,7 @@

Wordpress安装

-
【基础工具】Docker使用
+
【基础工具】Docker基础功能
https://lihaibineric.github.io/2024/01/19/docker/
@@ -530,7 +530,7 @@

Wordpress安装

Updated on
-
January 19, 2024
+
January 27, 2024
diff --git a/2024/01/19/pymarl-code/index.html b/2024/01/19/pymarl-code/index.html index 48ec1eb..3f4a35b 100644 --- a/2024/01/19/pymarl-code/index.html +++ b/2024/01/19/pymarl-code/index.html @@ -535,8 +535,8 @@

Test

- - 【基础工具】Docker使用 + + 【基础工具】Docker基础功能 Next diff --git a/2024/01/23/go-kit/index.html b/2024/01/23/go-kit/index.html index 825c4c2..8cc0f91 100644 --- a/2024/01/23/go-kit/index.html +++ b/2024/01/23/go-kit/index.html @@ -16,18 +16,20 @@ - + - + + - + + @@ -208,7 +210,7 @@ @@ -219,7 +221,7 @@ - 27 mins + 83 mins @@ -261,7 +263,7 @@

【后端开发】Go kit框架

- Last updated on January 27, 2024 am + Last updated on January 27, 2024 pm

@@ -274,13 +276,13 @@

Go-kit框架

Go-kit 是一个功能丰富、易于使用的分布式微服务框架,旨在帮助开发者构建健壮、可维护和可测试的分布式系统。它通过提供一系列可组合的组件,解决了分布式系统中的常见问题,使开发者能够专注于业务逻辑。Go-kit 的核心理念是通过可插拔的组件来实现微服务的功能,这些组件包括服务发现、负载均衡、请求追踪、日志记录和监控等。

+

Go-kit基本架构

Go-kit 包含了一些基本的组件,如服务端点(Endpoint)、传输层(Transport)、服务发现、负载均衡等。服务端点是 Go-kit 中微服务的基本构建块,用于定义 RPC 消息模式。传输层提供了将特定序列化算法绑定到端点的辅助方法,目前支持 JSON 和 HTTP 协议。

Go-kit的架构来源:https://github.com/go-kit/kit

-

Go-kit简单demo

基本的Go-kit的三层架构

  1. Transport

    @@ -290,6 +292,7 @@

    Go-kit简单demo

  2. Service

    主要职责是处理业务逻辑,也就是应用程序的核心功能和规则,这里就是我们的业务类、接口等。

+

Go-kit的demo

接下来我们将给出一个简单的demo(对输入的字符串大写转换和字符串个数计数的功能)来对Go-kit的基本架构的实现和功能展示:

Service层

首先这个层会给出业务的逻辑实现,核心功能和规则

@@ -303,10 +306,56 @@

Endpoint层

这部分会给出不同的endpoint接口的类型定义,使用不同的type定义request和response的json格式类型,用于后续的变量的选择命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package endpoints

import (
"context"
"github.com/go-kit/kit/endpoint"
"go-kit-test/services"
)

//这个地方借助go-kit来实现endpoint的内容
// uppercaseRequest 和 uppercaseResponse 用于 Uppercase 端点
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}

定义总的Endpoints接口,type Endpoints这个地方将会用于后续的对象的创建,func MakeEndpoints函数将被其他的函数进行调用用于创建内部的端点对象,其中在创建的过程中会调用以下的函数来分别创建两个功能的端口类型

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
type Endpoints struct {
UppercaseEndpoint endpoint.Endpoint
CountEndpoint endpoint.Endpoint
}

// MakeEndpoints 创建并返回所有服务端点
func MakeEndpoints(svc services.StringService) Endpoints {
return Endpoints{
UppercaseEndpoint: MakeUppercaseEndpoint(svc),
CountEndpoint: MakeCountEndpoint(svc),
}
}

// MakeUppercaseEndpoint 创建 Uppercase 端点
func MakeUppercaseEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
result, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{result, err.Error()}, nil
}
return uppercaseResponse{result, ""}, nil
}
}

// MakeCountEndpoint 创建 Count 端点
func MakeCountEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
result := svc.Count(req.S)
return countResponse{result}, nil
}
}

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
type Endpoints struct {
UppercaseEndpoint endpoint.Endpoint
CountEndpoint endpoint.Endpoint
}

// MakeEndpoints 创建并返回所有服务端点
func MakeEndpoints(svc services.StringService) Endpoints {
return Endpoints{
UppercaseEndpoint: MakeUppercaseEndpoint(svc),
CountEndpoint: MakeCountEndpoint(svc),
}
}

// MakeUppercaseEndpoint 创建 Uppercase 端点
func MakeUppercaseEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
result, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{result, err.Error()}, nil
}
return uppercaseResponse{result, ""}, nil
}
}

// MakeCountEndpoint 创建 Count 端点
func MakeCountEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
result := svc.Count(req.S)
return countResponse{result}, nil
}
}
+

Transport层

+

主体的实现框架,分别给出了两个不同服务接口的responserequest的数据类型这部分给出json格式

+

http.NewServeMux()返回一个新的http.ServeMux,这是一个用于处理HTTP请求的请求轮询器(request +router)。接下来,为/uppercase和/count路径分别配置了新的httptransport.NewServer服务

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}
// MakeHTTPHandler 创建 HTTP 处理程序
func MakeHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
options := []httptransport.ServerOption{
httptransport.ServerErrorEncoder(errorEncoder),
}
//http.NewServeMux()返回一个新的http.ServeMux,这是一个用于处理HTTP请求的请求轮询器(request router)。
//接下来,为/uppercase和/count路径分别配置了httptransport.NewServer:
m := http.NewServeMux()
//httptransport.NewServer是一个函数,它接受几个参数来创建一个新的HTTP服务器端点:
m.Handle("/uppercase", httptransport.NewServer(
endpoints.UppercaseEndpoint,
decodeUppercaseRequest,
encodeResponse,
options...,
))
m.Handle("/count", httptransport.NewServer(
endpoints.CountEndpoint,
decodeCountRequest,
encodeResponse,
options...,
))

return m
}
+

注意在定义endpoint的时候,要对request编码,对response解码

+

具体的解码和编码的过程如下:

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request uppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}

// decodeCountRequest 解码 HTTP 请求并创建 Count 请求结构
func decodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request countRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}

// encodeResponse 将响应编码为 JSON 并写入 HTTP 响应
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
+

Main主层

+

这一层是最外层的调用层:go run main.go,这一层的逻辑实现主要是:

    -
  • +
  • 创建一个service服务接口对象
  • +
  • 将接口对象作为参数传入并生成endpoint相应的端点
  • +
  • httpHandler := transports.MakeHTTPHandler(eps)这一步是产生http的根据提供的Endpoint配置来创建一个HTTP处理程序,这个处理程序负责处理来自客户端的HTTP请求,并将响应返回给客户端
  • +
  • 对于任何来到根路径("/")的请求,都应该由httpHandler来处理。httpHandler是在之前的步骤中创建的HTTP处理程序,它知道如何处理HTTP请求并生成响应。这意味着当你访问服务器的根URL(例如,http://localhost:8080/)时,httpHandler中定义的处理逻辑将会被执行
  • +
  • 其中端口8080可以根据自己的需求进行指定
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"go-kit-test/endpoints"
"go-kit-test/services"
"go-kit-test/transports"
"net/http"
"os"
)

func main() {
svc := services.SStringService{} //定义一个对象svc
eps := endpoints.MakeEndpoints(svc) //接收svc作为输入,创建endpoint端点
httpHandler := transports.MakeHTTPHandler(eps)

http.Handle("/", httpHandler)
port := ":8080"
if p := os.Getenv("PORT"); p != "" {
port = ":" + p
}

println("Service listening on port" + port)
http.ListenAndServe(port, nil)
}
+

Go-kit+Gin架构

+

Go-kit是一个微服务工具集,它提供了服务发现、负载均衡、请求追踪、日志记录和监控等功能,帮助开发者构建健壮、可维护、可测试的分布式系统。

+

Gin是一个轻量级的Go +Web框架,它提供了一个优雅的API和中间件支持,使得编写Web应用程序变得更加快速和简单

+

将两者进行结合:Gin负责处理HTTP请求和响应,提供路由和中间件功能,而go-kit则可以处理服务间的通信,提供服务发现、负载均衡等分布式系统功能。go-kit和Gin的结合使用,可以使得Go +Web应用的开发更加高效和模块化,有助于构建高性能、可伸缩且易于维护的分布式系统。

+

ApiService实现

+

我们需要利用gin对web端的应用程序进行实现,因此在这个架构之下我们设计的框架为:

+

Gin+Gokit架构图结构

+

其中services、endpoints、transports的功能和原来的go-kit基本一样,而handler主要处理的是gin的关于web端内容的控制,下面给出具体的实现

+

Service层

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package services
type IUserService interface {
GetName(userId int) string
}

type UserService struct {
}

func (s UserService) GetName(userId int) string {
if userId == 101 {
return "calvin"
}
return "guest"
}
+

这个地方给出了具体的业务的实现接口功能

+

Endpoint层

+

在实现端口的过程中一般都需要对相关的type类型进行定义和对应的json格式的描述,函数GetUserEndPoint返回一个endpoint.Endpoint的类型,这个函数用于后续的调用产生endpoint

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package endpoints

import (
"ApiService/services"
"context"
"github.com/go-kit/kit/endpoint"
)
type UserRequest struct {
Uid int `json:"uid"`
}

type UserResponse struct {
Result string `json:"result"`
}
func GetUserEndPoint(userService services.IUserService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(UserRequest)
result := userService.GetName(r.Uid)
return UserResponse{Result: result}, nil
}
}

+

Transport层

+

主要做的事情就是对requestresponse的解码和编码过程,因为通过对request的解码才能转换成能识别的json格式,才能进行业务端的使用,而后面的编码是为了能够进入web

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package transports
import (
"ApiService/endpoints"
"context"
"errors"
httptransport "github.com/go-kit/kit/transport/http"
"net/http"
"strconv"
)
// 请求解码函数
func DecodeUserRequest(ctx context.Context, r *http.Request) (interface{}, error) {
// 限定参数来源,我们直接从url的params中获取用户id
// 请求格式类似于:http://127.0.0.1?uid=101
if r.URL.Query().Get("uid") != "" {
uid, _ := strconv.Atoi(r.URL.Query().Get("uid")) //strconv.Atoi(...)将字符串转化为整数
return endpoints.UserRequest{Uid: uid}, nil
}
return nil, errors.New("参数错误")
}

// 响应编码函数
func EncodeUserResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
// 将返回体body置为json格式
return httptransport.EncodeJSONResponse(context.Background(), w, response)
}
+

Handle层

+

这一层主要的作用就是利用gin来对web的实现,传递的参数分别是

+

handler := httptransport.NewServer(endpoint, transports.DecodeUserRequest, transports.EncodeUserResponse)

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package handler

import (
. "ApiService/endpoints"
. "ApiService/services"
"ApiService/transports"
"github.com/gin-gonic/gin"
httptransport "github.com/go-kit/kit/transport/http"
)
// 创建 Gin 路由
func MakeGinHandler(svc IUserService) *gin.Engine {
//初始化一个Gin引擎,并配置了一些中间件
r := gin.New()
r.Use(gin.Logger()) //用于记录每个请求的详细信息,例如请求方法、URL、执行时间等
r.Use(gin.Recovery()) //在程序发生 panic 时恢复运行,并返回一个500的HTTP状态码

// 创建 Go kit 的 endpoint
endpoint := GetUserEndPoint(svc)

// 创建 HTTP 传输层处理程序
handler := httptransport.NewServer(endpoint, transports.DecodeUserRequest, transports.EncodeUserResponse)
r.GET("/hello", gin.WrapH(handler))
return r
}

+

Main层

+

这一层的实现是通过以下三个步骤实现的:

+
    +
  • 创建go -kit服务
  • +
  • 创建gin路由并绑定服务
  • +
  • 启动gin服务器
  • +
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
. "ApiService/handler"
. "ApiService/services"
"log"
)
func main() {
// 创建 Go kit 服务
userSvc := UserService{}
// 创建 Gin 路由并绑定服务
r := MakeGinHandler(userSvc)
// 启动 Gin 服务器
if err := r.Run(":8080"); err != nil {
log.Fatal(err)
}
}
/*
说明,这个demo运行后,浏览器输入 http://127.0.0.1:8080/hello?uid=1999 即可测试,还可以输入下面的内容进行测试:
http://127.0.0.1:8080/hello
http://127.0.0.1:8080
*/
diff --git a/archives/2024/01/index.html b/archives/2024/01/index.html index 5568a8d..bd74c18 100644 --- a/archives/2024/01/index.html +++ b/archives/2024/01/index.html @@ -226,7 +226,7 @@ -
【基础工具】Docker使用
+
【基础工具】Docker基础功能
diff --git a/archives/2024/index.html b/archives/2024/index.html index 32dbf7e..369eca0 100644 --- a/archives/2024/index.html +++ b/archives/2024/index.html @@ -226,7 +226,7 @@ -
【基础工具】Docker使用
+
【基础工具】Docker基础功能
diff --git a/archives/index.html b/archives/index.html index 303e1cc..e257949 100644 --- a/archives/index.html +++ b/archives/index.html @@ -226,7 +226,7 @@ -
【基础工具】Docker使用
+
【基础工具】Docker基础功能
diff --git a/categories/index.html b/categories/index.html index f23a424..105ea79 100644 --- a/categories/index.html +++ b/categories/index.html @@ -239,10 +239,10 @@ - - 【基础工具】Docker使用 + 【基础工具】Docker基础功能 diff --git "a/categories/\345\237\272\347\241\200\345\267\245\345\205\267/index.html" "b/categories/\345\237\272\347\241\200\345\267\245\345\205\267/index.html" index a636a2c..4ca4bfb 100644 --- "a/categories/\345\237\272\347\241\200\345\267\245\345\205\267/index.html" +++ "b/categories/\345\237\272\347\241\200\345\267\245\345\205\267/index.html" @@ -214,7 +214,7 @@ -
【基础工具】Docker使用
+
【基础工具】Docker基础功能
diff --git a/index.html b/index.html index ffb8690..f2b607e 100644 --- a/index.html +++ b/index.html @@ -218,7 +218,7 @@

- Go-kit框架 Go-kit 是一个功能丰富、易于使用的分布式微服务框架,旨在帮助开发者构建健壮、可维护和可测试的分布式系统。它通过提供一系列可组合的组件,解决了分布式系统中的常见问题,使开发者能够专注于业务逻辑。Go-kit 的核心理念是通过可插拔的组件来实现微服务的功能,这些组件包括服务发现、负载均衡、请求追踪、日志记录和监控等。 Go-kit 包含了一些基本的组件,如服务端点(Endpo + Go-kit框架 Go-kit 是一个功能丰富、易于使用的分布式微服务框架,旨在帮助开发者构建健壮、可维护和可测试的分布式系统。它通过提供一系列可组合的组件,解决了分布式系统中的常见问题,使开发者能够专注于业务逻辑。Go-kit 的核心理念是通过可插拔的组件来实现微服务的功能,这些组件包括服务发现、负载均衡、请求追踪、日志记录和监控等。 Go-kit基本架构 Go-kit 包含了一些基本的组件,
@@ -337,7 +337,7 @@

- 【基础工具】Docker使用 + 【基础工具】Docker基础功能

diff --git a/local-search.xml b/local-search.xml index e1c009e..1a42286 100644 --- a/local-search.xml +++ b/local-search.xml @@ -8,7 +8,7 @@ /2024/01/23/go-kit/ -

Go-kit框架

Go-kit是一个功能丰富、易于使用的分布式微服务框架,旨在帮助开发者构建健壮、可维护和可测试的分布式系统。它通过提供一系列可组合的组件,解决了分布式系统中的常见问题,使开发者能够专注于业务逻辑。Go-kit的核心理念是通过可插拔的组件来实现微服务的功能,这些组件包括服务发现、负载均衡、请求追踪、日志记录和监控等。

Go-kit包含了一些基本的组件,如服务端点(Endpoint)、传输层(Transport)、服务发现、负载均衡等。服务端点是Go-kit 中微服务的基本构建块,用于定义 RPC消息模式。传输层提供了将特定序列化算法绑定到端点的辅助方法,目前支持JSON 和 HTTP 协议。

Go-kit的架构来源:https://github.com/go-kit/kit

Go-kit简单demo

基本的Go-kit的三层架构

  1. Transport

    主要负责与HTTP、gRPC、thrift等相关的逻辑,提供端到端的通信服务,不同的传输协议来实现这些功能,最常见的协议是TCP(传输控制协议)和UDP(用户数据报协议)。

  2. Endpoint

    定义Request和Response格式,并可以使用装饰器包装函数,以此来实现各种中间件嵌套。

  3. Service

    主要职责是处理业务逻辑,也就是应用程序的核心功能和规则,这里就是我们的业务类、接口等。

接下来我们将给出一个简单的demo(对输入的字符串大写转换和字符串个数计数的功能)来对Go-kit的基本架构的实现和功能展示:

Service层

首先这个层会给出业务的逻辑实现,核心功能和规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package services

import (
"errors"
"strings"
)

// StringService 定义了字符串处理服务的接口
// 这个地方给出接口,相当于是虚基类,后续的接口继承需要实现这部分的函数内容
type StringService interface {
Uppercase(string) (string, error) //返回的值是一个string和一个error
Count(string) int
}

// SStringService 实现了 StringService 接口
type SStringService struct{}

// Uppercase 将字符串转换为大写
func (SStringService) Uppercase(s string) (string, error) {
if s == "" {
return "", errors.New("Input string is empty")
}
return strings.ToUpper(s), nil //直接调用string的功能来实现大小写转换
}

// Count 返回字符串的字符数
func (SStringService) Count(s string) int {
return len(s)
}

实现功能service的方式一般总结来说是:

  • 定义服务接口Interface{},再定义结构体来实现这个接口的函数来实现继承
  • 具体的函数内容就表示了业务的实际功能

Endpoint层

这部分会给出不同的endpoint接口的类型定义,使用不同的type定义request和response的json格式类型,用于后续的变量的选择命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package endpoints

import (
"context"
"github.com/go-kit/kit/endpoint"
"go-kit-test/services"
)

//这个地方借助go-kit来实现endpoint的内容
// uppercaseRequest 和 uppercaseResponse 用于 Uppercase 端点
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}

定义总的Endpoints接口,type Endpoints这个地方将会用于后续的对象的创建,func MakeEndpoints函数将被其他的函数进行调用用于创建内部的端点对象,其中在创建的过程中会调用以下的函数来分别创建两个功能的端口类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
type Endpoints struct {
UppercaseEndpoint endpoint.Endpoint
CountEndpoint endpoint.Endpoint
}

// MakeEndpoints 创建并返回所有服务端点
func MakeEndpoints(svc services.StringService) Endpoints {
return Endpoints{
UppercaseEndpoint: MakeUppercaseEndpoint(svc),
CountEndpoint: MakeCountEndpoint(svc),
}
}

// MakeUppercaseEndpoint 创建 Uppercase 端点
func MakeUppercaseEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
result, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{result, err.Error()}, nil
}
return uppercaseResponse{result, ""}, nil
}
}

// MakeCountEndpoint 创建 Count 端点
func MakeCountEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
result := svc.Count(req.S)
return countResponse{result}, nil
}
}

]]>
+

Go-kit框架

Go-kit是一个功能丰富、易于使用的分布式微服务框架,旨在帮助开发者构建健壮、可维护和可测试的分布式系统。它通过提供一系列可组合的组件,解决了分布式系统中的常见问题,使开发者能够专注于业务逻辑。Go-kit的核心理念是通过可插拔的组件来实现微服务的功能,这些组件包括服务发现、负载均衡、请求追踪、日志记录和监控等。

Go-kit基本架构

Go-kit包含了一些基本的组件,如服务端点(Endpoint)、传输层(Transport)、服务发现、负载均衡等。服务端点是Go-kit 中微服务的基本构建块,用于定义 RPC消息模式。传输层提供了将特定序列化算法绑定到端点的辅助方法,目前支持JSON 和 HTTP 协议。

Go-kit的架构来源:https://github.com/go-kit/kit

基本的Go-kit的三层架构

  1. Transport

    主要负责与HTTP、gRPC、thrift等相关的逻辑,提供端到端的通信服务,不同的传输协议来实现这些功能,最常见的协议是TCP(传输控制协议)和UDP(用户数据报协议)。

  2. Endpoint

    定义Request和Response格式,并可以使用装饰器包装函数,以此来实现各种中间件嵌套。

  3. Service

    主要职责是处理业务逻辑,也就是应用程序的核心功能和规则,这里就是我们的业务类、接口等。

Go-kit的demo

接下来我们将给出一个简单的demo(对输入的字符串大写转换和字符串个数计数的功能)来对Go-kit的基本架构的实现和功能展示:

Service层

首先这个层会给出业务的逻辑实现,核心功能和规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package services

import (
"errors"
"strings"
)

// StringService 定义了字符串处理服务的接口
// 这个地方给出接口,相当于是虚基类,后续的接口继承需要实现这部分的函数内容
type StringService interface {
Uppercase(string) (string, error) //返回的值是一个string和一个error
Count(string) int
}

// SStringService 实现了 StringService 接口
type SStringService struct{}

// Uppercase 将字符串转换为大写
func (SStringService) Uppercase(s string) (string, error) {
if s == "" {
return "", errors.New("Input string is empty")
}
return strings.ToUpper(s), nil //直接调用string的功能来实现大小写转换
}

// Count 返回字符串的字符数
func (SStringService) Count(s string) int {
return len(s)
}

实现功能service的方式一般总结来说是:

  • 定义服务接口Interface{},再定义结构体来实现这个接口的函数来实现继承
  • 具体的函数内容就表示了业务的实际功能

Endpoint层

这部分会给出不同的endpoint接口的类型定义,使用不同的type定义request和response的json格式类型,用于后续的变量的选择命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package endpoints

import (
"context"
"github.com/go-kit/kit/endpoint"
"go-kit-test/services"
)

//这个地方借助go-kit来实现endpoint的内容
// uppercaseRequest 和 uppercaseResponse 用于 Uppercase 端点
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}

定义总的Endpoints接口,type Endpoints这个地方将会用于后续的对象的创建,func MakeEndpoints函数将被其他的函数进行调用用于创建内部的端点对象,其中在创建的过程中会调用以下的函数来分别创建两个功能的端口类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
type Endpoints struct {
UppercaseEndpoint endpoint.Endpoint
CountEndpoint endpoint.Endpoint
}

// MakeEndpoints 创建并返回所有服务端点
func MakeEndpoints(svc services.StringService) Endpoints {
return Endpoints{
UppercaseEndpoint: MakeUppercaseEndpoint(svc),
CountEndpoint: MakeCountEndpoint(svc),
}
}

// MakeUppercaseEndpoint 创建 Uppercase 端点
func MakeUppercaseEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
result, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{result, err.Error()}, nil
}
return uppercaseResponse{result, ""}, nil
}
}

// MakeCountEndpoint 创建 Count 端点
func MakeCountEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
result := svc.Count(req.S)
return countResponse{result}, nil
}
}

Transport层

主体的实现框架,分别给出了两个不同服务接口的responserequest的数据类型这部分给出json格式

http.NewServeMux()返回一个新的http.ServeMux,这是一个用于处理HTTP请求的请求轮询器(requestrouter)。接下来,为/uppercase和/count路径分别配置了新的httptransport.NewServer服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}
// MakeHTTPHandler 创建 HTTP 处理程序
func MakeHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
options := []httptransport.ServerOption{
httptransport.ServerErrorEncoder(errorEncoder),
}
//http.NewServeMux()返回一个新的http.ServeMux,这是一个用于处理HTTP请求的请求轮询器(request router)。
//接下来,为/uppercase和/count路径分别配置了httptransport.NewServer:
m := http.NewServeMux()
//httptransport.NewServer是一个函数,它接受几个参数来创建一个新的HTTP服务器端点:
m.Handle("/uppercase", httptransport.NewServer(
endpoints.UppercaseEndpoint,
decodeUppercaseRequest,
encodeResponse,
options...,
))
m.Handle("/count", httptransport.NewServer(
endpoints.CountEndpoint,
decodeCountRequest,
encodeResponse,
options...,
))

return m
}

注意在定义endpoint的时候,要对request编码,对response解码

具体的解码和编码的过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request uppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}

// decodeCountRequest 解码 HTTP 请求并创建 Count 请求结构
func decodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request countRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}

// encodeResponse 将响应编码为 JSON 并写入 HTTP 响应
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}

Main主层

这一层是最外层的调用层:go run main.go,这一层的逻辑实现主要是:

  • 创建一个service服务接口对象
  • 将接口对象作为参数传入并生成endpoint相应的端点
  • httpHandler := transports.MakeHTTPHandler(eps)这一步是产生http的根据提供的Endpoint配置来创建一个HTTP处理程序,这个处理程序负责处理来自客户端的HTTP请求,并将响应返回给客户端
  • 对于任何来到根路径("/")的请求,都应该由httpHandler来处理。httpHandler是在之前的步骤中创建的HTTP处理程序,它知道如何处理HTTP请求并生成响应。这意味着当你访问服务器的根URL(例如,http://localhost:8080/)时,httpHandler中定义的处理逻辑将会被执行
  • 其中端口8080可以根据自己的需求进行指定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"go-kit-test/endpoints"
"go-kit-test/services"
"go-kit-test/transports"
"net/http"
"os"
)

func main() {
svc := services.SStringService{} //定义一个对象svc
eps := endpoints.MakeEndpoints(svc) //接收svc作为输入,创建endpoint端点
httpHandler := transports.MakeHTTPHandler(eps)

http.Handle("/", httpHandler)
port := ":8080"
if p := os.Getenv("PORT"); p != "" {
port = ":" + p
}

println("Service listening on port" + port)
http.ListenAndServe(port, nil)
}

Go-kit+Gin架构

Go-kit是一个微服务工具集,它提供了服务发现、负载均衡、请求追踪、日志记录和监控等功能,帮助开发者构建健壮、可维护、可测试的分布式系统。

Gin是一个轻量级的GoWeb框架,它提供了一个优雅的API和中间件支持,使得编写Web应用程序变得更加快速和简单

将两者进行结合:Gin负责处理HTTP请求和响应,提供路由和中间件功能,而go-kit则可以处理服务间的通信,提供服务发现、负载均衡等分布式系统功能。go-kit和Gin的结合使用,可以使得GoWeb应用的开发更加高效和模块化,有助于构建高性能、可伸缩且易于维护的分布式系统。

ApiService实现

我们需要利用gin对web端的应用程序进行实现,因此在这个架构之下我们设计的框架为:

Gin+Gokit架构图结构

其中services、endpoints、transports的功能和原来的go-kit基本一样,而handler主要处理的是gin的关于web端内容的控制,下面给出具体的实现

Service层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package services
type IUserService interface {
GetName(userId int) string
}

type UserService struct {
}

func (s UserService) GetName(userId int) string {
if userId == 101 {
return "calvin"
}
return "guest"
}

这个地方给出了具体的业务的实现接口功能

Endpoint层

在实现端口的过程中一般都需要对相关的type类型进行定义和对应的json格式的描述,函数GetUserEndPoint返回一个endpoint.Endpoint的类型,这个函数用于后续的调用产生endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package endpoints

import (
"ApiService/services"
"context"
"github.com/go-kit/kit/endpoint"
)
type UserRequest struct {
Uid int `json:"uid"`
}

type UserResponse struct {
Result string `json:"result"`
}
func GetUserEndPoint(userService services.IUserService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(UserRequest)
result := userService.GetName(r.Uid)
return UserResponse{Result: result}, nil
}
}

Transport层

主要做的事情就是对requestresponse的解码和编码过程,因为通过对request的解码才能转换成能识别的json格式,才能进行业务端的使用,而后面的编码是为了能够进入web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package transports
import (
"ApiService/endpoints"
"context"
"errors"
httptransport "github.com/go-kit/kit/transport/http"
"net/http"
"strconv"
)
// 请求解码函数
func DecodeUserRequest(ctx context.Context, r *http.Request) (interface{}, error) {
// 限定参数来源,我们直接从url的params中获取用户id
// 请求格式类似于:http://127.0.0.1?uid=101
if r.URL.Query().Get("uid") != "" {
uid, _ := strconv.Atoi(r.URL.Query().Get("uid")) //strconv.Atoi(...)将字符串转化为整数
return endpoints.UserRequest{Uid: uid}, nil
}
return nil, errors.New("参数错误")
}

// 响应编码函数
func EncodeUserResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
// 将返回体body置为json格式
return httptransport.EncodeJSONResponse(context.Background(), w, response)
}

Handle层

这一层主要的作用就是利用gin来对web的实现,传递的参数分别是

handler := httptransport.NewServer(endpoint, transports.DecodeUserRequest, transports.EncodeUserResponse)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package handler

import (
. "ApiService/endpoints"
. "ApiService/services"
"ApiService/transports"
"github.com/gin-gonic/gin"
httptransport "github.com/go-kit/kit/transport/http"
)
// 创建 Gin 路由
func MakeGinHandler(svc IUserService) *gin.Engine {
//初始化一个Gin引擎,并配置了一些中间件
r := gin.New()
r.Use(gin.Logger()) //用于记录每个请求的详细信息,例如请求方法、URL、执行时间等
r.Use(gin.Recovery()) //在程序发生 panic 时恢复运行,并返回一个500的HTTP状态码

// 创建 Go kit 的 endpoint
endpoint := GetUserEndPoint(svc)

// 创建 HTTP 传输层处理程序
handler := httptransport.NewServer(endpoint, transports.DecodeUserRequest, transports.EncodeUserResponse)
r.GET("/hello", gin.WrapH(handler))
return r
}

Main层

这一层的实现是通过以下三个步骤实现的:

  • 创建go -kit服务
  • 创建gin路由并绑定服务
  • 启动gin服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
. "ApiService/handler"
. "ApiService/services"
"log"
)
func main() {
// 创建 Go kit 服务
userSvc := UserService{}
// 创建 Gin 路由并绑定服务
r := MakeGinHandler(userSvc)
// 启动 Gin 服务器
if err := r.Run(":8080"); err != nil {
log.Fatal(err)
}
}
/*
说明,这个demo运行后,浏览器输入 http://127.0.0.1:8080/hello?uid=1999 即可测试,还可以输入下面的内容进行测试:
http://127.0.0.1:8080/hello
http://127.0.0.1:8080
*/
]]>
@@ -58,7 +58,7 @@ - 【基础工具】Docker使用 + 【基础工具】Docker基础功能 /2024/01/19/docker/ diff --git a/search.xml b/search.xml index 7e19369..859b6cb 100644 --- a/search.xml +++ b/search.xml @@ -1088,7 +1088,7 @@ system,能够产生极高的精度;直接测量速度和距离,这进一 - 【基础工具】Docker使用 + 【基础工具】Docker基础功能 /2024/01/19/docker/

Go-kit 是一个功能丰富、易于使用的分布式微服务框架,旨在帮助开发者构建健壮、可维护和可测试的分布式系统。它通过提供一系列可组合的组件,解决了分布式系统中的常见问题,使开发者能够专注于业务逻辑。Go-kit 的核心理念是通过可插拔的组件来实现微服务的功能,这些组件包括服务发现、负载均衡、请求追踪、日志记录和监控等。

+

Go-kit基本架构

Go-kit 包含了一些基本的组件,如服务端点(Endpoint)、传输层(Transport)、服务发现、负载均衡等。服务端点是 Go-kit 中微服务的基本构建块,用于定义 RPC 消息模式。传输层提供了将特定序列化算法绑定到端点的辅助方法,目前支持 JSON 和 HTTP 协议。

Go-kit的架构来源:https://github.com/go-kit/kit

-

Go-kit简单demo

基本的Go-kit的三层架构

  1. Transport

    @@ -5227,6 +5227,7 @@ JSON 和 HTTP 协议。

  2. Service

    主要职责是处理业务逻辑,也就是应用程序的核心功能和规则,这里就是我们的业务类、接口等。

+

Go-kit的demo

接下来我们将给出一个简单的demo(对输入的字符串大写转换和字符串个数计数的功能)来对Go-kit的基本架构的实现和功能展示:

Service层

首先这个层会给出业务的逻辑实现,核心功能和规则

@@ -5240,10 +5241,56 @@ JSON 和 HTTP 协议。

这部分会给出不同的endpoint接口的类型定义,使用不同的type定义request和response的json格式类型,用于后续的变量的选择命名

package endpoints

import (
"context"
"github.com/go-kit/kit/endpoint"
"go-kit-test/services"
)

//这个地方借助go-kit来实现endpoint的内容
// uppercaseRequest 和 uppercaseResponse 用于 Uppercase 端点
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}

定义总的Endpoints接口,type Endpoints这个地方将会用于后续的对象的创建,func MakeEndpoints函数将被其他的函数进行调用用于创建内部的端点对象,其中在创建的过程中会调用以下的函数来分别创建两个功能的端口类型

-
type Endpoints struct {
UppercaseEndpoint endpoint.Endpoint
CountEndpoint endpoint.Endpoint
}

// MakeEndpoints 创建并返回所有服务端点
func MakeEndpoints(svc services.StringService) Endpoints {
return Endpoints{
UppercaseEndpoint: MakeUppercaseEndpoint(svc),
CountEndpoint: MakeCountEndpoint(svc),
}
}

// MakeUppercaseEndpoint 创建 Uppercase 端点
func MakeUppercaseEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
result, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{result, err.Error()}, nil
}
return uppercaseResponse{result, ""}, nil
}
}

// MakeCountEndpoint 创建 Count 端点
func MakeCountEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
result := svc.Count(req.S)
return countResponse{result}, nil
}
}

-
    -
  • -
+
type Endpoints struct {
UppercaseEndpoint endpoint.Endpoint
CountEndpoint endpoint.Endpoint
}

// MakeEndpoints 创建并返回所有服务端点
func MakeEndpoints(svc services.StringService) Endpoints {
return Endpoints{
UppercaseEndpoint: MakeUppercaseEndpoint(svc),
CountEndpoint: MakeCountEndpoint(svc),
}
}

// MakeUppercaseEndpoint 创建 Uppercase 端点
func MakeUppercaseEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
result, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{result, err.Error()}, nil
}
return uppercaseResponse{result, ""}, nil
}
}

// MakeCountEndpoint 创建 Count 端点
func MakeCountEndpoint(svc services.StringService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
result := svc.Count(req.S)
return countResponse{result}, nil
}
}
+

Transport层

+

主体的实现框架,分别给出了两个不同服务接口的responserequest的数据类型这部分给出json格式

+

http.NewServeMux()返回一个新的http.ServeMux,这是一个用于处理HTTP请求的请求轮询器(request +router)。接下来,为/uppercase和/count路径分别配置了新的httptransport.NewServer服务

+
type uppercaseRequest struct {
S string `json:"s"`
}

type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"`
}

// countRequest 和 countResponse 用于 Count 端点
type countRequest struct {
S string `json:"s"`
}

type countResponse struct {
V int `json:"v"`
}
// MakeHTTPHandler 创建 HTTP 处理程序
func MakeHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
options := []httptransport.ServerOption{
httptransport.ServerErrorEncoder(errorEncoder),
}
//http.NewServeMux()返回一个新的http.ServeMux,这是一个用于处理HTTP请求的请求轮询器(request router)。
//接下来,为/uppercase和/count路径分别配置了httptransport.NewServer:
m := http.NewServeMux()
//httptransport.NewServer是一个函数,它接受几个参数来创建一个新的HTTP服务器端点:
m.Handle("/uppercase", httptransport.NewServer(
endpoints.UppercaseEndpoint,
decodeUppercaseRequest,
encodeResponse,
options...,
))
m.Handle("/count", httptransport.NewServer(
endpoints.CountEndpoint,
decodeCountRequest,
encodeResponse,
options...,
))

return m
}
+

注意在定义endpoint的时候,要对request编码,对response解码

+

具体的解码和编码的过程如下:

+
func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request uppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}

// decodeCountRequest 解码 HTTP 请求并创建 Count 请求结构
func decodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request countRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}

// encodeResponse 将响应编码为 JSON 并写入 HTTP 响应
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
+

Main主层

+

这一层是最外层的调用层:go run main.go,这一层的逻辑实现主要是:

+
    +
  • 创建一个service服务接口对象
  • +
  • 将接口对象作为参数传入并生成endpoint相应的端点
  • +
  • httpHandler := transports.MakeHTTPHandler(eps)这一步是产生http的根据提供的Endpoint配置来创建一个HTTP处理程序,这个处理程序负责处理来自客户端的HTTP请求,并将响应返回给客户端
  • +
  • 对于任何来到根路径("/")的请求,都应该由httpHandler来处理。httpHandler是在之前的步骤中创建的HTTP处理程序,它知道如何处理HTTP请求并生成响应。这意味着当你访问服务器的根URL(例如,http://localhost:8080/)时,httpHandler中定义的处理逻辑将会被执行
  • +
  • 其中端口8080可以根据自己的需求进行指定
  • +
+
package main

import (
"go-kit-test/endpoints"
"go-kit-test/services"
"go-kit-test/transports"
"net/http"
"os"
)

func main() {
svc := services.SStringService{} //定义一个对象svc
eps := endpoints.MakeEndpoints(svc) //接收svc作为输入,创建endpoint端点
httpHandler := transports.MakeHTTPHandler(eps)

http.Handle("/", httpHandler)
port := ":8080"
if p := os.Getenv("PORT"); p != "" {
port = ":" + p
}

println("Service listening on port" + port)
http.ListenAndServe(port, nil)
}
+

Go-kit+Gin架构

+

Go-kit是一个微服务工具集,它提供了服务发现、负载均衡、请求追踪、日志记录和监控等功能,帮助开发者构建健壮、可维护、可测试的分布式系统。

+

Gin是一个轻量级的Go +Web框架,它提供了一个优雅的API和中间件支持,使得编写Web应用程序变得更加快速和简单

+

将两者进行结合:Gin负责处理HTTP请求和响应,提供路由和中间件功能,而go-kit则可以处理服务间的通信,提供服务发现、负载均衡等分布式系统功能。go-kit和Gin的结合使用,可以使得Go +Web应用的开发更加高效和模块化,有助于构建高性能、可伸缩且易于维护的分布式系统。

+

ApiService实现

+

我们需要利用gin对web端的应用程序进行实现,因此在这个架构之下我们设计的框架为:

+

Gin+Gokit架构图结构

+

其中services、endpoints、transports的功能和原来的go-kit基本一样,而handler主要处理的是gin的关于web端内容的控制,下面给出具体的实现

+

Service层

+
package services
type IUserService interface {
GetName(userId int) string
}

type UserService struct {
}

func (s UserService) GetName(userId int) string {
if userId == 101 {
return "calvin"
}
return "guest"
}
+

这个地方给出了具体的业务的实现接口功能

+

Endpoint层

+

在实现端口的过程中一般都需要对相关的type类型进行定义和对应的json格式的描述,函数GetUserEndPoint返回一个endpoint.Endpoint的类型,这个函数用于后续的调用产生endpoint

+
package endpoints

import (
"ApiService/services"
"context"
"github.com/go-kit/kit/endpoint"
)
type UserRequest struct {
Uid int `json:"uid"`
}

type UserResponse struct {
Result string `json:"result"`
}
func GetUserEndPoint(userService services.IUserService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(UserRequest)
result := userService.GetName(r.Uid)
return UserResponse{Result: result}, nil
}
}

+

Transport层

+

主要做的事情就是对requestresponse的解码和编码过程,因为通过对request的解码才能转换成能识别的json格式,才能进行业务端的使用,而后面的编码是为了能够进入web

+
package transports
import (
"ApiService/endpoints"
"context"
"errors"
httptransport "github.com/go-kit/kit/transport/http"
"net/http"
"strconv"
)
// 请求解码函数
func DecodeUserRequest(ctx context.Context, r *http.Request) (interface{}, error) {
// 限定参数来源,我们直接从url的params中获取用户id
// 请求格式类似于:http://127.0.0.1?uid=101
if r.URL.Query().Get("uid") != "" {
uid, _ := strconv.Atoi(r.URL.Query().Get("uid")) //strconv.Atoi(...)将字符串转化为整数
return endpoints.UserRequest{Uid: uid}, nil
}
return nil, errors.New("参数错误")
}

// 响应编码函数
func EncodeUserResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
// 将返回体body置为json格式
return httptransport.EncodeJSONResponse(context.Background(), w, response)
}
+

Handle层

+

这一层主要的作用就是利用gin来对web的实现,传递的参数分别是

+

handler := httptransport.NewServer(endpoint, transports.DecodeUserRequest, transports.EncodeUserResponse)

+
package handler

import (
. "ApiService/endpoints"
. "ApiService/services"
"ApiService/transports"
"github.com/gin-gonic/gin"
httptransport "github.com/go-kit/kit/transport/http"
)
// 创建 Gin 路由
func MakeGinHandler(svc IUserService) *gin.Engine {
//初始化一个Gin引擎,并配置了一些中间件
r := gin.New()
r.Use(gin.Logger()) //用于记录每个请求的详细信息,例如请求方法、URL、执行时间等
r.Use(gin.Recovery()) //在程序发生 panic 时恢复运行,并返回一个500的HTTP状态码

// 创建 Go kit 的 endpoint
endpoint := GetUserEndPoint(svc)

// 创建 HTTP 传输层处理程序
handler := httptransport.NewServer(endpoint, transports.DecodeUserRequest, transports.EncodeUserResponse)
r.GET("/hello", gin.WrapH(handler))
return r
}

+

Main层

+

这一层的实现是通过以下三个步骤实现的:

+
    +
  • 创建go -kit服务
  • +
  • 创建gin路由并绑定服务
  • +
  • 启动gin服务器
  • +
+
package main
import (
. "ApiService/handler"
. "ApiService/services"
"log"
)
func main() {
// 创建 Go kit 服务
userSvc := UserService{}
// 创建 Gin 路由并绑定服务
r := MakeGinHandler(userSvc)
// 启动 Gin 服务器
if err := r.Run(":8080"); err != nil {
log.Fatal(err)
}
}
/*
说明,这个demo运行后,浏览器输入 http://127.0.0.1:8080/hello?uid=1999 即可测试,还可以输入下面的内容进行测试:
http://127.0.0.1:8080/hello
http://127.0.0.1:8080
*/
]]>
后端开发 diff --git "a/tags/\345\220\216\347\253\257\345\274\200\345\217\221/index.html" "b/tags/\345\220\216\347\253\257\345\274\200\345\217\221/index.html" index faeb157..8697475 100644 --- "a/tags/\345\220\216\347\253\257\345\274\200\345\217\221/index.html" +++ "b/tags/\345\220\216\347\253\257\345\274\200\345\217\221/index.html" @@ -220,7 +220,7 @@ -
【基础工具】Docker使用
+
【基础工具】Docker基础功能