Go微服务精讲:Go-Zero全流程实战即时通讯(13章全+电子书)

2024-04-29 13:25:14 浏览数 (1)

学习地址自己还原 /s/1p2gVcBMq87ko35yoWzyblQ 提取码: fajt

一、P2C负载均衡算法 & EWMA

在go-zero中默认使用的是P2C的负载均衡算法。

算法的原理:即随机从所有可用节点中选择两个节点,然后计算这两个节点的负载情况,选择负载较低的一个节点来服务本次请求。

为了避免某些节点一直得不到选择导致不平衡,会在超过一定的时间后强制选择一次。

使用EWMA指数移动加权平均,记录每个节点的平均延迟,该算法相对于算数平均来说对于突然的网络抖动没有那么敏感,从而可以让算法更加均衡。

g0-zer0 ,是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验。go-zero 包含极简的 AP!定义和生成工具 goctl,可以根据定义的 api文件一键生成 Go, i0s, Android,Kotlin, Dart,Typescript,javascript 代码并可直接运行。

使用 go-zero 的好处:

轻松获得支撑千万日活服务的稳定性

内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码

微服务治理中间件可无缝集成到其它现有框架使用

极简的 API 描述,一键生成各端代码

自动校验客户端请求参数合法性

大量微服务治理和并发工具包

二、源码阅读

2.1EWMA记录节点的平均延迟

buildDoneFunc返回函数会复制给 PickResult.Done, RPC完成调用后会执行PickResult.Done方法。

/*

// Done is called when the RPC is completed.

rpc 完成时将会执行该函数

*/

func (p *p2cPicker) buildDoneFunc(c *subConn) func(info balancer.DoneInfo) {

//start 记录subConn被选中的时间

start := int64(timex.Now())

return func(info balancer.DoneInfo) {

//......

now := timex.Now()

last := atomic.SwapInt64(&c.last, int64(now))

//本次请求 和 上次请求 请求间隔

td := int64(now) - last

if td < 0 {

td = 0

}

//e^x 距离最后一次请求 时间约久,权重约低

w := math.Exp(float64(-td) / float64(decayTime))

//本次请求花费的时间

lag := int64(now) - start

if lag < 0 {

lag = 0

}

//

olag := atomic.LoadUint64(&c.lag)

if olag == 0 {

w = 0

}

atomic.StoreUint64(&c.lag, uint64(float64(olag)*w float64(lag)*(1-w)))

success := initSuccess

if info.Err != nil && !codes.Acceptable(info.Err) {

success = 0

}

osucc := atomic.LoadUint64(&c.success)

atomic.StoreUint64(&c.success, uint64(float64(osucc)*w float64(success)*(1-w)))

//每一分钟记录一次请求日志

//......

}

go-zero 框架设计思考

对于微服务框架的设计,我们期望保障微服务稳定性的同时,也要特别注重研发效率。所以设计之初,我们就有如下一些准则:

保持简单

高可用

高并发

易扩展

弹性设计,面向故障编程

尽可能对业务开发友好,封装复杂度

尽可能约束做一件事只有一种方式

使用go-zero框架的时候,发现在API请求过程中如果出现错误,接口会直接返回http400错误。这对前端或者其它服务端很不友好,他们需要获得详细错误信息,并且不返回http错误。同时,对于有错误的请求和成功的请求,接口返回的数据不一致。

总的来说,我们需要解决以下三个问题:

处理框架自带参数解析失败后产生的error(需自己处理)

处理逻辑层处理失败后产生的error(官方已处理)

修改模板,统一接口返回值(官方已处理)

后两个官方已处理,并加入官方学习文档,可自行查阅:

逻辑层错误官方解决方案:官方错误处理方法

统一接口返回值官方解决方案:官方统一请求返回方法

go

0 人点赞