首页 > 其他分享 >Go-kit框架学习记录

Go-kit框架学习记录

时间:2024-02-25 10:33:28浏览次数:28  
标签:endpoint http name 框架 request kit go Go

2、go-kit三层结构

go-kit和MVC一样也有三层结构endpoint,service, transport,通过这三层结构来实现,接收一个请求,然后返回一个结果。

1.Transport

Transport处于该微服务的最上层,主要负责于HTTP, gRPC,thrift等相关的逻辑,负责解析请求,并且调用endpoint来处理请求

2.Endpoint

endpoint属于客户端和服务端的转接器,他定义了request和response的格式,上层给Transport调用来处理请求,下层链接Service将Service所返回的结果转换成request需要的格式

3.Service

这里就是我们的业务类、接口等相关信息存放

3、go-kit实例

// 项目结构

-| Server

----| server.go

-| EndPoint

----| endpoint.go

-| Transport

----| Transport.go

  • main.go

3.1、Service

首先我们先写Server层业务类

package service

import "fmt"

//用于定义业务方法的接口
type IHelloService interface {
	Hello(name string) string
}

//用于实现上面定义的接口
type HelloService struct {
	//根据业务需求填充结构体
}

//实现上方定义的业务方法
func (h HelloService) Hello(name string) string {
	return fmt.Sprintf("Hello:%s", name)
}

3.2、EndPoint

endpoint的作用最简单的,对于一个从上层Transport传入的request,我们返回一个response,签名如下:

type EndPoint func(request) response

具体代码实现

package endpoint

import (
	"context"
	"github.com/go-kit/kit/endpoint"
	"github.com/mwqnice/go-kit-demo/service"
)
// Hello 业务使用的请求和响应格式
//HelloRequest 请求格式
type HelloRequest struct {
	Name string `json:"name"`
}

//HelloResponse响应格式
type HelloResponse struct {
	Reply string `json:"reply"`
}

//创建构造函数hello方法的业务处理
// MakeHelloServiceEndPorint 创建关于业务的构造函数
// 传入 Service/HelloService.go 定义的相关业务接口
// 返回 go-kit/endpoint.Endpoint (实际上就是一个函数签名)
func MakeHelloServiceEndPorint(s service.IHelloService) endpoint.Endpoint {
	// 这里使用闭包,可以在这里做一些中间件业务的处理
	return func(ctx context.Context, request interface{}) (response interface{}, err error){
		// request 是在对应请求来时传入的参数(这里的request 实际上是等下我们要将的Transport中一个decode函数中处理获得的参数)
		// 这里进行以下断言
		r, ok := request.(HelloRequest)
		if !ok {
			return HelloResponse{}, nil
		}
		// 这里实际上就是调用我们在Service/HelloService.go中定义的业务逻辑
		// 我们拿到了 Request.Name 那么我们就可以调用我们的业务 service.IHelloService 中的方法来处理这个数据并返回
		// 具体的业务逻辑具体定义....
		return HelloResponse{Reply: s.Hello(r.Name)}, nil
		// response 这里返回的response 可以返回任意的 不过根据规范是要返回我们刚才定义好的返回对象
	}
}

3.3、Transport

package transport

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/mwqnice/go-kit-demo/endpoint"
	"net/http"
)
// Transport/transport.go 主要负责HTTP、gRpc、thrift等相关的逻辑

// 这里有两个关键函数
// DecodeRequest & EncodeResponse 函数签名是固定的哟
// func DecodeRequest(c context.Context, request *http.Request) (interface{}, error)
// func EncodeResponse(c context.Context, w http.ResponseWriter, response interface{}) error

// HelloDecodeRequest 解码 后封装至 EndPoint中定义的 Request格式中
func HelloDecodeRequest(c context.Context, request *http.Request) (interface{}, error) {
	// 这里主要就是通过 request 拿到对应的参数构造成在 EndPoint中定义的 Request结构体即可

	name := request.URL.Query().Get("name")
	if name == "" {
		return nil, errors.New("参数name不能为空")
	}
	return endpoint.HelloRequest{Name: name}, nil
}

//HelloEncodeResponse通过响应封装成Endpoint中定义的Response结构体
func HelloEncodeResponse(c context.Context, w http.ResponseWriter, response interface{}) error {
	//这里将Response返回成有效的json格式给http

	//设置请求头信息
	w.Header().Set("Content-Type", "application/json;charset=utf-8")

	//使用内置json包转换
	return json.NewEncoder(w).Encode(response)
}

3.4、服务启动

package main

import (
	httpTransport "github.com/go-kit/kit/transport/http"
	"github.com/mwqnice/go-kit-demo/endpoint"
	"github.com/mwqnice/go-kit-demo/service"
	"github.com/mwqnice/go-kit-demo/transport"
	"net/http"
)

