 Go读书会第二期Go 读书会第二期 白明 《 Go 语言精进之路》作者 tonybai.com 博主 目 录 写书的历程 0 1 Go 语言精进之路导读 0 2 我是怎么读书的 0 3 写书的历程 第一部分 程序员的“小目标”与写书三要素 写书三要素 写书 <- 能力 +意愿 + 机会 过程 写书不易,写高质量的书更难 2018 年下 旬开始动笔 2020 年 11 月下旬 初稿交付 初稿交付 2021 年 12 月出版 《 Go 语言精进之路》导读 第二部分 整体写作思路 异曲同工 精进之路,思维先行 – part1 践行哲学,遵循惯例,认清本质,理解原理 - (part2- part10) 精进之路,思维先行 异曲同工 “ 语言决定思维方式” - 萨丕尔假说 “ 我的语言之局限,即我的世界之局限” - 路德维 希 · 维特根斯坦(语言哲学奠基人) “0 码力 | 26 页 | 4.55 MB | 1 年前3 Go读书会第二期Go 读书会第二期 白明 《 Go 语言精进之路》作者 tonybai.com 博主 目 录 写书的历程 0 1 Go 语言精进之路导读 0 2 我是怎么读书的 0 3 写书的历程 第一部分 程序员的“小目标”与写书三要素 写书三要素 写书 <- 能力 +意愿 + 机会 过程 写书不易,写高质量的书更难 2018 年下 旬开始动笔 2020 年 11 月下旬 初稿交付 初稿交付 2021 年 12 月出版 《 Go 语言精进之路》导读 第二部分 整体写作思路 异曲同工 精进之路,思维先行 – part1 践行哲学,遵循惯例,认清本质,理解原理 - (part2- part10) 精进之路,思维先行 异曲同工 “ 语言决定思维方式” - 萨丕尔假说 “ 我的语言之局限,即我的世界之局限” - 路德维 希 · 维特根斯坦(语言哲学奠基人) “0 码力 | 26 页 | 4.55 MB | 1 年前3
 2.游戏战中陪伴助手微服务架构设计与应用别再打架啦,我们装 备不佳,先去躲躲吧 战中陪伴助手介绍——和平精英最佳第五人 • 游戏战斗中指导 / 建议 • 闲聊、鼓励、攻略 • 取得战绩,赞赏一波 毫不留情! 三杀收下! 早期探索 第二部分 需求思考 • 我们的输入是什么? • 游戏对局事件 • Snapshot • Diffs • 玩家位置 • 安全区 • 航线 • …… • 掉血10点 • 开枪3发 • 敌人方位 技术选型: - 对比:Lua vs Go 二进制——开发灵活 vs 性能 - 思考:Go 脚本? - 最终方案: - Go 脚本开发 - 二进制发布 我全都要 方案 耗时(冒泡排序) 耗时(斐波那契) Lua 脚本 94766 ns/op 4957 ns/op Go 脚本 23250 ns/op 27208 ns/op Go 二进制 175 ns/op 173 ns/op 未知(未交接过) 1 天(几位开发参与过) 持续测试 无 有 性能和成本优化 第四部分 贵 - 部署:腾讯云 TKE(Tencent Kubernetes Engine);微服务 - 上线前压测: - 预估 CPU:20,000+ 核,其中推荐系统接近 18,000 - 现象:网络流量极大 - 原因:流量中包含对局完整历史(Token 历史、推荐历史、……) 服务(某灰度下) 峰值0 码力 | 47 页 | 11.10 MB | 1 年前3 2.游戏战中陪伴助手微服务架构设计与应用别再打架啦,我们装 备不佳,先去躲躲吧 战中陪伴助手介绍——和平精英最佳第五人 • 游戏战斗中指导 / 建议 • 闲聊、鼓励、攻略 • 取得战绩,赞赏一波 毫不留情! 三杀收下! 早期探索 第二部分 需求思考 • 我们的输入是什么? • 游戏对局事件 • Snapshot • Diffs • 玩家位置 • 安全区 • 航线 • …… • 掉血10点 • 开枪3发 • 敌人方位 技术选型: - 对比:Lua vs Go 二进制——开发灵活 vs 性能 - 思考:Go 脚本? - 最终方案: - Go 脚本开发 - 二进制发布 我全都要 方案 耗时(冒泡排序) 耗时(斐波那契) Lua 脚本 94766 ns/op 4957 ns/op Go 脚本 23250 ns/op 27208 ns/op Go 二进制 175 ns/op 173 ns/op 未知(未交接过) 1 天(几位开发参与过) 持续测试 无 有 性能和成本优化 第四部分 贵 - 部署:腾讯云 TKE(Tencent Kubernetes Engine);微服务 - 上线前压测: - 预估 CPU:20,000+ 核,其中推荐系统接近 18,000 - 现象:网络流量极大 - 原因:流量中包含对局完整历史(Token 历史、推荐历史、……) 服务(某灰度下) 峰值0 码力 | 47 页 | 11.10 MB | 1 年前3
 1.5 Go 语言构建高并发分布式系统实践线上单机最⾼高160w⻓长连接 (24核 E5-2630 @ 2.30GHz 64G内存 ) qps在2~5w(取决于协议版本,业务逻辑,接⼊入端⺴⽹网络状况) 测试环境,可以通过300w⻓长连接压测(⺴⽹网络,连接稳定,⽆无带宽限制,实际可以更⾼高 ,决定于⼲⼴广播时候业务内存开销的cpu消耗带来的⼼心跳或者业务延时能否接受) 以360消息推送系统为例 ⾼高并发、通信交互复杂 问题与瓶颈 2~3s的GC 瓶颈 散列在协程⾥里⾯面的io 问题与瓶颈 奔放的协程使⽤用 接⼝口响应速度 降低,重试 增多,压⼒力倍增 问题与瓶颈 2~3s的GC 瓶颈 散列在协程⾥里⾯面的io 问题与瓶颈 奔放的协程使⽤用 内存暴涨 问题与瓶颈 性能优化:数据集中处理 go语⾔言开发追求开销优化的极限,谨慎引⼊入其他语⾔言领域⾼高性能 服务的通⽤用⽅方案 关注:内存池、对象池使⽤用与代码可读性与整体效率的权衡 经验⼆二 性能优化 内存池 性能优化:通⽤用⽅方案 性能优化 对象池 性能优化:通⽤用⽅方案 如何应对的? go语⾔言在基础服务开发领域的优势?0 码力 | 39 页 | 5.23 MB | 1 年前3 1.5 Go 语言构建高并发分布式系统实践线上单机最⾼高160w⻓长连接 (24核 E5-2630 @ 2.30GHz 64G内存 ) qps在2~5w(取决于协议版本,业务逻辑,接⼊入端⺴⽹网络状况) 测试环境,可以通过300w⻓长连接压测(⺴⽹网络,连接稳定,⽆无带宽限制,实际可以更⾼高 ,决定于⼲⼴广播时候业务内存开销的cpu消耗带来的⼼心跳或者业务延时能否接受) 以360消息推送系统为例 ⾼高并发、通信交互复杂 问题与瓶颈 2~3s的GC 瓶颈 散列在协程⾥里⾯面的io 问题与瓶颈 奔放的协程使⽤用 接⼝口响应速度 降低,重试 增多,压⼒力倍增 问题与瓶颈 2~3s的GC 瓶颈 散列在协程⾥里⾯面的io 问题与瓶颈 奔放的协程使⽤用 内存暴涨 问题与瓶颈 性能优化:数据集中处理 go语⾔言开发追求开销优化的极限,谨慎引⼊入其他语⾔言领域⾼高性能 服务的通⽤用⽅方案 关注:内存池、对象池使⽤用与代码可读性与整体效率的权衡 经验⼆二 性能优化 内存池 性能优化:通⽤用⽅方案 性能优化 对象池 性能优化:通⽤用⽅方案 如何应对的? go语⾔言在基础服务开发领域的优势?0 码力 | 39 页 | 5.23 MB | 1 年前3
 IPC性能极致优化方案-RPAL落地实践异步线程唤醒: 关键在于如何最低限度降低线程唤醒的开销,非必要不通知事件。 2. 数据序列化/反序列化 需要做到跨进程的虚拟地址空间共享,通过传递指针来传递一切数据。 全进程地址空间共享与保护 第二部分 全进程地址空间共享与保护 模拟插件/动态链接库等方案的用户态上下文切换和虚拟地址访问,需要解决: 1. 虚拟地址冲突问题; 2. 页表隔离问题; 3. 内存安全性问题; 全进程地址空间共享与保护 rpal线程切换: 用户态进程切换 用户态进程切换 延迟进程切换 1.发生 Kernel Entry 时,sender 线程将 pt_regs(保存 Kernel 返回到用户态的 上下文信息)压入 sender 线程内核栈 用户态进程切换 延迟进程切换 2. 判断 fsbase 寄存器保存的地址是否 在 kernel current task 的 512GB 地址 空间内? > Kitex 框架进行 benchmark 测试,对比 uds 和 rpal 的性能差异: 注:以上仅测试包含序列化开销的性能对比,benchmark测试受影响因素较多,实际收益需结合业务场景。 性能压测 性能收益与业务展望 1. 字节跳动微服务合并部署场景下,部分服务通过接入 RPAL 整体取得了 1-5% 的 CPU 收益, 以及 RPC 链路 1-6ms 的 P99 延迟下降。 2. 将某项0 码力 | 39 页 | 2.98 MB | 1 年前3 IPC性能极致优化方案-RPAL落地实践异步线程唤醒: 关键在于如何最低限度降低线程唤醒的开销,非必要不通知事件。 2. 数据序列化/反序列化 需要做到跨进程的虚拟地址空间共享,通过传递指针来传递一切数据。 全进程地址空间共享与保护 第二部分 全进程地址空间共享与保护 模拟插件/动态链接库等方案的用户态上下文切换和虚拟地址访问,需要解决: 1. 虚拟地址冲突问题; 2. 页表隔离问题; 3. 内存安全性问题; 全进程地址空间共享与保护 rpal线程切换: 用户态进程切换 用户态进程切换 延迟进程切换 1.发生 Kernel Entry 时,sender 线程将 pt_regs(保存 Kernel 返回到用户态的 上下文信息)压入 sender 线程内核栈 用户态进程切换 延迟进程切换 2. 判断 fsbase 寄存器保存的地址是否 在 kernel current task 的 512GB 地址 空间内? > Kitex 框架进行 benchmark 测试,对比 uds 和 rpal 的性能差异: 注:以上仅测试包含序列化开销的性能对比,benchmark测试受影响因素较多,实际收益需结合业务场景。 性能压测 性能收益与业务展望 1. 字节跳动微服务合并部署场景下,部分服务通过接入 RPAL 整体取得了 1-5% 的 CPU 收益, 以及 RPC 链路 1-6ms 的 P99 延迟下降。 2. 将某项0 码力 | 39 页 | 2.98 MB | 1 年前3
 1.每秒百万数据点 Go 应用监控系统演进good? 04 总结与展望 05 监控架构概览 第一部分 监控系统架构概览 -- 数据源 监控系统架构概览 -- 告警配置 监控系统架构概览 -- 告警通道 如何监控 Go 应用? 第二部分 基于 Prometheus Go 应用监控接入流程 确定指标 为应用埋点 部署应用 配置服务发现 监控展示 指标类型 ● Go 运行时指标 ○ Goroutine 数量 ● 应用层指标 2022 年底面临的问题 ● 超 100+ 倍数据点增长导致查询缓慢 ● 架构复杂,参数调优困难 ● 频繁 OOM ● 集群规模受制于 Prometheus ● 集群成本上升 2023 压测结果 VS ● CPU 使用低 1.7 倍 ● RAM 使用减少 5 倍 ● 存储空间减少了 3 倍 25K+ 1Mil 60Mil+ 业务指标数量 每秒写入数据点 Active Time value 先用一阶增量编码( Delta )压缩,然后再用 zigzag 算法压缩 ○ Counters 类型的 value 先用二阶增量编码( Delta of Delta )压缩,然后再用 zigzag 算法压缩 ● 最后再应用 ZSTD 算法进行二次压缩 Prometheus Thanos VictoriaMetrics Bytes / Sample 1.2B ~ 1.79B0 码力 | 42 页 | 2.32 MB | 1 年前3 1.每秒百万数据点 Go 应用监控系统演进good? 04 总结与展望 05 监控架构概览 第一部分 监控系统架构概览 -- 数据源 监控系统架构概览 -- 告警配置 监控系统架构概览 -- 告警通道 如何监控 Go 应用? 第二部分 基于 Prometheus Go 应用监控接入流程 确定指标 为应用埋点 部署应用 配置服务发现 监控展示 指标类型 ● Go 运行时指标 ○ Goroutine 数量 ● 应用层指标 2022 年底面临的问题 ● 超 100+ 倍数据点增长导致查询缓慢 ● 架构复杂,参数调优困难 ● 频繁 OOM ● 集群规模受制于 Prometheus ● 集群成本上升 2023 压测结果 VS ● CPU 使用低 1.7 倍 ● RAM 使用减少 5 倍 ● 存储空间减少了 3 倍 25K+ 1Mil 60Mil+ 业务指标数量 每秒写入数据点 Active Time value 先用一阶增量编码( Delta )压缩,然后再用 zigzag 算法压缩 ○ Counters 类型的 value 先用二阶增量编码( Delta of Delta )压缩,然后再用 zigzag 算法压缩 ● 最后再应用 ZSTD 算法进行二次压缩 Prometheus Thanos VictoriaMetrics Bytes / Sample 1.2B ~ 1.79B0 码力 | 42 页 | 2.32 MB | 1 年前3
 Hello 算法 1.1.0 Go版7.1 二叉树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.2 二叉树遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.3 二叉树数组表示 二叉树数组表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.4 二叉搜索树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.5 AVL 树 * . . . . . . . . 208 10.1 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 10.2 二分查找插入点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 10.3 二分查找边界 .0 码力 | 383 页 | 18.48 MB | 1 年前3 Hello 算法 1.1.0 Go版7.1 二叉树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.2 二叉树遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.3 二叉树数组表示 二叉树数组表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.4 二叉搜索树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.5 AVL 树 * . . . . . . . . 208 10.1 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 10.2 二分查找插入点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 10.3 二分查找边界 .0 码力 | 383 页 | 18.48 MB | 1 年前3
 Hello 算法 1.0.0 Golang版7.1 二叉树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.2 二叉树遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.3 二叉树数组表示 二叉树数组表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.4 二叉搜索树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.5 AVL 树 * . . . . . . . . 209 10.1 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 10.2 二分查找插入点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 10.3 二分查找边界 .0 码力 | 382 页 | 17.60 MB | 1 年前3 Hello 算法 1.0.0 Golang版7.1 二叉树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.2 二叉树遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.3 二叉树数组表示 二叉树数组表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.4 二叉搜索树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.5 AVL 树 * . . . . . . . . 209 10.1 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 10.2 二分查找插入点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 10.3 二分查找边界 .0 码力 | 382 页 | 17.60 MB | 1 年前3
 Hello 算法 1.2.0 简体中文 Go 版7.1 二叉树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.2 二叉树遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.3 二叉树数组表示 二叉树数组表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.4 二叉搜索树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.5 AVL 树 * . . . . . . . . 208 10.1 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 10.2 二分查找插入点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 10.3 二分查找边界 .0 码力 | 384 页 | 18.49 MB | 10 月前3 Hello 算法 1.2.0 简体中文 Go 版7.1 二叉树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.2 二叉树遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.3 二叉树数组表示 二叉树数组表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.4 二叉搜索树 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.5 AVL 树 * . . . . . . . . 208 10.1 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 10.2 二分查找插入点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 10.3 二分查找边界 .0 码力 | 384 页 | 18.49 MB | 10 月前3
 Golang在接入层长连接服务中的实践-黄欣86 22/8 85 15 50000 10 672448 8/24 81 23/17 91 在这种极端压测情况下(冲突及其严重的场景下) • Cpu消耗从sy转移到us,因为有大量的cas fail,导致大量重试 • 整体耗时也没有明显减少 心得—channel优化 • 方案二:减小锁的粒度 队列从一条变成N条,缩小竞争范围 A B C cs Cpu (us/sy) Cost(s)0 码力 | 31 页 | 1.67 MB | 1 年前3 Golang在接入层长连接服务中的实践-黄欣86 22/8 85 15 50000 10 672448 8/24 81 23/17 91 在这种极端压测情况下(冲突及其严重的场景下) • Cpu消耗从sy转移到us,因为有大量的cas fail,导致大量重试 • 整体耗时也没有明显减少 心得—channel优化 • 方案二:减小锁的粒度 队列从一条变成N条,缩小竞争范围 A B C cs Cpu (us/sy) Cost(s)0 码力 | 31 页 | 1.67 MB | 1 年前3
 Go性能优化概览-曹春晖⾸先,是发现问题 API 压测 全链路压测 ⽣产环境被 ⾼峰流量打爆了 进 pprof 寻找(可能的) 故障原因 按照不同的情况 选择不同的⽅案 线上⼀定要开 pprof 如果有安全考虑 那也⼀定要有能通过配置开启的能⼒ CPU ⽤爆了?90%? 内存⽤爆了?OOM? Goroutine ⽤爆了?80w? 线程数爆了? 延迟太⾼? 压测时关注哪些服务指标 压测时关注哪些服务指标 goroutine 数量过多 -> 从 profile ⽹⻚进去看看 goroutine 都在⼲什 么 -> 查死锁、阻塞等问题 -> 个别不在意延迟的选择第三⽅库优 化 压测⼿段 公司内部压测平台 全链路压测 阻塞导致⾼延迟 在后端系统开发中,锁瓶颈是较常⻅的问题,⽐如⽂件锁 阻塞导致⾼延迟 还有⼀些公司的 metrics 系统设计,本机上会有 udp 通信 阻塞导致⾼延迟 异步⽇志,若队列满则丢弃,不阻塞业务逻辑 CPU 使⽤太⾼了-编解码使⽤ CPU 过⾼ 通过更换 json 库,就可以提⾼系统的吞吐量 本质上就是请求的 CPU 使⽤被优化了 我们可以使⽤固定 QPS 压测来验证该结论 https://golearn.coding.net/p/gonggongbanji/files/all/DF46 CPU 使⽤太⾼了-GC 使⽤ CPU 过⾼ https://github0 码力 | 40 页 | 8.69 MB | 1 年前3 Go性能优化概览-曹春晖⾸先,是发现问题 API 压测 全链路压测 ⽣产环境被 ⾼峰流量打爆了 进 pprof 寻找(可能的) 故障原因 按照不同的情况 选择不同的⽅案 线上⼀定要开 pprof 如果有安全考虑 那也⼀定要有能通过配置开启的能⼒ CPU ⽤爆了?90%? 内存⽤爆了?OOM? Goroutine ⽤爆了?80w? 线程数爆了? 延迟太⾼? 压测时关注哪些服务指标 压测时关注哪些服务指标 goroutine 数量过多 -> 从 profile ⽹⻚进去看看 goroutine 都在⼲什 么 -> 查死锁、阻塞等问题 -> 个别不在意延迟的选择第三⽅库优 化 压测⼿段 公司内部压测平台 全链路压测 阻塞导致⾼延迟 在后端系统开发中,锁瓶颈是较常⻅的问题,⽐如⽂件锁 阻塞导致⾼延迟 还有⼀些公司的 metrics 系统设计,本机上会有 udp 通信 阻塞导致⾼延迟 异步⽇志,若队列满则丢弃,不阻塞业务逻辑 CPU 使⽤太⾼了-编解码使⽤ CPU 过⾼ 通过更换 json 库,就可以提⾼系统的吞吐量 本质上就是请求的 CPU 使⽤被优化了 我们可以使⽤固定 QPS 压测来验证该结论 https://golearn.coding.net/p/gonggongbanji/files/all/DF46 CPU 使⽤太⾼了-GC 使⽤ CPU 过⾼ https://github0 码力 | 40 页 | 8.69 MB | 1 年前3
共 49 条
- 1
- 2
- 3
- 4
- 5














