【GO-Micro】micro 重试机制

Go-micro的依赖启动报错解决办法 Go-micro的依赖启动报错解决办法 错误:q.s.Close undefined (type quic.Session has no field or method Close) GOROOT=D:\work\go1.14\go #gosetup GOPATH=D:\work\GoLand\code\Go\src;D:\work\GoLand\code\Go #gosetup D:\work\go1.14\go\bin\go.exe build -o C:\Users\xuekan\AppData\Lo 阅读详情

github完整代码地址 https://github.com/Allenxuxu/microservices

在分布式系统中,经常会有服务出现故障,所以良好的重试机制可以大大的提高系统的可用性。本文主要分析micro的客户端重试机制,以及实例演示。

micro 重试实现

micro框架提供方法设置客户端重试的次数。

Client.Init(
	client.Retries(3),
)

当client请求失败时,客户端会根据selector的策略选择下一个节点重试请求。这样当一个服务实例故障时,客户端可以自动调用另一个实例。

我们来看看micro 客户端内部重试的实现:

go-micro\client\rpc_client.go


func (r *rpcClient) Call(ctx context.Context, request Request, response interface{}, opts ...CallOption) error {
...
    //客户端call 调用函数, 在下面的循环中调用
	call := func(i int) error {
		// call backoff first. Someone may want an initial start delay
		t, err := callOpts.Backoff(ctx, request, i)
		if err != nil {
			return errors.InternalServerError("go.micro.client", "backoff error: %v", err.Error())
		}

		// only sleep if greater than 0
		if t.Seconds() > 0 {
			time.Sleep(t)
		}

		// 根据selector策略 选出 下一个节点
		node, err := next()
		if err != nil && err == selector.ErrNotFound {
			return errors.NotFound("go.micro.client", "service %s: %v", request.Service(), err.Error())
		} else if err != nil {
			return errors.InternalServerError("go.micro.client", "error getting next %s node: %v", request.Service(), err.Error())
		}

		// 客户端调用
		err = rcall(ctx, node, request, response, callOpts)
		r.opts.Selector.Mark(request.Service(), node, err)
		return err
	}

	ch := make(chan error, callOpts.Retries+1)
	var gerr error
    //根据设定的**Retries**(重试次数)循环调用 call,如果执行成功,调用超时或者设置的**Retry**函数执行出错则直接退出,不继续重试
	for i := 0; i <= callOpts.Retries; i++ {
		go func(i int) {
			ch <- call(i)
		}(i)

		select {
		case <-ctx.Done(): //超时
			return errors.Timeout("go.micro.client", fmt.Sprintf("call timeout: %v", ctx.Err()))
		case err := <-ch:
			// if the call succeeded lets bail early
			if err == nil {  //调用成功
				return nil
			}

			retry, rerr := callOpts.Retry(ctx, request, i, err)
			if rerr != nil {
				return rerr
			}

			if !retry {
				return err
			}

			gerr = err
		}
	}

	return gerr
}

micro将选举下一个节点,RPC调用封装到一个匿名函数中,然后根据设定的重试次数循环调用。如果调用成功或者超时则直接返回,不继续重试。其中,当callOpts里设定的Retry函数执行失败,即第一个返回值为false,或者第二个返回值为err不会nil时,也会退出循环直接返回。

我们来看下Retry是什么:

type CallOptions struct {
	Retry RetryFunc
}

client的CallOptions中定义了Retry,我们跳转到RetryFunc

go-micro\client\retry.go

// note that returning either false or a non-nil error will result in the call not being retried
type RetryFunc func(ctx context.Context, req Request, retryCount int, err error) (bool, error)

// RetryAlways always retry on error
func RetryAlways(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
	return true, nil
}

// RetryOnError retries a request on a 500 or timeout error
func RetryOnError(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
	if err == nil {
		return false, nil
	}

	e := errors.Parse(err.Error())
	if e == nil {
		return false, nil
	}

	switch e.Code {
	// retry on timeout or internal server error
	case 408, 500:
		return true, nil
	default:
		return false, nil
	}
}

