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

news2025/1/20 21:27:04

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/996886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataGridView绑定数据更新

1、创建数据类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace DataGridViewTest {internal class UserData{public string Name { get; set; }public int Weight { get; set; }public int …

“内存炸弹”DDOS拒绝服务攻击

Windows平台演示 最早的内存炸弹是 zip 炸弹,也称为死亡 zip,它是一种恶意计算机文件,旨在使读取该文件的程序崩溃或瘫痪。zip 炸弹不会劫持程序的操作,而是利用解压缩压缩文件所需的时间、磁盘空间或内存。 zip 炸弹的一个示例…

ConnectionError: Error connecting to Visdom server

pip install visdom python -m visdom.server点击网站即可访问

Modelsim仿真问题解疑三:LM_LICENSE_FILE与Vivado命名冲突

现象: modelsim和Vivado同一时间只能使用一个,另一个会报license相关的错误 原因: modelsim和Vivado的环境变量名称都为LM_LICENSE_FILE,值配置为其中一个时会导致另一个值被覆盖 解决: 对LM_LICENSE_FILE同时配置modelsim和v…

win10环境安装使用docker-maxwell

目的:maxwell可以监控mysql数据变化,并同步到kafka、mq或tcp等。 maxwell和canal区别: maxwell更轻量,canal把表结构也输出了 docker bootstrap可导出历史数据,canal不能 环境 :win10,mysql5…

反编译小程序 SyntaxError: Unexpected token ‘}‘ 异常处理

反编译小程序出现异常: SyntaxError: Unexpected token ‘}’ 网上很多都说使用最新版本的反编译 wxappUnpacker-master 包可以进行解析,但是大神已经停止了更新wxappUnpacker-master 包; 查找了网上大部分的wxappUnpacker-master 包&#…

查看mysql数据库的charset和collation

SELECT * FROM information_schema.SCHEMATA WHERE schema_name test_data; 发现: chaset是utf8mb4,collation是utf8mb4_generic_ci 可笑的是我导入sql脚本,要把脚本中所有的utf8mb4改为utf8,将utf8mb4_generic_ci为utf8_unico…

有哪些适合初学者的编程语言?

C语言 那为什么我还要教你C语言呢?因为我想要让你成为一个更好、更强大的程序员。如果你要变得更好,C语言是一个极佳的选择,其原因有二。首先,C语言缺乏任何现代的安全功能,这意味着你必须更为警惕,时刻了…

日志平台搭建第二章:Linux使用docker安装elasticsearch-head

一、elasticsearch-head的安装启动 #下载镜像 docker pull alivv/elasticsearch-head #启动 docker run -d --name eshead -p 9100:9100 alivv/elasticsearch-head 查看日志 docker logs -f eshead 出现如下证明启动成功 浏览器访问9100端口,出现以下页面也说明…

End-to-end 3D Human Pose Estimation with Transformer

基于Transformer的端到端三维人体姿态估计 摘要 基于Transformer的架构已经成为自然语言处理中的常见选择,并且现在正在计算机视觉任务中实现SOTA性能,例如图像分类,对象检测。然而,卷积方法在3D人体姿态估计的许多方法中仍然保…

vue学习之基本用法

1. 前期准备 安装vs code IDE&#xff0c;vs code 安装 插件 open in brower新建 vue-learning 文件夹vs code IDE打开文件夹 2. 基本用法 创建demo1.html文件,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

Converting Phase Noise to Random Jitter(Cycle-to-Cycle)

借用Phase Noise to Random Jitter(Period)的转换过程推导了Cycle to Cycle random Jitter&#xff0c;一般展频时钟调制,用来评估相邻周期的随机抖动。

AMD锐龙R5600GVEGA7 GPU环境搭建

AMD的GPU驱动很早就合入LINUX开源主线了,非常适合对GPU分析和学习,所以组装了一台搭配AMD锐龙R5 5600G CPU主机,配有VEGA7核显。不过,经过测试,由于是2021年的产品,所以需要安装较新的LINUX发行版,至少是UBUNTU20.04之后的,主机环境简单记录如下: 配置参数: 基础评分…

C语言之指针进阶篇(2)

目录 函数指针 函数名和&函数名 函数指针的定义 函数指针的使用 函数指针陷阱 代码1 代码2 注意 函数指针数组定义 函数指针数组的使用 指向函数指针数组的指针 书写 终于军训圆满结束了&#xff0c;首先回顾一下指针进阶篇&#xff08;1&#xff09;主要是…

C语言实现三字棋

实现以下&#xff1a; 1游戏不退出&#xff0c;继续玩下一把&#xff08;循环&#xff09; 2应用多文件的形式完成 test.c. --测试游戏 game.c -游戏函数的实现 game.h -游戏函数的声明 (2)游戏再走的过程中要进行数据的存储&#xff0c;可以使用3*3的二维数组 char bor…

【送书活动】揭秘分布式文件系统大规模元数据管理机制——以Alluxio文件系统为例

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

Modelsim仿真问题解疑二:ERROR: [USF-ModelSim-70]

现象&#xff1a;在Vivado中已配置modelsim为仿真工具后&#xff0c;运行仿真&#xff0c;报错USF-ModelSim-70和ERROR: [Vivado 12-4473] 详细报错内容如下 ERROR: [USF-ModelSim-70] compile step failed with error(s) while executing C:/Users/ZYP_PC/Desktop/verilog_t…

多线程与高并发——并发编程(7)

文章目录 七、JUC并发工具1 CountDownLatch应用&源码分析1.1 CountDownLatch介绍1.2 CountDownLatch应用1.3 CountDownLatch源码分析1.3.1 有参构造1.3.2 await 方法1.3.3 countDown方法2 CyclicBarrier应用&源码分析2.1 CyclicBarrier介绍2.2 CyclicBarrier应用2.3 Cy…

python DVWA文件上传POC练习

首先&#xff0c;构造POC我们首先要明白漏洞利用的流程&#xff0c;然后要知道请求包的格式&#xff0c;然后才能针对性的POC 这里先选择低难度的文件上传&#xff0c;低难度的是没有任何过滤可以直接上传的&#xff0c;先上传一个php一句话木马&#xff0c;使用burpsuite抓包 …

go channel实践与源码探索(初始化、发送消息、接收消息、关闭)

文章目录 概要一、并发编程1.1、Actor模型1.2、CSP模型 二、Go Channel实践三、源码分析3.1、初始化3.2、发送消息3.3、接收消息3.4、关闭通道 总结 概要 通道&#xff08;Channel&#xff09;是Go语言提供的协程之间通信与同步的方式。我们知道在并发编程&#xff08;多进程、…