1. 为什么会有微服务


  • 之前一般是一个单一的巨石架构,存在很多问题
    • 应用比较复杂,没有人能够搞懂
    • 应用扩展比较复杂,可靠性比较低
    • 无法进行敏捷开发和部署
  • 所以这个时候就会考虑按照服务功能拆分

2. 微服务是什么


  • SOA(面向服务)是什么?
    • 服务拆分后比较小,bug少,容易测试和维护,也容易扩展
    • 单一职责,一个服务只做一件事情
    • 尽可能早的创建原型,先定义api,达成契约
    • 可移植性比效率更重要,通讯协议的可移植性更加重要
  • SOA和微服务是什么关系?
    • 微服务是SOA的一种实践,微服务也是面向服务的一种架构
  • 微服务是什么?
    • 围绕业务功能构建的,服务关注单一业务,服务间采用轻量级通讯机制,可以全自动独立部署,可以使用不同的编程语言和数据存储技术

      3. 微服务好处与缺点


  • 优点
    • 服务拆分后比较小,BUG 少,容易测试和维护,也容易扩展
    • 原子服务,一个服务只做一件事情,并且这个属于这个服务的也不应该拆分到其他服务去
    • 独立进程,一个服务只有一个独立进程,可以很好的和当前的容器化进行结合,无状态的服务可以很容易的享受到,k8s 上的故障转移,自动重启等好处
    • 隔离部署,每个服务之间独立部署,可以避免相互影响,并且和按需进行分配资源,节省成本
    • 去中心化服务治理
      • 数据去中心化,每个服务独享数据库,缓存等设施,也有个别情况多个服务共享数据库,例如面向用户的管理后台和面向管理员的管理后台
      • 治理去中心化
      • 技术去中心化,每个服务可以使用适合自己的技术进行实施,但是注意如果技术栈过于发散对于企业或者团队本身也是不利的
  • 缺点
    • 服务之间的依赖关系复杂,成千上万个服务相互依赖就像一团乱麻一样,剪不断理还乱。
      • 常见的解决方案:全链路追踪,例如, opentracing
    • 微服务本身是分布式系统,需要使用 RPC 或者 消息进行通信,此外,必须要写代码来处理消息传递中速度过慢或者服务不可用等局部失效问题
      • 例子:服务调用流量会容易被放大,如果 服务 A -> B ->C 如果 A 有一个循环调用 B,B 也有一个循环调用 C,那么一个请求到达 C 之后就被放大了 100 倍甚至上千倍。这是扛不住的
      • 常见解决方案:粗粒度的进程间通信(batch 接口,批量请求,避免 n+1 问题),隔离,超时保护,负载保护,熔断、限流、降级、重试,负载均衡
    • 会有分布式事务问题,因为现在每个微服务之间都会有一个独立的数据库,事务在单体应用中很好处理,但是在跨服务时会变得很麻烦
    • 测试会非常复杂,由于依赖多,无法得知是因为功能异常还是依赖的某个服务发版出现问题
      • 常见解决方案:独立测试环境,后面会有一个解决方案
    • 服务模块间的依赖,应用的升级有可能会波及多个服务模块的修改。
      • 切记,在服务需要变更时我们要特别小心,服务提供者的变更可能引发服务消费者的兼容性破坏,时刻谨记保持服务契约(接口)的兼容性
      • 发送时要保守,接收时要开放。按照伯斯塔尔法则的思想来设计和实现服务时,发送的数据要更保守,意味着最小化的传送必要的信息,接收时更开放意味着要最大限度的容忍冗余数据,保证兼容性。
    • 对基础建设的要求很高,基础设施需要自动化,日志采集,监控数据采集,告警,CICD,K8s 等
      • 常见解决方案:上云

4. 微服务如何构建


多个微服务组合(compose)完成了一个完整的用户场景(usecase)。

  • kit:一个微服务的基础库(框架)。
  • service:业务代码 + kit 依赖 + 第三方依赖组成的业务微服务
  • rpc + message queue:轻量级通讯

5. 微服务如何对外暴露


image.png
流量链路是什么?
• 移动端 -> API Gateway -> BFF -> 微服务
• 不含 CDN、负载均衡(LB)
• BFF 纯 web 的业务一般用 nodejs 做 SSR
为什么我们的服务不直接对外进行暴露?
• 前端(移动端、客户端、web)同学非常痛苦,需要对接多个服务,兼容性差,沟通效率低
• 后端同学也很痛苦,一年前的版本都有人使用,服务无法进行重构升级
为什么需要最外层的 api gateway?
• 基础库的同学非常同步,限流熔断安全等业务无关的功能需要进行升级的时候升不动

6. 微服务如何拆分


  • 在对业务领域不是特别熟悉的时候,按照部门职能进行,例如账号 财务
    • 注意划分的时候要闭环,不要相同的功能散落到几个部门当中


  • 在系统稳定之后,积累了相关的业务经验和微服务开发经验之后,再考虑使用 DDD 限界上下文进行划分
  • 如果可以闭环的解决一个用户场景,那么它应该是一个微服务
  • 还可以根据访问频率进行区分划分,将用户高频访问的部分划分为一个服务
  • 还可以根据读写进行划分
    • CQRS: 将应用程序分为两部分:命令端和查询端。命令端处理程序创建,更新和删除请求,并在数据更改时发出事件。查询端通过针对一个或多个物化视图执行查询来处理查询,这些物化视图通过订阅数据更改时发出的事件流而保持最新
    • 微服务概览 - 图2

7. 如何保证微服务之间的安全


微服务概览 - 图3
01Go进阶训练营微服务_v1.svg

在内网主要看安全级别一般有三种:

  • Full Trust:假定内网服务之间是安全的,在内网裸奔
  • Half Trust:内网服务之间需要进行认证鉴权,但是不需要所有的都进行加密
  • Zero Trust: 零信任,任务内部网络是不安全的,类似公网,所有的请求通过身份认证鉴权之后,都需要通过安全加密,防止被嗅探

1、DDD (领域驱动设计)是一种在面向高度复杂的软件系统时,关于如何去建模的方法论,它的关键点是根据系统的复杂程度建立合适的模型,强调的是解耦具体实现技术,所以它可以迅速梳理核心业务逻辑。