从中我们可以发现,作者预实现了两个Retry函数:RetryAlways、RetryOnError。
RetryAlways直接返回true, nil,即不退出重试。
RetryOnError只有当e.Code(上一次RPC调用结果)为408或者500时才会返回true, nil,继续重试。
micro的默认Retry为RetryOnError,但是我们可以自定义并设置,下面的实验中将会演示。

	DefaultRetry = RetryOnError
	// DefaultRetries is the default number of times a request is tried
	DefaultRetries = 1
	// DefaultRequestTimeout is the default request timeout
	DefaultRequestTimeout = time.Second * 5

实验

当客户端请求另一个服务时,如果被请求的服务突然挂了,而此时客户端依旧会去请求,重试时客户端会请求另一个实例(有一定几率还会请求同一个实例,因为默认的负载均衡策略是哈希随机)。

我们修改api/user下的服务,在main函数中设置客户端重试。

sClient := hystrixplugin.NewClientWrapper()(service.Options().Service.Client())
	sClient.Init(
		client.WrapCall(ocplugin.NewCallWrapper(t)),
		client.Retries(3),
		client.Retry(func(ctx context.Context, req client.Request, retryCount int, err error) (bool, error) {
			log.Log(req.Method(), retryCount, " client retry")
			return true, nil
		}),
	)

然后,我们依次启动 micro网关,user API服务,hello SRV服务(启动两个实例)。

cd micro && make run
cd api/user && make run
cd srv/hello && make run
cd srv/hello && make run

我们通过kill -9 杀死其中一个hello服务,然后通过postman请求 GET 172.0.0.1:8080/user/test。

[GIN] 2019/05/14 - 14:52:20 | 200 |    1.253576ms |       127.0.0.1 | GET      /user/test
2019/05/14 14:52:48 Received Say.Anything API request
2019/05/14 14:52:48 0x19a1680 0 retry func
2019/05/14 14:52:48 msg:"Hello xuxu"
[GIN] 2019/05/14 - 14:52:48 | 200 |   13.821193ms |       127.0.0.1 | GET      /user/test

通过usr API服务的输出,我们可以看到重试一次后,客户端成功请求了另一个实例。

github完整代码地址 https://github.com/Allenxuxu/microservices

「go-micro」学习笔记1——Micro 与 Go-Micro 新建服务 # 新建一个 helloworld 的服务 micro new helloworld 服务的启动与运行 # 在本地运行该服务并确保其正常工作. # 启动服务器 micro server # 设置为本地环境 micro env set local # 启动你的服务 micro run helloworld 服务状态 # 检查状态 micro status # 检查是否已注册 micro services # 检查日志 micro logs helloworld 结束服务 micro k 阅读详情

相关推荐

微服务框架go-micro探究

微服务框架go-micro探究一、简介二、主要功能三、处理请求流程四、架构设计1. client2. server3. broker4. codec5. registry6. selector7. transport五、应用实例1. server端2. client端 一、简介 go-micro是一个插件化的基础框架,基于此可以构建微服务。在架构之外,它默认实现了consul作为服务发现(2019年源码修改了默认使用mdns),通过http进行通信,通过protobuf和json进行编解码。 二、主要功能

qq_41928921的博客 758

快速实现 RPC 微服务:使用 go-micro 从零开始

大家好,我是木川本文将演示如何从 0 到 1 使用 go-micro 框架实现 RPC 微服务,包括服务端和客户端,客户端发送一个名字到服务端,服务端返回问候语。一、创建项目创建项目目录,使用 go mod 初始化mkdirgoexamples gomodinitgoexamples如果当前项目在 GOPATH 目录之外,记得设置goenv-wGO111MODULE=on目录结构如下...

木川的技术之路 487

手把手教你用树莓派蓝牙抓取小米温湿度计2代数据,接入HomeAssistant(附密钥获取避坑指南)

本文详细介绍了如何通过树莓派蓝牙抓取小米温湿度计2代数据并接入HomeAssistant的完整流程。重点解析了获取32位加密密钥的三种方法,包括使用Telink Flasher工具、米家APP抓包和开源工具ATC_MiThermometer,并提供了HomeAssistant集成配置和常见问题排查指南,帮助用户实现稳定可靠的温湿度监测。

一名菜鸟攻城师 779

go-micro v2安装 以及go语言使用案例+超时处理

