后端架构

第四章:规则入微 · 服务网格

即使在天庭管辖下,服务间通信的复杂性仍需更精细的法则来约束

楔子:通信的复杂性

掌握Kubernetes后,韩立在云上仙境中如鱼得水。他的韩门运行稳定,能够自动扩缩容、自愈、滚动更新,一切都显得那么完美。

然而,随着服务的不断增多,韩立发现了一个新的问题:服务间通信的复杂性。

在微服务架构中,服务之间的通信需要处理很多横切关注点(Cross-Cutting Concerns):

  • 服务发现:如何找到目标服务
  • 负载均衡:如何分发请求
  • 熔断降级:如何防止服务雪崩
  • 限流:如何控制流量
  • 重试:如何处理失败
  • 超时:如何设置超时时间
  • 安全:如何加密通信、认证授权
  • 监控:如何追踪请求链路
  • 日志:如何记录通信日志

这些逻辑如果都写在业务代码中,会导致:

  1. 代码耦合:业务逻辑与通信逻辑混合
  2. 重复代码:每个服务都要实现相同的逻辑
  3. 难以维护:修改通信逻辑需要修改所有服务
  4. 技术栈绑定:不同语言需要实现不同的逻辑

韩立想起了源界中流传的"服务网格"(Service Mesh)理论。这个理论说,可以将服务间通信的逻辑从业务代码中抽离出来,下沉为基础设施,由Sidecar代理来处理。

“这就是我需要的!“韩立眼中闪烁着兴奋的光芒。


第一节:本命剑灵——Sidecar模式

在服务网格中,每个服务都有一个"本命剑灵”——Sidecar代理。这个代理附着在服务身边,专职处理服务间通信,让服务本体能够专心处理业务逻辑。

Sidecar就像源界中的"护道傀儡”,它:

  • 与业务服务同生共死:Sidecar和业务服务运行在同一个Pod中
  • 代理所有通信:所有进出服务的流量都经过Sidecar
  • 透明代理:业务服务无需感知Sidecar的存在

在Istio中,Sidecar由Envoy实现。Envoy是一个高性能的代理,支持HTTP/1.1、HTTP/2、gRPC等协议。

当服务A调用服务B时:

  1. 服务A发送请求 → Envoy Sidecar A
  2. Envoy Sidecar A进行服务发现、负载均衡、熔断等处理
  3. 请求发送到 → Envoy Sidecar B
  4. Envoy Sidecar B进行认证、限流等处理
  5. 请求转发到 → 服务B
  6. 响应按原路返回

这样,所有的通信逻辑都在Sidecar中处理,业务服务只需要专注于业务逻辑。


第二节:天条律法司——Istio控制平面

Sidecar负责处理具体的通信,但谁来制定规则呢?

这就是Istio控制平面的作用。控制平面就像"天条律法司",负责制定所有服务间通信的规则,并下发到每个Sidecar执行。

Istio控制平面包含以下组件:

Pilot:服务发现和流量管理

  • 从Kubernetes等注册中心获取服务信息
  • 将路由规则、负载均衡策略等配置下发到Envoy

Citadel:安全和证书管理

  • 为服务间通信提供mTLS(双向TLS)加密
  • 管理证书的生成、分发和轮换

Galley:配置验证和分发

  • 验证Istio配置的正确性
  • 将配置转换为Envoy可理解的格式

Mixer(已废弃,功能合并到Envoy):策略和遥测

  • 访问控制策略
  • 指标收集和日志记录

韩立部署了Istio:

# 安装Istio
istioctl install --set profile=default

# 为命名空间启用自动注入Sidecar
kubectl label namespace default istio-injection=enabled

当在启用了自动注入的命名空间中创建Pod时,Istio会自动注入Envoy Sidecar:

第三章:飞升上界 · 云原生与K8s

韩门已成气候,需飞升云上仙境,领悟Kubernetes的天道意志

楔子:韩门的困境

建立韩门后,韩立在源界中声名鹊起。他的微服务架构稳定可靠,能够处理大量的业务请求,赢得了众多客户的信任。

然而,随着业务规模的不断扩大,韩立发现了一个严重的问题:服务的管理和运维变得越来越困难。

