深度分析 Golang sync.Pool 底层原理
sync.Pool 是 Golang 内置的对象池技术,可用于缓存临时对象,以缓解因频繁建立临时对象带来的性能损耗以及对 GC 带来的压力。
含有 #源码分析 标签的所有内容。
sync.Pool 是 Golang 内置的对象池技术,可用于缓存临时对象,以缓解因频繁建立临时对象带来的性能损耗以及对 GC 带来的压力。
一致性 Hash 常用于缓解分布式缓存系统扩缩容节点时造成的缓存大量失效的问题。一致性 Hash 与其说是一种 Hash 算法,其实更像是一种负载均衡策略。
sync.Cond 条件变量是 Golang 标准库 sync 包中的一个常用类。sync.Cond 往往被用在一个或一组 goroutine 等待某个条件成立后唤醒这样的场景,例如常见的生产者消费者场景。
sync.WaitGroup 是 Golang 中常用的并发措施,我们可以用它来等待一批 Goroutine 结束。
本文将基于 Golang 源码对 Timer 的底层实现进行深度剖析。主要包含以下内容:
time.Sleep 的实现细节,Golang 如何实现 Goroutine 的休眠。注:本文基于 go-1.13 源码进行分析,而在 go 的 1.14 版本中,关于定时器的实现略有一些改变,以后会再专门写一篇文章进行分析。
channel 是 Golang 中一个非常重要的特性,也是 Golang CSP 并发模型的一个重要体现。简单来说就是,goroutine 之间可以通过 channel 进行通信。
channel 在 Golang 如此重要,在代码中使用频率非常高,以至于不得不好奇其内部实现。本文将基于 go 1.13 的源码,分析 channel 的内部实现原理。
定时器是网络框架中非常重要的组成部分,往往可以利用定时器做一些超时事件的判断或者定时清理任务等。
Redis 作为一个单线程高性能的内存缓存 Server 而被人熟知。作为一个典型的 Reactor 式网络应用,Redis 能够达到如此高的性能,必然要依靠足够可靠的事件循环库。
Redis 内置了一个高性能事件循环器,叫做 AE。其定义和实现可以在 ae*.h/cpp 这些文件中找到。
AE 本身就是 Redis 的一部分,所以整体设计原则就是够用就行。也正因为这个背景,AE 的代码才可以简短干净,非常适合阅读和学习。
本文将基于 Redis 5.0.6 的源码分析下其事件循环器 (AE) 的实现原理。
同时本人也提供了一个 Redis 注释版,用以辅助理解 Redis 的源码。
Filebeat 是使用 Golang 实现的轻量型日志采集器,也是 Elasticsearch stack 里面的一员。本质上是一个 agent,可以安装在各个节点上,根据配置读取对应位置的日志,并上报到相应的地方去。
Filebeat 的可靠性很强,可以保证日志 At least once 的上报,同时也考虑了日志搜集中的各类问题,例如日志断点续读、文件名更改、日志 Truncated 等。
Filebeat 并不依赖于 Elasticsearch,可以单独存在。我们可以单独使用 Filebeat 进行日志的上报和搜集。filebeat 内置了常用的 Output 组件, 例如 kafka、Elasticsearch、redis 等。出于调试考虑,也可以输出到 console 和 file。我们可以利用现有的 Output 组件,将日志进行上报。
当然,我们也可以自定义 Output 组件,让 Filebeat 将日志转发到我们想要的地方。
filebeat 其实是 elastic/beats 的一员,除了 filebeat 外,还有 HeartBeat、PacketBeat。这些 beat 的实现都是基于 libbeat 框架。
uber 在 Github 上开源了一套用于服务限流的 go 语言库 ratelimit, 该组件基于 Leaky Bucket(漏桶) 实现。
我在之前写过一篇 《Golang 限流器 time/rate 实现剖析》,分析了 Golang 标准库中基于 Token Bucket 实现限流组件的 time/rate 原理,同时也讲了限流的一些背景。
相比于 TokenBucket 中,只要桶内还有剩余令牌,调用方就可以一直消费的策略。Leaky Bucket 相对来说更加严格,调用方只能严格按照预定的间隔顺序进行消费调用。(虽然 uber-go 对这个限制也做了一些优化,具体可以看下文详解)
还是老规矩,在正式讲其实现之前,我们先看下 ratelimit 的使用方法。
限流器是微服务中必不缺少的一环,可以起到保护下游服务,防止服务过载等作用。上一篇文章 《Golang 限流器 time/rate 使用介绍》 简单介绍了 time/rate 的使用方法,本文则着重分析下其实现原理。建议在正式阅读本文之前,先阅读下上一篇文章。
上一篇文章讲到,time/rate 是基于 Token Bucket(令牌桶) 算法实现的限流。本文将会基于源码,深入剖析下 Golang 是如何实现 Token Bucket 的。其代码也非常简洁,去除注释后,也就 200 行左右的代码量。
同时,我也提供了 time/rate 注释版,辅助大家理解该组件的实现。
libco 是微信后台开发和使用的协程库,同时也是极少数的直接将 C/C++ 协程运用到如此大规模的生产环境中的案例。
在 《云风 coroutine 协程库源码分析》 中,介绍了有栈协程的实现原理。相比云风的 coroutine,libco 在性能上号称可以调度千万级协程。 从使用上来说,libco 不仅提供了一套类 pthread 的协程通信机制,同时可以零改造地将三方库的阻塞 IO 调用进行协程化。
本文将从源码角度着重分析 libco 的高效之道。
在正式阅读本文之前,如果对有栈协程的实现原理不是特别了解,建议提前阅读 《云风 coroutine 协程库源码分析》。
同时,我也提供了 libco 注释版,用以辅助理解 libco 的源码
随着 Golang 的兴起,协程尤其是有栈协程 (stackful coroutine) 越来越受到程序员的关注。协程几乎成了程序员的一套必备技能。
云风实现了一套 C 语言的协程库,整体背景可以参考其 博客。
这个协程库非常轻量级,一共也才 200 多行代码,使用上更贴近于 lua 的写法(众所周知,云风是知名的 lua 粉)。整体基于 ucontext 和共享栈模型实现了有栈协程,代码质量毋庸置疑,本文将详细剖析该协程库的实现原理。
同时,我也提供了 coroutine 注释版,辅助大家理解 coroutine 的代码。
muduo是 陈硕 大神个人开发的 C++ 的 TCP 网络编程库。muduo 基于 Reactor 模式实现,Reactor 模式也是目前大多数 Linux 端高性能网络编程框架和网络应用所选择的主要架构,例如 Redis 和 Java 的 Netty 库等。
陈硕的《Linux 多线程服务器端编程》一书对 muduo 整个架构进行了非常详尽的介绍和分析,可以说是学习 muduo 源码和设计理念最好的资料了。
而本文则主要是从源码角度辅助理解整个 muduo 的实现,同时也姑且算是对 muduo 的一个小小的补充。
同时我也提供了一个 muduo 注释版,用以辅助理解 muduo 的源码。
BloomFilter(布隆过滤器)是一种可以高效地判断元素是否在某个集合中的算法。
在很多日常场景中,都大量存在着布隆过滤器的应用。例如:检查单词是否拼写正确、网络爬虫的 URL 去重、黑名单检验,微博中昵称不能重复的检测等。