G0第28章:Go语言微服务框架

Go-kit

Go kit教程04——中间件和日志

本文主要介绍了Go kit 中的中间件,并以日志中间件为例演示了如何设计和实现中间件。
上一篇中,我们对go kit搭建的项目进行了目录结构拆分

中间件

在 go kit 中,它对中间件的定义是一个接收Endpoint并返回Endpoint的函数,具体定义如下。

type Middleware func(Endpoint) Endpoint

在中间件接收Endpoint参数和返回Endpoint之间,你可以做任何事。

例如,下面的示例演示了如何实现一个基础的日志中间件。

import (
	"context"

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

func loggingMiddleware(logger log.Logger) endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (interface{}, error) {
			logger.Log("msg", "calling endpoint")
			defer logger.Log("msg", "called endpoint")
			return next(ctx, request)
		}
	}
}

transport层日志

这里想要记录transport层的日志信息,将先前的NewHTTPServer按如下方式进行改造即可。

func NewHTTPServer(svc AddService, logger log.Logger) http.Handler {
	// sum
	sum := makeSumEndpoint(svc)
	// 使用loggingMiddleware为sum端点加上日志
	sum = loggingMiddleware(log.With(logger, "method", "sum"))(sum)
	sumHandler := httptransport.NewServer(
		sum,
		decodeSumRequest,
		encodeResponse,
	)

	// concat
	concat := makeConcatEndpoint(svc)
	// 使用loggingMiddleware为concat端点加上日志
	concat = loggingMiddleware(log.With(logger, "method", "concat"))(concat)
	concatHandler := httptransport.NewServer(
		concat,
		decodeConcatRequest,
		encodeResponse,
	)

	r := gin.Default()
	r.POST("/sum", gin.WrapH(sumHandler))
	r.POST("/concat", gin.WrapH(concatHandler))
	return r
}

请添加图片描述

应用层日志

第一种 引用全局的logger

请添加图片描述

第二种 结构体注入 (缺点:后期更改日志工具不方便)

请添加图片描述
请添加图片描述

官方方法

如果要在应用程序层面添加日志,例如需要记录下详细的请求参数,那么就需要为我们的服务来定义中间件。

由于我们的 AddService 服务定义为接口类型,所以我们只需要定义一个新类型(把原先的实现和一个额外的logger包装起来)并实现这个接口即可。

先定义类型。

type logMiddleware struct {
	logger log.Logger
	next   AddService
}

再实现接口。

func (mw logMiddleware) Sum(ctx context.Context, a, b int) (res int, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "sum",
			"a", a,
			"b", b,
			"output", res,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	res, err = mw.next.Sum(ctx, a, b)
	return
}

func (mw logMiddleware) Concat(ctx context.Context, a, b string) (res string, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "sum",
			"a", a,
			"b", b,
			"output", res,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	res, err = mw.next.Concat(ctx, a, b)
	return
}

// NewLogMiddleware 创建一个带日志的add service
func NewLogMiddleware(logger log.Logger, svc AddService) AddService {
	return &logMiddleware{
		logger: logger,
		next:   svc,
	}
}

请添加图片描述

集成zap日志库

上述示例默认使用的是github.com/go-kit/log,你也可以使用其他的日志库,例如下面示例中使用社区常用的zap日志库。
请添加图片描述

ratelimit限流中间件

import "golang.org/x/time/rate"

var (
	ErrRateLimit = errors.New("request rate limit")
)

// rateMiddleware 限流中间件
func rateMiddleware(limit *rate.Limiter) endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (interface{}, error) {
			if !limit.Allow() {
				return nil, ErrRateLimit
			}
			return next(ctx, request)
		}
	}
}

使用限流中间件。

import "golang.org/x/time/rate"

sum = rateMiddleware(rate.NewLimiter(1, 1))(sum)

Go-Zero

连接mysql

请添加图片描述

mysql -uroot -p -hlocalhost

请添加图片描述

请添加图片描述

请添加图片描述

使用 goctl model mysql … 自动生成model 可选择在最后加上 -c 来生成带缓存的代码

请添加图片描述

请添加图片描述

加不加缓存对于逻辑层是无感知的,但是需要添加上配置以连接缓存

日志 logx

在开发阶段需要查看一些信息的,可以使用debug级别或者Info级别日志
对于私密的信息不允许落盘和网络传输的使用debug级别日志
而对于需要探究哪出错的日志,使用Error级别

使用docker启动mysql、redis、etcd、grpcui

mysql

docker run --name mysql -e MYSQL_ROOT_PASSWORD=123 -d mysql:latest

redis

docker pull redis

docker run --name reids -e redis_password=123 -d redis:latest

etcd

docker run -it --name Etcd bitnami/etcd

grpcui

go install github.com/fullstorydev/grpcui/cmd/grpcui@latest

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值