安装go-micro go get github.com/micro/go-micro/v2@v2.6.0 安装工具集 go get github.com/micro/micro/v2 安装protobuf插件 go get -u github.com/golang/protobuf/{proto,protoc-gen-go} go get -u github.com/micro/protoc-gen-micro/v2

weixin_43406295的博客 1539

【探秘】二维异形件重叠移除算法:从度量到消除的实战解析

本文深入解析二维异形件重叠移除算法的核心技术与实战应用,涵盖重叠度量、零件扰动策略及消除方法。通过NFP(临界多边形)技术、空间分区加速等优化手段,有效解决异形件排版中的重叠问题,提升材料利用率和计算效率。适合制造业、CAD软件开发者及算法工程师参考。

weixin_28698059的博客 253

Quantum Espresso Hands-On实战训练(四)——PDOS计算与轨道分析

本文详细介绍了Quantum Espresso中PDOS计算与轨道分析的实战方法,重点解析了PDOS在材料电子结构研究中的核心价值,包括原子级分辨率、轨道级解析和自旋极化分析。通过具体案例和操作步骤,帮助读者掌握从输入文件准备到结果解读的全流程,并提供了高级分析技巧和疑难问题解决方案。

weixin_29211309的博客 504

micro api入门

上一节学习了go-micro的入门。 这一节我们来熟悉micro的工具集里的api用法。 micro api网关 Micro的api就是api网关 API参考了API网关模式为服务提供了一个单一的公共入口。基于服务发现,使得micro api可以提供具备http及动态路由的服务。 下载micro工具集 go install github.com/micro/micro 该命令会在GOPATH/bi...

一个不靠谱的程序员 5588

Replay音频转换时samplerate缺失的解决方案指南

Replay音频转换时提示"No module named 'samplerate' This error is lazily reported, having originally occured in File"的解决方案

weixin_47445543的博客 2134

Golang装饰器模式使用误区

go micro用装饰器模式封装的包装器可以额外增加很多修饰方法,但其执行逻辑是所有包装器全局执行,适用于日志、链路追踪等不影响最终结果的场景,对于影响最终结果的场景如重试机制则推荐在应用层执行。

2401_89221867的博客 85

Python批量注册脚本开发详细

开发一个Python批量注册脚本需要考虑多个方面,包括目标网站的注册流程、验证码处理、请求发送、数据存储等。以下是一个详细的开发流程和代码示例,用于实现基本的批量注册功能。

nsp202505的博客 3349

用Python和NumPy可视化理解波函数:从概率密度到薛定谔方程的可视化教程

本文通过Python和NumPy实现量子力学波函数的可视化,从概率密度到薛定谔方程的动态演化,帮助读者直观理解量子态的特性。教程涵盖无限深势阱、量子谐振子等模型,结合代码示例展示时间演化和期望值计算,为量子力学学习提供实用工具。

weixin_27303545的博客 227

Go 微服务架构Micro相关概念理解

Micro是一个微服务框架(或者说是工具集):提供了各类组件,解决微服务架构中的不同问题,服务监控、服务发现、熔断机制,负载均衡等等,自己一个个解决这些问题几乎不可能,这时候就需要借助go-micro这些组件了。提供了微服务的基础框架。是一种架构.(go-micro 是Micro 底层实现, 用于写服务的,而工具集是用来访问附服务的) 服务被拆分为几十个甚至上百个后如何进行管理呢?比如服务的伸...

weixin_30699831的博客 174

UNext:基于 MLP 的快速医学图像分割网络

有代码,可深入学习轻量级分割模型的论文切入点 UNet 及其最新扩展(如 TransUNet)近年来一直是领先的医学图像分割方法。然而,这些网络无法有效地用于应用中的快速图像分割,因为它们参数繁重、计算复杂且使用缓慢。为此,我们提出了 UNeXt,它是一种基于卷积多层感知器(MLP)的图像分割网络。我们以有效的方式设计了 UNeXt,其中包括早期卷积阶段和潜在阶段的 MLP 阶段。我们提出了一个标记化的 MLP 块,我们可以在其中有效地标记和投影卷积特征,并使用 MLP 来对表示进行建模。

Philo的博客 3942

go微服务框架go-micro深度学习(三) Registry服务的注册和发现

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34258838的博客 97

