5.7. go-kit是个啥,我想试一试

未匹配的标注

无水印图片找不到嘞,文中图片来自知乎自己以前的账号,现在是开源到。

何为go-kit

Go kit is a programming toolkit for building microservices (or elegant monoliths) in Go. We solve common problems in distributed systems and application architecture so you can focus on delivering business value.

gokit是一个用于在Go中构建微服务(或优雅的整体)的编程工具包,解决了分布式系统和应用程序体系结构中的常见问题,以便开发者能够专注于业务交付。


go-kit主要分为三层结构:Transport层,Endpoint层,Service层。

  • Transport 负责与传输协议HTTP、GRPC等相关的逻辑
  • Endpoint 负责request/response格式的转换,以及公用拦截器相关的逻辑
  • Service 业务逻辑。

另外,go-kit提供log日志,metric计数器,tracing请求跟踪,circuitbreaker服务熔断,rate-limiter限流器等模块。简单说,go-kit提供了微服务架构常见的基础模块,可以让开发者省去很多时间。

开始

了解了还不够,show code。我们先定义下service,不如就做个简单的计算器,仅仅做演示,有加减功能即可,不整太复杂了。

package service

// 接口定义
type CalculateService interface {
    Add(a, b int) int
    Reduce(a, b int) int
    Multi(a, b int) int
}

type calculateService struct{}

func NewService() *calculateService {
    return &calculateService{}
}

func (s *calculateService) Add(a, b int) int {
    return a + b
}

func (s *calculateService) Reduce(a, b int) int {
    return a - b
}

func (s *calculateService) Multi(a, b int) int {
    return a * b
}

注意:Go 接口是一组方法的集合,可以理解为抽象的类型。它提供了一种非侵入式的接口。任何类型,只要实现了该接口中方法集,那么就属于这个类型。(这是go中非常常用的特性,切记)

endpoint格式化请求,调用service服务,并格式化输出

package endpoint

import (
    "context"
    "demo6/service"
    "fmt"

    "github.com/go-kit/kit/endpoint"
)

type Request struct {
    A int `json:"a" form:"a"`
    B int `json:"b" form:"b"`
}

type Res struct {
    Res int   `json:"res"`
    Err error `json:"err"`
}

func MakeAddEndpoint(s service.CalculateService) endpoint.Endpoint {
    return func(_ context.Context, request interface{}) (interface{}, error) {
        req := request.(Request)
        return Res{Res: s.Add(req.A, req.B)}, nil
    }
}

func MakeReduceEndpoint(s service.CalculateService) endpoint.Endpoint {
    return func(_ context.Context, request interface{}) (interface{}, error) {
        req := request.(Request)
        return Res{Res: s.Reduce(req.A, req.B)}, nil
    }
}

func MakeMultiEndpoint(s service.CalculateService) endpoint.Endpoint {
    return func(_ context.Context, request interface{}) (interface{}, error) {
        req := request.(Request)
        return Res{Res: s.Multi(req.A, req.B)}, nil
    }
}

接下来,定义transport定义请求方式(这里我们使用json):

package transport

import (
    "context"
    "demo6/endpoint"
    "encoding/json"
    "errors"
    "net/http"
)

func DecodeRequest(_ context.Context, r *http.Request) (interface{}, error) {
    var req endpoint.Request
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        return nil, errors.New("params error")
    }
    return req, nil
}

func EncodeResponse(_ context.Context, w http.ResponseWriter, res interface{}) error {
    return json.NewEncoder(w).Encode(res)
}

最后我们将它们endpoint和transport粘合起来,跑起来go~

package main

import (
    "demo6/endpoint"
    "demo6/service"
    "demo6/transport"
    "net/http"

    httpTransport "github.com/go-kit/kit/transport/http"
)

func main() {
    s := service.NewService()

    add := httpTransport.NewServer(
        endpoint.MakeAddEndpoint(s),
        transport.DecodeRequest,
        transport.EncodeResponse,
    )

    reduce := httpTransport.NewServer(
        endpoint.MakeReduceEndpoint(s),
        transport.DecodeRequest,
        transport.EncodeResponse,
    )

    multi := httpTransport.NewServer(
        endpoint.MakeMultiEndpoint(s),
        transport.DecodeRequest,
        transport.EncodeResponse,
    )
    http.Handle("/add", add)
    http.Handle("/reduce", reduce)
    http.Handle("/multi", multi)
    http.ListenAndServe(":9009", nil)
}

运行起来:

成功运行!

详细代码进github,有用不妨star一下


留一个问题,对于json格式错误的请求,返回的不是json,如何改造,让接口返回json呢?


关注和赞赏都是对笔者最大的支持
关注和赞赏都是对笔者最大的支持

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~