// 服务发布
func main()  {
	//1.创建我们最开始定义的service/HelloService.go
	s := service.HelloService{}

	//2.在用endpoint/HelloEndpoint创建业务服务
	hello := endpoint.MakeHelloServiceEndPorint(s)

	//3.使用kit创建handler
	//传入业务服务 以及 定义的加密解密方法
	helloServer := httpTransport.NewServer(hello, transport.HelloDecodeRequest,transport.HelloEncodeResponse)

	// 4.使用http包启动服务
	go http.ListenAndServe("0.0.0.0:8000", helloServer)
	select {}
}

最重要的其实就在组装这个handler的地方serverHandler := httpTransport.NewServer(endPoint, transport.HelloDecodeRequest, transport.HelloEncodeResponse)这里我们将HelloDecodeRequest和endPoint一起传入进去,在NewServer内部会有自动将结果传入request的方法,然后打开ListenAndServer函数就可以开始监听8000窗口了默认是127.0.0.1:8000

标签:endpoint,http,name,框架,request,kit,go,Go
From: https://www.cnblogs.com/muzinan110/p/18032123

相关文章

  • 关于虚拟化的框架梳理
    需求1:人们需要在同一套硬件上,运行一台或多台虚拟机,同时这些虚拟机可能是不同的操作系统。解决方案1:通过抽象线程,虚拟内存和逻辑卷,可以解决一套硬件支持多台虚拟机的问题。如果这些虚拟机分属不同的操作系统,也可以通过构建一个通用的虚拟机管理层,捕获并翻译虚拟机操作系统为底......
  • golang 系统调用与阻塞处理
    所有在UNIX系统上运行的程序最终都会通过C系统调用来和内核打交道。用其他语言编写程序进行系统调用,方法不外乎两个:一是自己封装,二是依赖glibc、或者其他的运行库。Go语言选择了前者,把系统调用都封装到了syscall包。封装时也同样得通过汇编实现。当M一旦进入系统调用后,会......
  • go堆内存分配
    mutator申请内存是以应用视角来看问题,我需要的是某一个struct,某一个slice对应的内存,这与从操作系统中获取内存的接口(比如mmap)之间还有一个鸿沟。需要由allocator进行映射与转换,将以“块”来看待的内存与以“对象”来看待的内存进行映射。在现代CPU上,我们还要考虑内存分配......
  • golang io优化
    如果想兼顾开发效率,又能保证高并发,协程就是最好的选择。它可以在保持异步化运行机制的同时,用同步方式写代码(goroutine-per-connection),这在实现高并发的同时,缩短了开发周期,是高性能服务未来的发展方向。CPU和IO设备是不同的设备,能并行运行。合理调度程序,充分利用硬件,就能跑出......
  • golang性能优化
    性能优化流程理清待优化代码的常用逻辑与场景根据实际场景编写压测用例使用pprof或者火焰图等工具取得数据找到热点代码重点优化Profilingpprof是用于可视化和分析性能分析数据的工具。为什么pprof可以帮助我们分析Go程序性能呢?因为它可以采集程序运行时数据:比如说协程栈,这样服......
  • 2024-02-24:用go语言,给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1, 同时还有一
    2024-02-24:用go语言,给你一个n个点的带权无向连通图,节点编号为0到n-1,同时还有一个数组edges,其中edges[i]=[fromi,toi,weighti],表示在fromi和toi节点之间有一条带权无向边,最小生成树(MST)是给定图中边的一个子集,它连接了所有节点且没有环,而且这些边的权值和最......
  • 痛定思痛,好好做人,从头过一遍PyTorch框架(一)(1.深度学习简介、2.预备知识)
    现在是2024年2月24日,13:59,从研一就开始断断续续说要过一遍框架,到现在博一下学期,还一直拖着呢,拖延症太可怕啦,决定好好做人,不拖了,就从现在开始,好好过一遍,呜呜呜呜呜呜呜呜,(罪该万死)。看的教程是:《动手学深度学习》(PyTorch版),是把李沐老师的《动手学深度学习》原书中的MXNet实现改......
  • go经典知识及总结
    1.无论sync.Mutex还是其衍生品都会提示不能复制,但是能够编译运行加锁后复制变量,会将锁的状态也复制,所以mu1其实是已经加锁状态,再加锁会死锁.所以此题的答案是fatalerror;typeMyMutexstruct{countintsync.Mutex}funcmain(){varmuMyMutexmu.L......
  • Golang Swag 注释
    常用的注释用法:@title:指定API的标题。@description:对API的简要描述。@version:API的版本号。@termsOfService:API的使用条款。@contact:API的联系方式,例如邮箱。@license:API的许可证信息。@host:API的主机名和端口号。@BasePath:API的基本路径。@S......
  • Go语言精进之路读书笔记第34条——了解channel的妙用
    c:=make(chanint)//创建一个无缓冲(unbuffered)的int类型的channelc:=make(chanint,5)//创建一个带缓冲的int类型的channelc<-x//向channelc中发送一个值<-c//从channelc中接收一个值x=<-c//从channelc接收一个值并......