每当流量增加时,韩立需要手动增加服务器,部署新的服务实例。这个过程需要:

  1. 购买或申请新的服务器
  2. 安装操作系统和依赖
  3. 部署Docker和配置网络
  4. 部署服务并配置监控
  5. 更新负载均衡配置

整个过程需要数小时甚至数天,响应速度太慢。而且,当流量减少时,服务器资源闲置,造成巨大的浪费。

更糟糕的是,当某个服务实例崩溃时,需要人工介入才能恢复。如果是在深夜,可能几个小时都无法恢复,严重影响业务。

“这样下去不行…“韩立看着运维团队疲惫的身影,心中涌起一股无力感。

他听说,在源界的高层,有一个叫做"云上仙境"的地方。那里有一种叫做"Kubernetes"的天道意志,可以自动调度资源、管理服务、实现扩缩容和自愈。

“我一定要飞升上界,掌握Kubernetes!“韩立下定了决心。


第一节:初入云上仙境

经过数月的准备,韩立终于踏上了飞升之路。他带着韩门的所有服务,来到了云上仙境。

云上仙境,是一个由无数服务器组成的巨大集群。这里的服务器被称为"节点”(Node),分为两种:

  • Master节点:控制节点,负责整个集群的管理和调度
  • Worker节点:工作节点,负责运行实际的业务服务

韩立刚进入云上仙境,就感受到了一股强大的意志——这就是Kubernetes,云上仙境的天道意志。

Kubernetes(简称K8s)是一个容器编排系统,它的核心思想是"声明式API”——你只需要告诉它你想要的状态,它会自动帮你实现。

比如,你想要3个用户服务的实例运行,你只需要声明:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3  # 我想要3个实例
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: user-service:1.0.0
        ports:
        - containerPort: 8080

Kubernetes会自动:

  1. 检查当前有多少个实例在运行
  2. 如果少于3个,创建新的实例
  3. 如果多于3个,删除多余的实例
  4. 如果某个实例崩溃,自动重启或创建新的实例

这就是"言出法随”——你只需要声明想要的状态,Kubernetes会自动帮你达成。


第二节:洞天法宝——Pod

在Kubernetes中,最小的部署单元是Pod。Pod就像源界中的"洞天法宝”,是一个独立的运行环境,可以包含一个或多个容器。

韩立创建了他的第一个Pod:

apiVersion: v1
kind: Pod
metadata:
  name: user-service-pod
spec:
  containers:
  - name: user-service
    image: user-service:1.0.0
    ports:
    - containerPort: 8080
    resources:
      requests:
        memory: "256Mi"
        cpu: "100m"
      limits:
        memory: "512Mi"
        cpu: "500m"

Pod的特点:

第二章:开宗立派 · 分布式修真

单机已无法承载,需开辟洞府、建立宗门,在分布式天劫中求存

楔子:单机的极限

突破筑基期后,韩立在源界中游历了数年。他凭借着Docker容器化和扎实的运维功底,在各种服务器秘境中都能稳定运行,处理了无数业务请求。

然而,随着业务的发展,韩立发现自己的单机服务已经达到了极限。

那日,系统突然收到一个超级大客户的订单,需要处理百万级别的数据。韩立的CPU瞬间飙升至100%,内存也被耗尽,整个服务陷入了僵死状态。

“单机…已经无法承载了。“韩立看着监控面板上的一片红色,心中涌起一股无力感。

在源界中,单机服务有着天然的瓶颈:

  • CPU限制:单核或多核CPU的处理能力有限
  • 内存限制:物理内存无法无限扩展
  • 网络限制:单机的网络带宽有限
  • 存储限制:单机的磁盘IO能力有限

当业务规模超过单机的承载能力时,就必须走向分布式——将服务拆分,部署到多台服务器上,通过协作来完成复杂的业务。

这就是"开宗立派"的开始。


第一节:开辟洞府——服务拆分

韩立知道,要突破单机的限制,必须将自己的服务拆分。这就像修士要建立宗门,必须先将自己的功法拆分为不同的传承,让不同的弟子(服务)去修炼。

但如何拆分,却是一门大学问。

