基于gRPC的注册发现与负载均衡的原理和实战
熔断原理与实现Golang版
go-zero 如何应对海量定时/延迟任务?
go-zero 如何应对海量定时/延迟任务?
[TOC]
一个系统中存在着大量的调度任务,同时调度任务存在时间的滞后性,而大量的调度任务如果每一个都使用自己的调度器来管理任务的生命周期的话,浪费cpu的资源而且很低效。
本文来介绍 go-zero
中 延迟操作,它可能让开发者调度多个任务时,只需关注具体的业务执行函数和执行时间「立即或者延迟」。而 延迟操作,通常可以采用两个方案:
Timer
:定时器维护一个优先队列,到时间点执行,然后把需要执行的 task 存储在 map 中collection
中的timingWheel
,维护一个存放任务组的数组,每一个槽都维护一个存储task的双向链表。开始执行时,计时器每隔指定时间执行一个槽里面的tasks。
方案2把维护task从 优先队列 O(nlog(n))
降到 双向链表 O(1)
,而执行task也只要轮询一个时间点的tasks O(N)
,不需要像优先队列,放入和删除元素 O(nlog(n))
。
微服务过载保护原理与实战
通过MapReduce降低服务响应时间
通过MapReduce降低服务响应时间
[TOC]
在微服务中开发中,api网关扮演对外提供restful api的角色,而api的数据往往会依赖其他服务,复杂的api更是会依赖多个甚至数十个服务。虽然单个被依赖服务的耗时一般都比较低,但如果多个服务串行依赖的话那么整个api的耗时将会大大增加。
那么通过什么手段来优化呢?我们首先想到的是通过并发来的方式来处理依赖,这样就能降低整个依赖的耗时,Go基础库中为我们提供了 WaitGroup 工具用来进行并发控制,但实际业务场景中多个依赖如果有一个出错我们期望能立即返回而不是等所有依赖都执行完再返回结果,而且WaitGroup中对变量的赋值往往需要加锁,每个依赖函数都需要添加Add和Done对于新手来说比较容易出错
基于以上的背景,go-zero框架中为我们提供了并发处理工具MapReduce,该工具开箱即用,不需要做什么初始化,我们通过下图看下使用MapReduce和没使用的耗时对比: