Go最新Go分布式爬虫笔记(五)_golang分布式爬虫架构(6),一个Golang程序员的面试心得

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

服务治理:

  • 监控、告警
  • 降级策略(限流、重试、降级、熔断)
  • 分布式追踪与分布式日志收集

程序设计和组织级别

程序设计

  • 功能的拆分
  • 流程的抽象
  • 使用何种形式组织代码
  • 定义清晰的模块间的接口边界
  • 使用何种框架
  • 并发处理模型
  • 搭建的开发流程和规范
  • 重点指标体系的设计和监控

高性能程序设计的几个原则:

  • 流程异步化
    为了外部用户的体验,降低延迟,有时我们可以结合业务对流程进行异步化,快速返回结果给外部用户。这可以提高用户体验、服务的 QPS 与吞吐量。
    例如,任务执行完毕后需要将一些数据存入缓存中。这时可以直接返回结果,并异步地写入数据库。又如,调用一个执行周期很长的函数,可以先直接返回,然后在执行完毕后请求用户给的回调地址。不过要注意的是,无论怎样异步化,终究是需要执行任务的。
  • 在执行的关键阶段请求并行化,尽可能把串行改为并行。
    你可能听说过华罗庚烧水泡茶的故事,这个故事的要点,就是将整个大任务分割为小任务,让关键任务并行进行处理,这个方案可以大大减少整个任务的处理时间。
  • 合理选择与实际系统匹配的并发模型
    根据自身服务的不同,需要了解 Go 语言在网络 I/O、磁盘 I/O,CPU 密集型系统在程序处理过程中的不同处理模型。并根据不同的场景选择不同的高并发模型。
  • 无锁化与缓存化,保证并发的威力。
    试想一个极端的不合理的锁设计,它可能会让所有的用户协程等待某一个协程执行完成,导致并行处理退化为串行执行。无锁化并不是完全不加锁,而是要合理设计并发控制。
    例如设计无锁的结构,在多读少写场景用读锁替代写锁,用局部缓存来减少对于全局结构的访问(关于如何设计无锁化结构,你可以参考 sync.pool 库、go 内存分配、go 调度器等模块在并行处理中的极致优化)。

怎么用工具和指标来验证程序实际并行的效率呢?

  • 协程数量
  • 调度器的运行方式

获取协程数量的方式:

  • 借助 Debug 库中的 NumGoroutine 函数,GOMAXPROCS 还可以获取逻辑处理器 P;
  • 使用 runtime/metrics 包,获取运行时 metric,进而获取到协程数量;
  • 通过 pprof 获取当前的协程数量。

调度器:Go调度跟踪

  • 启动 GODEBUG 特定环境变量方式,查看调度器日志;
  • 通过 pprof 和 trace 工具,可视化分析调度器的运行状态。

代码实施级别

  • 合理代码优化

    • 代码规范

    • 数据结构与算法

      • 算法优化
      • 数据结构优化
    • 缓存:空间换时间

      • CPU多级缓存
      • Go运行时调度器
      • Go内存分配器
      • sync.pool
    • 复杂度

    • benchmark对比

  • 刻意的优化

    • 放入接口中的数据会进行内存逃逸,需不需要优化?

    • 字节数组与 String 互转导致的性能损失需不需要优化?

    • 无用的内存需不需要复用?

    • 定位瓶颈问题

      • 工具:pprof、trace、dlv、gdb

      • 数据结构与算法

      • 序列化

      • Go 语言的编译时和运行时。例如,之前介绍过的将环境变量 GOMAXPROC 调整为更合适的大小,本质上就是在修改运行时可并行的线程数量。

      • 此外,当并发量上来之后,垃圾回收(GC)也可能成为系统的瓶颈所在。GC 有一段 STW 的时长完全不能执行用户协程,并且在并行标记期间会占用 25% 的 CPU 时间。如果 STW 时间过长,或者并发标记阶段由于频繁的内存分配触发了辅助标记,都会导致程序无法有效处理用户协程,产生严重的响应超时问题。
        一般这类 GC 问题可以通过修改代码逻辑减少内存分配频繁,或是借助 sync.pool 等内存池复用内存来解决。

      • 另外,运行时也暴露了一些有限的 API 能够干预垃圾回收的运行,在特殊情况下调整这些参数能够提高程序运行效率:

        • 运行时环境变量 GOGC 可以调整 GC 的内存触发水位,当 GOGC=off 时,它甚至能够关闭 GC 的执行;
        • Runtime.GC() 可以手动强制执行 GC。
      • 另外,设置运行时环境变量 GODEBUG=gctrace=1 可以让运行时打印 GC 的相关日志。

  • 危险的尝试

    • 少用CGO
    • unsafe 库本身不是向后兼容的,这意味着在当前版本中有效的代码在之后的版本中的行为是未知的。
    • 另外,对指针进行运算的 uintptr 类型本质上是一个整数,Go 内置的垃圾回收无法对它进行管理。操作指针时,由于 Go 运行时栈的自动扩容,可能导致之前指针指向的内容无效。这些危险的操作,需要开发者摸透使用规则并进行正确的权衡(unsafe 包的具体用法可以参考这篇文章)。

思维导图

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值