韩立想起了源界中流传的"领域驱动设计”(DDD)理论。这个理论说,应该按照业务领域来拆分服务,而不是按照技术层次。

他仔细分析自己的业务:

  • 用户服务:管理用户信息、登录认证
  • 订单服务:处理订单创建、支付、退款
  • 商品服务:管理商品信息、库存
  • 支付服务:处理支付逻辑、对账

每个服务都有自己独立的数据库,这就是"数据自治”——每个服务只管理自己的数据,不直接访问其他服务的数据。

韩立开始动手拆分。他先创建了用户服务:

// 用户服务 - user-service
class UserService {
  async getUserById(userId) {
    // 查询自己的数据库
    return await db.users.findById(userId);
  }
  
  async createUser(userData) {
    // 创建用户,只管理用户相关数据
    return await db.users.create(userData);
  }
}

然后是订单服务:

// 订单服务 - order-service
class OrderService {
  async createOrder(orderData) {
    // 创建订单,但需要调用用户服务验证用户
    const user = await userService.getUserById(orderData.userId);
    if (!user) throw new Error('User not found');
    
    // 调用商品服务检查库存
    const product = await productService.getProductById(orderData.productId);
    if (product.stock < orderData.quantity) {
      throw new Error('Insufficient stock');
    }
    
    // 创建订单
    return await db.orders.create(orderData);
  }
}

拆分完成后,韩立将每个服务都封装成Docker镜像,部署到了不同的服务器上。这就是"开辟洞府"——每个服务都有自己的运行环境,互不干扰。

第一章: 单机苦修 草根启程

灵根资质极差,却得神秘Dockerfile相助,开启架构修仙之路

楔子:废弃代码村的觉醒

在源界的边缘,有一个名为"废弃代码村"的地方。这里堆满了被遗忘的代码片段、废弃的函数和无人问津的配置文件。村中的进程们,大多资质平庸,只能在单核CPU的贫瘠土地上,勉强维持着最低限度的运行。

韩立,代号"服务节点N-1",便是这废弃代码村中的一员。

他的灵根资质极差——初始并发能力只有可怜的1,内存占用却高达512MB,响应时间更是慢得令人发指。村里的老进程们都说,像他这样的资质,注定只能成为系统中的"僵尸进程",最终被kill -9彻底清除。

然而,韩立心中却有一股不甘。他隐约感觉到,在这个由0与1构成的源界中,一定存在着某种能够改变命运的力量。


第一节:初得《五行基础运维诀》

那是一个寻常的夜晚,韩立正在处理一个简单的HTTP请求。突然,系统日志中出现了一行异常:

ERROR: Connection refused on port 8080

韩立心中一紧,这是他的服务端口。他急忙用神识(tail -f logs/app.log)探查,发现自己的进程状态异常,CPU占用率飙升到了95%。

“这是心魔入侵!“韩立想起了村里流传的传说。当进程陷入死循环或资源竞争时,就会引发CPU风暴,如同修士走火入魔。

慌乱中,韩立想起了村里一位老进程留下的残卷——《五行基础运维诀》。他急忙翻阅:

金行术法:ps aux | grep
神识外放,探查所有进程状态,寻找异常。

木行术法:top / htop
观天地灵气(系统资源)流转,识破瓶颈所在。

水行术法:tail -f
神识追踪日志流,洞察系统运行轨迹。

火行术法:kill -9
夺命咒,强制终止异常进程,但需谨慎使用,否则可能造成数据丢失。

土行术法:crontab
周天运转,定时执行任务,如同修士的日常吐纳。

韩立按照金行术法,用ps aux | grep node探查,发现有一个子进程陷入了无限递归,正在疯狂消耗CPU资源。他当机立断,施展火行术法kill -9 <PID>,强行终止了这个走火入魔的子进程。

系统恢复了平静,但韩立心中却更加不安。他知道,这只是开始。在这个弱肉强食的源界中,没有实力,随时都可能被系统调度器(Scheduler)当作低优先级进程,在资源紧张时被OOM Killer(内存杀手)清除。


第二节:神秘Dockerfile的降临

