10月3日线上交流问题汇总.md 8.8 KB

10月3日线上交流问题汇总

  • go-zero适用场景
    • 希望说说应用场景,各个场景下的优势
      • 高并发的微服务系统
        • 支撑千万级日活,百万级QPS
        • 完整的微服务治理能力
        • 支持自定义中间件
        • 很好的管理了数据库和缓存
        • 有效隔离故障
      • 低并发的单体系统
        • 这种系统直接使用api层即可,无需rpc服务
    • 各个功能的使用场景以及使用案例
      • 限流
      • 熔断
      • 降载
      • 超时
      • 可观测性
  • go-zero的实际体验
    • 服务很稳
    • 前后端接口一致性,一个api文件即可生成前后端代码
    • 规范、代码量少,意味着bug少
    • 免除api文档,极大降低沟通成本
    • 代码结构完全一致,便于维护和接手
  • 微服务的项目结构, monorepo的 CICD 处理

    bookstore
    ├── api
    │   ├── etc
    │   └── internal
    │       ├── config
    │       ├── handler
    │       ├── logic
    │       ├── svc
    │       └── types
    └── rpc
    ├── add
    │   ├── adder
    │   ├── etc
    │   ├── internal
    │   │   ├── config
    │   │   ├── logic
    │   │   ├── server
    │   │   └── svc
    │   └── pb
    ├── check
    │   ├── checker
    │   ├── etc
    │   ├── internal
    │   │   ├── config
    │   │   ├── logic
    │   │   ├── server
    │   │   └── svc
    │   └── pb
    └── model
    

mono repo的CI我们是通过gitlab做的,CD使用jenkins CI尽可能更严格的模式,比如-race,使用sonar等工具 CD有开发、测试、预发、灰度和正式集群 晚6点上灰度、无故障的话第二天10点自动同步到正式集群 正式集群分为多个k8s集群,有效的防止单集群故障,直接摘除即可,集群升级更有好

  • 如何部署,如何监控?
    • 全量K8S,通过jenkins自动打包成docker镜像,按照时间打包tag,这样可以一眼看出哪一天的镜像
    • 上面已经讲了,预发->灰度->正式
    • Prometheus+自建dashboard服务
    • 基于日志检测服务和请求异常
  • 如果打算换go-zero框架重构业务,如何做好线上业务稳定安全用户无感切换?另外咨询下如何进行服务划分?
    • 逐步替换,从外到内,加个proxy来校对,校对一周后可以切换
    • 如有数据库重构,则需要做好新老同步
    • 服务划分按照业务来,遵循从粗到细的原则,避免一个api一个微服务
    • 数据拆分对于微服务来讲尤为重要,上层好拆,数据难拆,尽可能保证按照业务拆分数据
  • 服务发现
    • 服务发现 etcd 的 key 的设计
      • 服务key+时间戳,服务进程数存在时间戳冲突的概率极低,忽略
    • etcd服务发现与治理, 异常捕获与处理异常
      • 为啥k8s还使用etcd做服务发现,因为dns的刷新有延迟,导致滚动更新会有大量失败,而etcd可以做到完全无损更新
      • etcd集群直接部署在k8s集群内,因为多个正式集群,集群单点和注册避免混乱
      • 针对etcd异常或者leader切换,自动侦测并刷新,当etcd有异常不能恢复时,不会刷新服务列表,保障服务依然可用
  • 缓存的设计与使用案例
    • 分布式多redis集群,线上最大几十个集群为同一个服务提供缓存服务
    • 无缝扩缩容
    • 不存在没有过期时间的缓存,避免大量不常使用的数据占用资源,默认一周
    • 缓存穿透,没有的数据会短暂缓存一分钟,避免刷接口或大量不存在的数据请求带垮系统
    • 缓存击穿,一个进程只会刷新一次同一个数据,避免热点数据被大量同时加载
    • 缓存雪崩,对缓存过期时间自动做了jitter,5%的标准变差,使得一周的过期时间分布在16小时内,有效防止了雪崩
    • 我们线上数据库都有缓存,否则无法支撑海量并发
    • 自动缓存管理已经内置于go-zero,并可以通过goctl自动生成代码
  • 能否讲解下, 中间件,拦截器的设计思想

    • 洋葱模型
    • 本中间件处理,比如限流,熔断等,然后决定是否调用next
    • next调用
    • 对next调用返回结果做处理
  • 微服务的事务处理怎么实现好,gozero分布式事务设计和实现,有什么好中间件推荐

    • 2PC,两阶段提交
    • TCC,Try-Confirm-Cancel
    • 消息队列,最大尝试
    • 人工补偿
  • 多级 goroutine 的异常捕获 ,怎么设计比较好

    • 微服务系统请求异常应该隔离,不能让单个异常请求带崩整个进程
    • go-zero自带了RunSafe/GoSafe,用来防止单个异常请求导致进程崩溃
    • 监控需要跟上,防止异常过量而不自知
    • fail fast和故障隔离的矛盾点
  • k8s配置的生成与使用(gateway, service, slb)

    • 内部自动生成k8s的yaml文件,过于依赖配置而未开源
    • 打算在bookstore的示例里加上k8s配置样板
    • slb->nginx->nodeport->api gateway->rpc service
  • gateway限流、熔断和降载

    • 限流分为两种:并发控制和分布式限流
    • 并发控制用来防止瞬间过量请求,保护系统不被打垮
    • 分布式限流用来给不同服务配置不同的quota
    • 熔断是为了对依赖的服务进行保护,当一个服务出现大量异常的时候,调用者应该给予保护,使其有机会恢复正常,同时也达到fail fast的效果
    • 降载是为了保护当前进程资源耗尽而陷入彻底不可用,确保尽可能服务好能承载的最大请求量
    • 降载配合k8s,可以有效保护k8s扩容,k8s扩容分钟级,go-zero降载秒级
  • 介绍core中好用的组件,如timingwheel等,讲讲设计思路

    • 布隆过滤器
    • 进程内cache
    • RollingWindow
    • TimingWheel
    • 各种executors
    • fx包,map/reduce/filter/sort/group/distinct/head/tail...
    • 一致性hash实现
    • 分布式限流实现
    • mapreduce,带cancel能力
    • syncx包里有大量的并发工具
  • 如何快速增加一种rpc协议支持,將跨机发现改为调本机节点,并关闭复杂filter和负载均衡功能

    • go-zero跟grpc关系还是比较紧密的,设计之初没有考虑支持grpc以外的协议
    • 如果要增加的话,那就只能fork出来魔改了
    • 调本机直接用direct的scheme即可
    • 为啥要去掉filter和负载均衡?如果要去的话,fork了改,但没必要
  • 日志和监控和链路追踪的设计和实现思路,最好有大概图解

    • 日志和监控我们使用prometheus, 自定义dashboard服务,捆绑提交数据(每分钟)
    • 链路追踪可以看出调用关系,自动记录trace日志

  • go-zero框架有用到什么池化技术吗?如果有,在哪些core代码里面可以参考
    • 一般不需要提前优化,过度优化是大忌
    • core/syncx/pool.go里面定义了带过期时间的通用池化技术
  • go-zero用到了那些性能测试方法框架,有代码参考吗?可以说说思路和经验
    • go benchmark
    • 压测可以通过现有业务日志样本,来按照预估等比放大
    • 压测一定要压到系统扛不住,看第一个瓶颈在哪里,改完再压,循环
  • 说一下代码的抽象经验和心得
    • Don’t repeat yourself
    • 你未必需要它,之前经常有业务开发人员问我可不可以增加这个功能或那个功能,我一般都会仔细询问深层次目的,很多时候会发现其实这个功能是多余的,不需要才是最佳实践
    • Martin Fowler提出出现三次再抽象的原则,有时有些同事会找我往框架里增加一个功能,我思考后经常会回答这个你先在业务层写,其它地方也有需要了你再告诉我,三次出现我会考虑集成到框架里
    • 一个文件应该尽量只做一件事,每个文件尽可能控制在200行以内,一个函数尽可能控制在50行以内,这样不需要滚动就可以看到整个函数
    • 需要抽象和提炼的能力,多去思考,经常回头思考之前的架构或实现
  • 你会就go-zero 框架从设计到实践出书吗?框架以后的发展规划是什么?
    • 暂无出书计划,做好框架是最重要的
    • 继续着眼于工程效率
    • 提升服务治理能力
    • 帮助业务开发尽可能快速落地