谁拔了我的网线?

Go编写网络程序非常的高效,而且有是那么的简单,寥寥几行代码就可以写一个ECHO协议的程序,所以现在很多网络程序都采用Go语言开发。但是网络状况是复杂的,会有很多的异常状况,如果不能很好和正确的处理这些异常状况,会导致网络程序出现莫名其妙的现象,或者hang住。

本文尝试探讨几种网络异常的情况,研究在这些情况下客户端和服务端的的行为,包括连接断掉的检测能力、half-close情况下两端的读写能力、丢包的情况等等。

这是我首次采用微课的方式分享技术内容,本文是视频内容的整理版。 本来是想录制一个10分钟的视频,一不小心录制了半小时。

阅读全文

妙到颠毫: bigcache优化技巧

最近看到 yoko 翻译的一篇文章: [译] Go开源项目BigCache如何加速并发访问以及避免高额的GC开销, 翻译自 How BigCache avoids expensive GC cycles and speeds up concurrent access in Go, 应该是 Douglas Makey Mendez Molero 在阅读了 bigcache 的作者写的 bigcache设计文章Writing a very fast cache service with millions of entries in Go做的一些调研和总结。

我在刚读取这篇文档的时候,顺着连接把相关的文章都找出来细细读了一遍,结合bigcache的代码,仔细学习了相关的优化设计,感觉设计非常的精妙,所以特意根据自己的理解又总结了一篇。

bigcache的精妙的设计也吸引了fasthttp的作者Aliaksandr Valialkin,他在bigcache的基础上,结合自己的公司的使用场景,进一步的做了相应的优化, 也开源了这个项目fastcache, 本文在最后也做了介绍。

阅读全文

[译]Golang template 小抄

这是 Curtis Vermeeren 做的 Go模板技术的小抄,这是我非常喜欢的形式,可以以一个简短的总结把相关的技术介绍出来。 大家可以看我以前翻译的Go文件操作大全,也是统一风格的文章。我翻译了这篇文章,补充了遗漏的知识点。

Go标准库提供了几个package可以产生输出结果,而text/template 提供了基于模板输出文本内容的功能。html/template则是产生 安全的HTML格式的输出。这两个包使用相同的接口,但是我下面的例子主要面向HTML应用。

阅读全文

Hi, 使用多年的go pprof检查内存泄漏的方法居然是错的?!

最近在做一个 Redis 的 Proxy 的项目,其中利用Redis 6.0 新加的 tracking 功能实现客户端缓存的功能,可以为某些特定的redis使用场景提高吞吐和延迟。

当然,cache的实现也是有代价的。首先,cache的大小不能无限制的大,否则总有一点会把内存撑爆的;其次,cache的淘汰算法有多种方式,LRU、LFU等等,具体可以参考Cache replacement policies,不同的场景下各种淘汰算法的效果是不一样的;第三,对于大并发情况实现cache是有代价的,因为并发情况下对cache的访问需要加锁,而加锁就意味着有性能的损失。

我在实现这个cache的过程中稍微偷了一下懒, 想尽量的减少锁的scope,结果导致内存泄漏的问题。本来cache占用的最大内存我设置为10GB, 结果过了个周末发现程序已经占用了80GB的内存了。

当然本文不是要介绍这个项目的内存泄漏原因,而是介绍一下Go pprof工具查找内存泄漏的一个不太常用的方法。

阅读全文

读写 Redis RESP3 协议以及Redis 6.0客户端缓存

在四月份的一篇翻译的文章中,我介绍了读写Redis RESP version 2的协议的Go 语言的实现,你可以使用它采用底层的方式读写5.0以及以下版本的Redis。Redis 6.0还在开发之中年底或者明年初就要发布了。Redis 6.0支持多线程I/O,还有客户端缓存。

客户端缓存是未来Redis最重要的特性。如果我们需要快速存储和快速缓存,那么我们就需要在客户端存储数据的子集。这是为了提供小延迟、大规模数据的想法的自然延伸。很多公司都采用了在客户端缓存数据以避免每次都请求redis,但是本地缓存和redis服务器数据之间有延迟,很难保证数据的一致性。Ben Malec在Redis Conf 2018上做了一个关于客户端缓存的演讲,给了Salvatore Sanfilippo以灵感,Salvatore Sanfilippo决定在Redis 6.0中支持客户端缓存的功能。但是为了支持这个功能,使用当前的redis协议很难实现,所以他设计了下一代的Redis协议: RESP3

阅读全文

Go并发设计模式之 Half-Sync/Half-Async

半同步/半异步(half-sync/half-async)的模式集成了同步IO模式和异步IO模型,既简化了并发系统的开发,又兼顾了效率。在这个并发设计模式的实现中,高级的任务使用同步IO模型,使开发者可以无太多的心智负担在并发编程中,底层的任务使用异步IO模型,这就提高了并发的效率。这个设计模式广泛的应用在操作系统的实现中,如UNIX、Mach,Windows等。

阅读全文