diff --git a/SUMMARY.md b/SUMMARY.md index 5f88546..c94b1e5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -50,7 +50,6 @@ * [5.7. Layout大型web项目分层](ch5-web/ch5-07-layout-of-web-project.md) * [5.8. interface 和 table-driven 开发](ch5-web/ch5-08-interface-and-web.md) * [5.9. 灰度发布和 A/B test](ch5-web/ch5-09-gated-launch.md) - * [5.10. 服务发现](ch5-web/ch5-10-service-discovery.md) * [5.11. Load-balance负载均衡](ch5-web/ch5-11-load-balance.md) * [第六章 分布式系统](ch6-cloud/readme.md) * [6.1. 云上地鼠(TODO)](ch6-cloud/ch6-01-cloud.md) diff --git a/ch6-cloud/ch6-10-delay-job.md b/ch6-cloud/ch6-10-delay-job.md index 92f33db..ba9be04 100644 --- a/ch6-cloud/ch6-10-delay-job.md +++ b/ch6-cloud/ch6-10-delay-job.md @@ -10,3 +10,42 @@ 2. 实现一个支持定时发送消息的消息队列。 两种思路进而衍生出了一些不同的系统,但其本质是差不多的。都是需要实现一个定时器。定时器英文为 timer,在单机的场景下其实并不少见,例如我们在和网络库打交道的时候经常会写 `SetReadDeadline`,这实际上就是在本地创建了一个定时器,在到达指定的时间后,我们会收到定时器的通知,告诉我们时间已到。这时候如果读取还没有完成的话,就可以认为发生了网络问题,从而中断读取。 + +timer 的实现在工业界已经是有解的问题了。常见的就是时间堆和时间轮。 + +## timer 实现 + +### 时间堆 + +Go 自身的 timer 就是用时间堆来实现的。在最近的版本中,还加了一些优化,我们先不说优化,时间堆本身是一个四叉的小顶堆: + +``` + +-----+ + | | + | 0 | + +-----+ + | + | + | + v + +-----+-----+-----+-----+ + | | | | | + | 3 | 2 | 2 | 10 | + +-----+-----+-----+-----+ + | | | | + | | | | + +----------+ | | | | + +----------------+ 4*i+1 +-----------------------+ | | +-----------------------------+ + | +----------+ +-------------------+ +---+ | + | | | | + | | | | + v | | v ++-----+-----+-----+-----+ | | +-----+-----+-----+-----+ +| | | | | v v | | | | | +| 20 | 4 | 5 | 13 | +-----+-----+-----+-----+ +-----+-----+-----+-----+ | 99 | 13 | 11 | 12 | ++-----+-----+-----+-----+ | | | | | | | | | | +-----+-----+-----+-----+ + | 12 | 14 | 15 | 16 | | 3 | 10 | 3 | 3 | + +-----+-----+-----+-----+ +-----+-----+-----+-----+ +``` + +### 时间轮