华为OD机考双机位C卷 - 信道分配(Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 信道分配

算法大师! 454

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

go-micro教程

1.micro介绍 { 1.micro简介 Micro由开源的库与工具组成,旨在辅助微服务开发。 go-micro - 基于Go语言的可插拔RPC微服务开发框架;包含服务发现、RPC客户/服务端、广播/订阅机制等等。 go-plugins - go-micro的插件有etcd、kubernetes、nats、rabbitmq、grpc等等。 micro - 微服务工具集包含传统的入口点(entry...

Salted fish in hand, I have the world. 2673

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

[GO]go-micro介绍

API 网关、CLI、Slack Bot、代理及Web UI。go-plugins - go-micro的插件有etcd、kubernetes、nats、rabbitmq、grpc等等。go-micro - 基于Go语言的可插拔RPC微服务开发框架;包含服务发现、RPC客户/服务端、广播/订阅机制等等。可插拔 - 可以选择从哪个源加载配置:文件、环境变量、consul。集成服务发布、RPC、分发/订阅机制、消息编码。Micro由开源的库与工具组成,旨在辅助微服务开发。Go Micro可以帮你编写微服务。..

红尘道,红尘练心 1499

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

go-micro

前言 由于go语言和go-micro框架迭代迅速,我在学习go-micro框架查询资料时,经常因为过时的资料遇到莫名其妙的错误。因此我决心根据自己的实践与摸索,编写一个适合go-micro V2版本切实可用的go-micro开发指南,重点记录开发的流程和各类问题的解决方案。希望这份笔记能够帮助以后的自己,和所有看到它的朋友实现以下目标: 顺利搭建一个当前版本下被反复验证可行的go-micro系统 通过一系列插件引入对go-micro框架全貌有大致理解 在笔记中快速检索到go-micro框架的各种搭建

hllyzms的博客 1033

[golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例

go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例

资深系统架构,深耕高并发研发与 AI 大模型工程化落地。技术栈以 Python (AI/NLP/RAG/Agent) 与 Golang (高并发架构) 为双核心,兼具 PHP 大型应用经验。专注算法落地、复杂系统设计及团队技术赋能 6967

go-micro V2 从零开始(一)使用micro工具自动生成项目

文章目录前言一、Go-Micro是什么?go-micro简介go-micro的主要功能go-micro通信流程二、使用步骤1.安装micro2.读入数据总结1. 什么是 前言 这是一系列GO语言微服务框架go-micro的学习笔记,主要记录我在go-micro学习摸索中遇到的问题。 由于微服务知识浩如烟海,每一个点展开都值得大书特书,这份笔记重实操轻理论重点记录的是操作的流程,和各类问题的解决方案。希望这份笔记能够帮助以后的自己,和所有看到它的朋友实现以下目标: 顺利搭建一个当前版本下被反复验证可行

hotcoffie的博客 4515

Go Micro:构建分布式系统的利器

Go Micro:构建分布式系统的利器 【免费下载链接】go-micro A Go microservices framework 项目地址: https://gitcode.com/gh_mirrors/go/go-micro ...

gitblog_00409的博客 1216

微服务框架Go-Micro集成Nacos实战之服务注册与发现

导读:本文主要介绍如何使用 Golang 生态中的微服务框架 Go-Micro(v2) 集成 Nacos 进行服务注册与发现。(Go-Micro 目前已经是 v3 版本,但由于某些原因项...

阿里巴巴中间件 2691

consul golang使用_go-micro+gin+consul微服务实战之使用http api请求

本文是基于上一篇【go-micro+gin+consul微服务实战之服务注册与发现】的,没看过的同学,请移步:https://www.jianshu.com/p/757dc1bb3930我们在使用微服务构建系统时,必然会用到http api,下面介绍下,在如何使用go-micro自带的http库构建http api 请求我们还使用上一篇【go-micro+gin+consul微服务实战之服务注册与...

weixin_39562606的博客 380

微服务_go-micro介绍

微服务_go-micro安装

huan 1060
上一篇: 【go-micro实践】健康检查
下一篇: GolangCI-Lint: 比gometalinter快5倍的Golang静态检查工具
惜朝_
博客等级 码龄10年 9粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值