102

Golang 介绍及踩坑系列之三

 6 years ago
source link: https://zhuanlan.zhihu.com/p/31395716?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Golang 介绍及踩坑系列之三

NextBillion.AI 软工

聪明的你,用golang写后端服务,各种使用channel和goroutine,把java要用线程池干的事儿用携程都搞掂了。服务线下运行一切正常,压测,单元测,联调统统通过。你露出得意的微笑,一键发布到生产环境,欣喜的发现服务崩溃了。

为什么服务会崩溃呢?

channel死锁

死锁是golang里边最常见的一类问题,我们从java和c/c++转过来的gopher在编程时候会特别注意mutex,semaphore,atomic等等的使用,反复检查会不会造成死锁。但是我们有可能会忽略掉另一个死锁大元凶:channel。

channel简直就是用来死锁的。

unbuffered channel读和写都是blocking的,也就是说读一个没人写的channel和写一个没人读的channel都会造成死锁。死锁状态下的goroutine会永远等待这个channel operation返回。这么做的goroutine多了,直接就会造成内存泄漏,服务器崩溃。

buffered channel不会吗?

也会的。buffered channel写满了之后再写就会死给你看。空的channel没人的情况下去读也死给你看。

怎么避免呢?

select {
case <-ch:
    // a read from ch has occurred
case <-time.After(1 * time.Second):
    // moving on after 1 second
}

这在官方的 effective go里边就有介绍。

第三方调用

我们往往不能天真的认为我们调用的上游服务不会挂,我们也不能淳朴的认为我们的网络环境永远是可靠的。往往一个小波动就会使得我们好多goroutine临时的卡在第三方api调用上。比如正常状况下我们期待所有goroutine20ms都会完成。但是突然网络抖动,或者第三方服务稳定性出了一点小问题,我们的goroutine都要2秒钟才会完成。

可能有人会觉得,不就是慢了一点吗,有什么大关系。

同志们,关系非常大。本来goroutine 20ms就退出的情况下,我们可能同时也就是几千个goroutine。如果goroutine生命周期变长,我们就会瞬间攒下来100*几千个goroutine,如果不加以限制的话,我们的服务就会瞬间崩溃。

所以别人的问题,可能会导致我们自己服务的失败。

使用circuit breaker。

我们想这样保护我们的服务:

首先设定SLA (service level agreement)

  1. 平均响应时间
  2. max qps

我们需要monitor第三方服务的调用出错率。当出错率高于某个阈值(超时也是一种错误),我们需要暂时对服务调用这个操作直接报错,这样调用的goroutine就可以迅速的退出。

我们还需要不断的尝试,看看调用状况是不是变回良好可用的状态,如果是,我们就得恢复正常的调用机制。并且重新开始计算出错率。

这个pattern其实就是大家常说的熔断器(circuit breaker)

熔断器的一个golang实现:afex/hystrix-go

怎么观测我们的服务承受的压力?

普罗米修斯:Prometheus

数据狗:Modern monitoring & analytics

NewRelic: Digital Performance Monitoring and Management | New Relic

如何debug到底goroutine卡在什么地方?

pprof : https://golang.org/pkg/net/http/pprof/

这篇文章粗浅无比的谈了一下golang服务如何防止,检测,排查goroutine过多引起的在线故障。意在抛砖引玉。聪明的你,我们一起学习,一起深入讨论。

希望我们露出得意微笑部署golang服务的时候,可以更加自信,更加成竹在胸。




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK