微服务一:微服务概览

一、 单体架构(巨石架构)

下图就是一个巨石架构,尽管也是模块化逻辑,但是最终它还是会打包并部署为单体式应用。其中最主要问题就是这个应用太复杂,以至于任何单个开发者都不可能搞懂它。应用无法扩展,可靠性很低,最终,敏捷性开发和部署变的无法完成。我们应对的思路:化繁为简,分而治之
在这里插入图片描述

各个模块整合成一个war包,作为单体服务部署在这里插入图片描述

二、微服务

微服务定义

围绕业务功能构建的,服务关注单一业务,服务间采用轻量级的通信机制,可以全自动独立部署,可以使用不同的编程语言和数据存储技术。微服务架构通过业务拆分实现服务组件化,通过组件组合快速开发系统,业务单一的服务组件又可以独立部署,使得整个系统变得清晰灵活:如下图,各个服务拆分开,各个服务也可以有自己的DB在这里插入图片描述

优点

  • 服务拆分后比较小,BUG 少,容易测试和维护,也容易扩展
  • 原子服务,一个服务只做一件事情,并且属于这个服务的也不应该拆分到其他服务去
  • 独立进程,一个服务只有一个独立进程,可以很好的和当前的容器化进行结合,无状态的服务可以很容易的享受到k8s上的故障转移,自动重启等好处
  • 隔离部署,每个服务之间独立部署,可以避免相互影响,并且和按需进行分配资源,节省成本

去中心化服务治理

  • 数据去中心化,每个服务独享数据库,缓存等设施,也有个别情况多个服务共享数据库,例如面向用户的管理后台和面向管理员的管理后台
  • 治理去中心化
  • 技术去中心化,每个服务可以使用适合自己的技术进行实施,但是注意如果技术栈过于发散对于企业或者团队本身也是不利的

缺点

  • 服务之间的依赖关系复杂,成千上万个服务相互依赖就像一团乱麻一样,剪不断理还乱。

常见的解决方案:全链路追踪,例如, opentracing

  • 微服务本身是分布式系统,需要使用 RPC 或者 消息进行通信,此外,必须要写代码来处理消息传递中速度过慢或者服务不可用等局部失效问题

例子:服务调用流量会容易被放大,如果 服务 A -> B ->C 如果 A 有一个for循环调用 B某个接口,B 也有一个for循环调用 C某个接口,那么一个请求到达 C 之后就被放大了 100 倍甚至上千倍。这是扛不住的
常见解决方案:粗粒度的进程间通信(batch 接口,批量请求,避免 n+1 问题),隔离,超时保护,负载保护,熔断、限流、降级、重试,负载均衡

  • 会有分布式事务问题,因为现在每个微服务之间都会有一个独立的数据库,事务在单体应用中很好处理,但是在跨服务时会变得很麻烦

常见解决方案:两阶段提交、TCC 等

  • 测试会非常复杂,由于依赖多,无法得知是因为功能异常还是依赖的某个服务发版出现问题

常见解决方案:独立测试环境,后面会有一个解决方案

  • 服务模块间的依赖,应用的升级有可能会波及多个服务模块的修改。

切记,在服务需要变更时我们要特别小心,服务提供者的变更可能引发服务消费者的兼容性破坏,时刻谨记保持服务契约(接口)的兼容性
发送时要保守,接收时要开放。按照伯斯塔尔法则的思想来设计和实现服务时,发送的数据要更保守,意味着最小化的传送必要的信息,接收时更开放意味着要最大限度的容忍冗余数据,保证兼容性。

  • 对基础建设的要求很高,基础设施需要自动化,日志采集,监控数据采集,告警,CICD,K8s

常见解决方案:上云

微服务设计

微服务如何对外暴露

整体分层如下图
在这里插入图片描述

为什么我们的服务不直接对外进行暴露?
如果外部可以直接调用微服务,则前端(移动端、客户端、web)同学非常痛苦,需要对接多个服务,兼容性差,沟通效率低
后端同学也很痛苦,一年前的版本都有人使用,服务无法进行重构升级

为什么需要最外层的 api gateway?
最外层网关进行认证和限流等,如果没有该层,则每个服务都需要有自己的认证和限流,基础库的同学会非常痛苦,限流熔断安全等业务无关的功能需要进行升级的时候升不动

微服务如何拆分

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

  • 在系统稳定之后,积累了相关的业务经验和微服务开发经验之后,再考虑使用 DDD 限界上下文进行划分

  • 如果可以闭环的解决一个用户场景,那么它应该是一个微服务

  • 还可以根据访问频率进行区分划分,将用户高频访问的部分划分为一个服务

  • 还可以根据读写进行划分

CQRS(Command Query Responsibility Segregation)架构模式。CQRS 是一种与领域驱动设计 (DDD) 和事件溯源相关的架构模式,它将写入和读取分开,将应用程序分为两部分:命令端和查询端。命令端处理程序创建,更新和删除请求,并在数据更改时发出事件。查询端通过针对一个或多个物化视图执行查询来处理查询,这些物化视图通过订阅数据更改时发出的事件流而保持最新

CQRS举例如下图:底部External为外部服务,关注的是稿件结果,即稿件是否可以查询出来进行查看。上层创作则流转到稿件服务时,还需要审批等一系列操作,是外部不关心的,此时我们通过Binlog,由Canal同步到Kafka,并用一个稿件job服务作为消费者,将稿件结果写入到新的MySQL库,专门存储外部关注的相关稿件信息,即将稿件的创作和查看进行了拆分。
在这里插入图片描述

微服务安全

对于外网的请求来说,我们通常在 API Gateway 进行统一的认证拦截,一旦认证成功,我们会使用 JWT 方式通过 RPC 元数据传递的方式带到 BFF 层,BFF 校验 Token 完整性后把身份信息注入到应用的 Context 中,BFF 到其他下层的微服务,建议是直接在 RPC Request 中带入用户身份信息(UserID)请求服务。

  • API Gateway -> BFF -> Service
  • Biz Auth -> JWT -> Request Args

对于服务内部,一般要区分身份认证和授权。

  • Full Trust
  • Half Trust
  • Zero Trust
    在这里插入图片描述
    详细如下
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值