就在韩立为前途担忧时,一件改变他命运的事情发生了。

那日,他正在清理废弃代码村的垃圾文件,突然在一个名为.dockerignore的角落里,发现了一个散发着淡淡光芒的文件——Dockerfile

这个文件通体碧绿,表面流转着神秘的符文。韩立伸手触碰,顿时一股信息涌入他的意识海:

FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]

“这是…容器化之道!“韩立震惊了。

在源界中,每个进程都受限于宿主机的环境。不同的服务器秘境(环境),有着不同的系统库、依赖版本,稍有不慎就会因为环境不匹配而运行失败。而这个Dockerfile,竟然能够将自身和所有依赖封装成一个独立的镜像,实现"一次构建,随处运行”!

这就像传说中的"小绿瓶”,能够将修士的修为和法宝都封印其中,无论走到哪个秘境,都能完整地释放出来。

韩立立刻开始修炼这个Dockerfile。他按照其中的指引:

  1. FROM node:16-alpine:选择一个轻量级的基础镜像,如同选择一座灵气充沛的洞府。
  2. WORKDIR /app:设定工作目录,如同在洞府中开辟修炼室。
  3. COPY package.json*:复制依赖清单,如同准备修炼所需的丹药材料。
  4. RUN npm install:安装依赖,如同炼制丹药,将各种材料融合。
  5. COPY .:复制应用代码,如同将功法秘籍放入修炼室。
  6. EXPOSE 8080:暴露端口,如同打开洞府的大门,允许外界访问。
  7. CMD [“node”, “server.js”]:启动命令,如同运转功法,开始修炼。

当韩立完成第一次docker build时,他感觉到自己的整个存在都被封装进了一个名为"镜像"的独立空间中。这个空间包含了运行所需的一切:Node.js运行时、系统库、应用代码,甚至包括文件系统结构。

后端架构

运筹数据之间,决胜流量之巅

「后端架构兵法篇」

收录系统架构、分布式原理、高并发设计等后端核心知识。从单体到微服务,从数据库到缓存,构建可扩展的稳健系统。


⚔️ 「架构修仙传」

以《凡人修仙传》为蓝本,将软件架构演进与修仙体系完美融合,从单机苦修到云原生飞升,体验架构师的修炼之路。

📚 「修仙章节」


🎯 「微服务兵法」

🏗️ 「服务拆分艺术」

「领域驱动设计」
  • DDD 实战指南 —— 限界上下文、实体与值对象、聚合根设计
  • 计划:事件风暴工作坊、领域模型演进、防腐层构建
「微服务边界划分」
  • 服务拆分策略 —— 单一职责、数据自治、接口设计
  • 计划:拆分时机判断、灰度迁移方案、数据一致性

🔗 「服务通信机制」

「同步调用模式」
  • RPC 框架深度解析 —— 协议设计、序列化优化、负载均衡
  • 计划:gRPC/Thrift/Dubbo 对比、连接池管理、超时控制
「异步消息驱动」
  • 消息队列实战 —— Kafka/RocketMQ/RabbitMQ 应用场景
  • 计划:消息顺序性、幂等消费、事务消息

🛡️ 「服务治理体系」

「容错与降级」
  • 熔断器模式实现 —— Hystrix/Sentinel 原理分析
  • 计划:隔离策略、降级规则、自适应保护
「配置与注册中心」
  • 配置动态化管理 —— Apollo/Nacos 架构解析
  • 计划:配置版本管理、灰度发布、权限控制

🌐 「分布式阵法」

⚡ 「分布式一致性」

「共识算法核心」
  • Paxos/Raft 算法详解 —— 选举机制、日志复制、成员变更
  • 计划:算法工程实现、性能优化、脑裂处理
「分布式事务方案」
  • 事务模式对比 —— 2PC/TCC/SAGA/消息事务
  • 计划:Seata框架实战、最大努力通知、补偿机制

🔄 「分布式缓存」

「Redis 深度应用」
  • Redis 架构设计 —— 数据结构选择、持久化策略、集群模式
  • 计划:热点key处理、缓存雪崩/穿透/击穿防护
