秋来冬风的博客

优化http2 Web Server 之Go标准库和运行时可修改的源代码

目录

这是我的高吞吐http2服务器优化经验分享系列 第三篇博客。

背景

我在优化我的用go语言写的http2服务器时,尝试修改go的源代码对标准库和运行时进行优化,本文分享我发现的一些源代码中可以修改的部分。

对应版本是go1.26开发分支。

net/http包

除非有特别声明,要修改的代码在h2_bundle.go

加大缓冲区

调整 http2bufWriterPoolBufferSize 常量,原来是4kb。

调整DATA帧大小

调整 http2handlerChunkWriteSize 常量,原来是4kb。

减少时间字符串分配

http2responseWriterState.writeChunk方法,每次调用会动态分成堆分配的RFC1123时间字符串,可以自行优化为1秒获取1次。

避免响应码字符串堆分配

http2httpCodeString函数,除了200和404,其他响应码每次都会堆分配一个字符串,可以优化掉。

调整Content-Type猜测规则

要修改的代码在sniff.go

sniffSignatures变量,它定义了Content-Type猜测规则,可以针对性调整来优化。

runtime包

调大每P最大栈缓存

在malloc.go的_StackCacheSize常量,定义每P对特定大小(例如2kb,4kb)的栈,每种最多缓存多少,默认32kb。

调整GC目标占用CPU率

在mgcpacer.go的gcGoalUtilization常量,定义GC目标占用百分之多少CPU,默认0.25(25%)。

注意这个值如果设置的太低,可能导致反效果,严重超出目标。例如设置为1%,可能时间使用是10+%。

辅助标记(assist marking)相关

辅助标记是指:如果 GC 正在进行并发标记阶段,并且发现 GC 的进度落后于内存分配的速度,用户 goroutine 在进行分配时,协助 GC 执行一部分标记工作。

在mgcpacer.go的gcCreditSlack常量是本地累计的扫描工作信用(scan work credit)阈值,超过该值后会更新全局的gcController.heapScanWork和bgScanCredit。

  • 值越小,辅助比例(assist ratio)越精确,辅助线程更可能成功 “窃取” 后台信用。
  • 值越大,可减少内存竞争(因全局更新频率降低)。

gcAssistTimeSlack是P(处理器)上累计的 “辅助标记时间”(mutator assist time)阈值,超过后会更新全局的gcController.assistTime。控制辅助时间统计的更新频率。

调整最小堆大小

在mgcpacer.go的defaultHeapMinimum常量定义当 GOGC=100时,堆内存的最小阈值。默认4Mb,避免小堆频繁 GC。

调整最小栈大小

在stack.go中的 stackMin 常量,控制创建goroutine时的初始栈大小,也是最小栈大小。

Tags:
Categories: