微服务架构原理与治理 探究 |青训营

1. 微服务结构初探

随着时代和科技发展,系统架构正在持续演进,主要有以下几个影响方面:

  • 互联网的爆炸性发展
  • 硬件设施的快速发展
  • 需求复杂性的多样化
  • 开发人员的急剧增加
  • 计算机理论及技术的发展

以下为架构演变轴:

1.1 单体架构

在单体架构中,整个应用程序被构建为一个单一的、完整的软件单元,通常由一个大型的、紧密耦合的代码库组成。在单体架构中,所有的功能模块和组件都运行在同一个进程中,共享同一个数据库和资源。这种紧密耦合的设计使得开发、部署和维护相对简单,冗余小,性能最高,但也存在一些潜在的问题,如下:

  • debug 困难
  • 模块相互影响
  • 模块分工、开发流程

1.2 垂直应用架构

按照业务线垂直划分,具有业务独立开发维护的优势,但也存在一些潜在的问题,如下:

  • 不同业务存在冗余
  • 每个业务还是单体

1.3 分布式架构

抽出业务无关的公共模块。具有业务无关的独立模块单独抽离的优势,但也存在一些潜在的问题,如下:

  • 服务模块bug可导致全站瘫疾
  • 调用关系复杂
  • 不同服务冗余

1.4 SOA架构

SOA架构是面向服务的,优势是服务注册。但也存在一些潜在的问题,如下:

  • 整个系统设计中心化
  • 需要从上至下设计
  • 重构困难

1.5 微服务架构

彻底的服务化。 优势:

  • 开发效率
  • 业务独立设计
  • 自下而上
  • 故障隔离 缺点:
  • 治理、运维难度
  • 观测挑战
  • 安全性
  • 分布式系统

1.6 微服务架构的核心要素

  • 服务治理
    • 服务注册
    • 服务发现
    • 负载均衡
    • 扩缩容
    • 流量治理
    • 稳定性治理
  • 可观测性
    • 日志采集
    • 日志分析
    • 监控打点
    • 监控大盘
    • 异常报警
    • 链路追踪
  • 安全
    • 身份验证
    • 认证授权
    • 访问令牌
    • 审计
    • 传输加密
    • 黑产攻击

2. 微服务架构原理及特征

2.1 基本概念

以下是一些基本概念

  • 服务 (service)。一组具有相同逻辑的运行实体
  • 实例 (instance)。一个服务中,每个运行实体即为一个实例
  • 实例与进程的关系。
    • 实例与进程之间没有必然对应关系,可以一个实例对应一个或多个进程(反之不常见)。
  • 集群(cluster)。通常指服务内部的逻辑划分,包含多个实例。
  • 常见的实例承载形式。进程、VM、k8s pod.....
  • 有状态 / 无状态服务。服务的实例是否存储了可持久化的数据(例如磁盘文件)。
  • 微服务间通信
    • 对于单体服务,不同模块通信只是简单的函数调用。
    • 对于微服务,服务间通信意味着网络传输

2.2 服务注册及发现

在代码层面,如何指定调用一个目标服务的地址 (ip:port)? 若是采用DNS,会存在:

  • 本地 DNS 存在缓存,导致延时。
  • 负载均衡问题
  • 不支持服务实例的探活检查
  • 域名无法配置端口。 解决思路: 新增一个统一的服务注册中心,用于存储服务名到服务实例的映射.
  • 服务实例上线及下线过程

2.3 流量特征

  • 统一网关入口
  • 内网通信多数采用RPC
  • 网状调用链路

3. 核心服务治理功能

3.1 服务发布

服务发布 (deployment),即指让一个服务升级运行新的代码的过程。

服务发布的难点:

  • 服务不可用
  • 服务抖动
  • 服务回滚

服务发布的形式:

  • 蓝绿部署。旨在实现无缝的版本切换和最小化生产环境中的中断时间。简单,稳定,但需要两倍资源。
    • 蓝环境是当前正在运行的生产环境,处理实际用户流量。
    • 绿环境是新版本的环境,用于部署和测试新功能和代码。
  • 灰度发布(金丝雀发布)。灰度发布通过逐步将新版本或新功能发布给一部分用户或服务器,以便在实际环境中进行测试和验证,从而降低风险并确保系统的稳定性。

3.2 流量治理

在微服务架构下,可以基于地区、集群、实例、请求等维度,对端到端流量的路由路径进行精确控制。

3.3 负载均衡

负载均衡 (Load Balance) 负责分配请求在每个下游实例上的分布。

负载均衡算法:

  • Round Robin
  • Random
  • Ring Hash
  • Least Request

3.4 稳定性治理

线上服务总是会出问题的,但与程序的正确性无关。

有以下突发情况:

  • 网络攻击
  • 流量突增
  • 机房断电
  • 光纤被挖
  • 机器故障
  • 网络故障
  • 机房空调故障

典型稳定性治理方案:

  • 限流
  • 熔断
  • 过载保护
  • 降级

4. 字节跳动服务治理实践

4.1 重试的意义

本地函数调用可能存在异常:

  • 参数非法
  • OoM (Out Of Memory)
  • NPE(Null Pointer Exception)
  • 边界 case
  • 系统崩溃
  • 死循环
  • 程序异常退出

远程函数调用可能存在异常:

  • 网络抖动
  • 下游负载高导致超时
  • 下游机器宕机
  • 本地机器负载高,调度超时
  • 下游熔断、限流

重试可以避免掉偶发的错误,提高 SLA (Service-Level Agreement)

go 复制代码
func RemoteFunc(ctx context.Context, x int) (int, error) {
    ctx2, defer_func := context.WithTimeout(ctx, time.Second)
    defer defer_func()
    res, err := grpc_client.Calculate(ctx2,x * 2)
    return res, err
}
func RemoteFuncRetry(ctx context.Context, x int) (res int, err error)[
    for i := 0;i < 3; i++ {
        if res, err = RemoteFunc(ctx, x); err == nil [
            return
        }
    }
    return
}

重试意义

  • 降低错误率。假设单次请求的错误概率为 0.01,那么连续两次错误概率则为 0.0001
  • 降低长尾延时。对于偶尔耗时较长的请求,重试请求有机会提前返回。
  • 容忍暂时性错误。某些时候系统会有暂时性异常 (例如网络抖动),重试可以尽量规避。
  • 避开下游故障实例。一个服务中可能会有少量实例故障(例如机器故障),重试其他实例可以成功。

4.2 重试的难点

  • 幂等性。多次请求可能会造成数据不一致。
  • 重试风暴。随着调用深度的增加,重试次数会指数级上涨。
  • 超时设置。假设一个调用正常是 1s 的超时时间,如果允许一次重试,那么第一次请求经过多少时间时,才开始重试呢?

4.3 重试策略

  • 限制重试比例
    • 设定一个重试比例闽值 (例如 1%),重试次数占所有请求比例不超过该闯值
  • 放止链路重试
    • 链路层面的防重试风暴的核心是限制每层都发生重试。
    • 理想情况下只有最下一层发生重试。
    • 可以返回特殊的 status 表明"请求失败,但别重试"。
  • Hedged requests
    • 对于可能超时 (或延时高) 的请求,,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应。

4.4 重试效果验证

验证经过上述重试策略后,在链路上发生的重试放大效应。

5. 结语

微服务架构原理与治理是当今软件开发领域中的热门话题,它提供了一种灵活且可扩展的方法来构建复杂的应用程序。通过将应用程序拆分为小而自治的服务,微服务架构使得团队能够更加敏捷地开发、部署和维护应用程序。同时,治理是确保微服务架构成功实施的关键因素之一,它涉及到服务发现、负载均衡、故障恢复等方面的实践。

在学习微服务架构原理与治理的过程中,我深深地体会到了以下几点:

首先,微服务架构的设计理念强调松耦合和高内聚。每个服务都是独立的、自治的,可以独立开发、部署和扩展。这种模块化的设计使得团队能够更好地应对需求变化,并且能够更加灵活地进行团队组织和协作。

其次,治理是微服务架构成功实施的重要组成部分。通过使用适当的工具和技术,我们可以实现服务的自动发现、负载均衡、故障恢复等功能。这些治理机制不仅可以提高系统的可用性和性能,还可以简化开发和运维的工作。

另外,微服务架构也带来了一些挑战和复杂性。服务之间的通信、数据一致性、分布式事务等问题需要仔细考虑和解决。同时,微服务架构也需要更强大的基础设施和监控系统来支持。

总的来说,微服务架构原理与治理是一门值得深入学习和实践的领域。它不仅可以提高应用程序的灵活性和可扩展性,还可以促进团队的协作和创新。然而,我们也要认识到微服务架构并不适用于所有场景,需要根据具体情况进行评估和决策。只有在正确的使用和治理下,微服务架构才能发挥出它的优势,为我们构建高效、可靠的应用程序带来更多的机会和挑战。

相关推荐
夭要7夜宵3 天前
Go 垃圾回收 | 豆包MarsCode AI刷题
青训营笔记
末班车4224 天前
前端框架中的设计模式 | 豆包MarsCode AI刷题
青训营笔记
VanceLLF5 天前
神奇数字组合 | 豆包MarsCode AI刷题
青训营笔记
lann5 天前
Go 程序的优化 | 豆包MarsCode AI刷题
青训营笔记
用户52281271049785 天前
性能优化与调试技巧 | 豆包MarsCode AI刷题
青训营笔记
千慌百风定乾坤7 天前
Go 语言入门指南:基础语法和常用特性解析(下) | 豆包MarsCode AI刷题
青训营笔记
FOFO7 天前
青训营笔记 | HTML语义化的案例分析: 粗略地手绘分析juejin.cn首页 | 豆包MarsCode AI 刷题
青训营笔记
滑滑滑9 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬9 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399659 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记