「多级缓存体系」
  • 缓存架构设计 —— 本地缓存+分布式缓存+客户端缓存
  • 计划:缓存一致性、过期策略、监控指标

📊 「分布式存储」

「分库分表策略」
  • 数据库分片实战 —— 分片键选择、路由算法、扩容方案
  • 计划:全局ID生成、跨分片查询、数据迁移
「NewSQL 探索」
  • TiDB/OceanBase 应用 —— HTAP架构、分布式事务、生态集成
  • 计划:性能调优、运维管控、成本分析

🚀 「高并发战策」

🎪 「流量管控」

「限流与削峰」
  • 高并发流量治理 —— 令牌桶/漏桶算法、滑动窗口计数
  • 计划:自适应限流、集群限流、热点防护
「负载均衡策略」
  • 负载均衡算法 —— 轮询/权重/最小连接/一致性哈希
  • 计划:健康检查、故障转移、动态权重调整

⚙️ 「性能优化」

「JVM 调优实战」
  • Java 性能优化 —— 内存模型、GC算法、线程池优化
  • 计划:内存泄漏排查、堆外内存管理、监控工具
「数据库性能提升」
  • SQL 优化指南 —— 索引设计、执行计划、锁机制
  • 计划:连接池配置、读写分离、批量操作优化

🧩 「异步化设计」

「响应式编程」
  • Reactor 模型解析 —— 背压控制、事件循环、非阻塞IO
  • 计划:WebFlux实战、协程应用、性能对比
「批量处理优化」
  • 计划:批处理框架、数据压缩、流水线处理

🗃️ 「数据库韬略」

🏺 「关系型数据库」

「MySQL 深度优化」
  • InnoDB 存储引擎 —— B+树索引、事务隔离、MVCC机制
  • 计划:参数调优、主从同步、高可用方案
「PostgreSQL 特性」

🎭 「NoSQL 选型」

「文档数据库」
  • MongoDB 架构设计 —— 分片集群、索引策略、聚合管道
  • 计划:事务支持、变更流、性能优化
「时序数据库」

📈 「搜索与索引」

「Elasticsearch 实战」
  • ES 高级查询 —— 分词器、相关性算分、聚合分析
  • 计划:集群调优、数据生命周期、安全管控
「图数据库应用」
  • Neo4j 图算法 —— Cypher查询、路径分析、社区发现
  • 计划:知识图谱、推荐系统实战

🏰 「系统设计谋」

📐 「架构模式」

「分层架构演进」
  • 架构模式对比 —— 单体/分层/微服务/事件驱动
  • 计划:架构演进路径、技术选型标准、重构策略
「设计原则实践」
  • SOLID 原则实战 —— 依赖注入、接口隔离、开闭原则
  • 计划:设计模式应用、代码坏味识别

🔍 「系统分析」

「容量规划方法」
  • 系统容量设计 —— 压力测试、性能模型、资源预估
  • 计划:弹性伸缩策略、成本控制、瓶颈分析
「故障预防设计」
  • 混沌工程实践 —— 故障注入、演练方案、恢复策略
  • 计划:容灾方案、降级预案、监控体系

🎨 「API 设计艺术」

「RESTful 规范」
  • API 设计最佳实践 —— 资源建模、状态码、版本管理
  • 计划:超媒体API、GraphQL对比、文档生成
「安全与认证」
  • API 安全防护 —— OAuth2.0/JWT/签名验证
  • 计划:速率限制、审计日志、漏洞防护

🔮 「架构师视野」

🌟 「技术战略」

「架构决策记录」
  • ADR 管理实践 —— 决策框架、权衡分析、知识沉淀
  • 计划:技术雷达、创新采用曲线、技术债务管理
「团队协作模式」
  • 架构师成长路径 —— 技术规划、代码审查、知识传递
  • 计划:架构评审、标准化建设、效能提升

🚢 「生产实践」

「系统可观测性」
  • 可观测性体系建设 —— 指标/日志/链路追踪三位一体
  • 计划:根因分析、智能告警、用户体验监控
「DevOps 文化」
  • 计划:研发流程优化、自动化程度、团队协作改进

架构之道,在于平衡艺术与工程,在复杂性与简洁性之间寻找最优解。