微服务设计

1. API Gateway

以毛剑在实际架构中的案例作为分析的材料

毛剑在架构初期其实是采用直连的方式,连接的客户端可能是浏览器也有可能是手机,直接裸着连服务,然后就遇到了一系列的问题。

我们进行了 SOA 服务化的架构演进,按照垂直功能进行了拆分,对外暴露了一批微服务,但是因为缺乏统一的出口面临了不少困难:

·客户端到微服务直接通信,强耦合。

·需要多次请求,客户端聚合数据,工作量巨大,延迟高。

·协议不利于统一,各个部门间有差异,需要端来兼容。

·面向API适配,耦合到了内部服务。

·多终端兼容逻辑复杂,每个服务都需要处理。

·统一逻辑无法收敛,比如安全认证、限流。

下图就是最初的V1.0的架构

我们之前提到了我们工作模型,要内聚模式配合。继这上面的v1.0版本之后,我们自然的而然的就想到在客户端与后端服务之间加一个app-interface的组件。

我们新增了一个 app-interface 用于统一的协议出口,这就是下面的v2.0版本。在服务内进行大量的 dataset join,按照业务场景来设计粗粒度的 API,给后续服务的演进带来的很多优势:

·轻量交互:协议精简、聚合。

·差异服务:数据裁剪以及聚合、针对终端定制化API

·动态升级:原有系统兼容升级,更新服务而非协议。

·沟通效率提升,协作模式演进为移动业务 网关小组。

BFF 可以认为是一种适配服务,将后端的微服务进行适配(主要包括聚合裁剪和格式适配等逻辑),向无线端设备暴露友好和统一的 API,方便无线设备接入访问后端服务。

v2.0的BFF架构的版本最致命的一个问题是整个 app-interface 属于 single point of failure,严重代码缺陷或者流量洪峰可能引发集群宕机。

于是继续改进,在V2.0的版本上,将BFF根据业务模块拆成多个,每个BFF网关都有自己的任务,于是v3.0的架构就横空出世,就是下图。

v 3.0的版本在后续使用中比较突出的问题也是逐渐浮现出来:

·单个模块也会导致后续业务集成复杂度高,根据康威法则,单块的无线BFF和多团队之间就出现不匹配问题,团队之间沟通协调成本高,交付效率低下。

·很多跨横切面逻辑,比如安全认证,日志监控,限流熔断等。随着时间的推移,代码变得越来越复杂,技术债越堆越多。

跨横切面(Cross-Cutting Concerns)的功能,需要协调更新框架升级发版(路由、认证、限流、安全),因此全部上沉,引入了 API Gateway,把业务集成度高的 BFF 层和通用功能服务层 API Gateway 进行了分层处理。

在新的架构中,网关承担了重要的角色,它是解耦拆分和后续升级迁移的利器。在网关的配合下,单块 BFF 实现了解耦拆分,各业务线团队可以独立开发和交付各自的微服务,研发效率大大提升。另外,把跨横切面逻辑从 BFF 剥离到网关上去以后,BFF 的开发人员可以更加专注业务逻辑交付,实现了架构上的关注分离(Separation of Concerns)。

我们业务流量实际为:

移动端 -> API Gateway -> BFF -> Mircoservice,**在 FE Web业务中,BFF 可以是 nodejs 来做服务端渲染(SSRServer-Side Rendering),注意这里忽略了上游的 CDN4/7层负载均衡(ELB**)。

API 网关的产品有很多,比如Java的zuul或者是大名鼎鼎的Kong又或者是Api six,OR.....

2. Mircoservice 划分

微服务架构时遇到的第一个问题就是如何划分服务的边界。在实际项目中通常会采用两种不同的方式划分服务边界,即通过业务职能(Business Capability)或是 DDD (领域驱动设计)的限界上下文(Bounded Context)。

·Business Capability

由公司内部不同部门提供的职能。例如客户服务部门提供客户服务的职能,财务部门提供财务相关的职能。

·Bounded Context

限界上下文是 DDD 中用来划分不同业务边界的元素,这里业务边界的含义是“解决不同业务问题”的问题域和对应的解决方案域,为了解决某种类型的业务问题,贴近领域知识,也就是业务。

这本质上也促进了组织结构的演进:Service per team

举个例子,按照毛剑的说法就是B站做微服务架构演进的初期,按照业务拆解服务,比如说现在就有两个业务,一个叫稿件服务,一个叫视频服务,这是初期的一个架构设计,之后在架构调整中,觉得稿件和视频都是和创作的业务相关的,所以将原来的稿件和视频都划分在创作的业务域下。

CQRS

微服务的划分还有一个非常重要的模式就是CQRS(Command Query Responsibility Segregation)故名思义是将 command 与 query 分离的一种模式。query 很好理解,就是我们之前提到的「查询」,那么 command 即命令又是什么呢?

CQRS 将系统中的操作分为两类,即「命令」(Command) 与「查询」(Query)。命令则是对会引起数据发生变化操作的总称,即我们常说的新增,更新,删除这些操作,都是命令。而查询则和字面意思一样,即不会对数据产生变化的操作,只是按照某些条件查找数据。

CQRS 的核心思想是将这两类不同的操作进行分离,然后在两个独立的「服务」中实现。这里的「服务」一般是指两个独立部署的应用。在某些特殊情况下,也可以部署在同一个应用内的不同接口上。

Command 与 Query 对应的数据源也应该是互相独立的,即更新操作在一个数据源,而查询操作在另一个数据源上。

看到这里,你可能想到一个问题,既然数据源进行了分离,如何做到数据之间的同步呢?

来看下面的例子

基于上面说的创作服务,由于稿件的服务需要做审核,稿件库有很多的业务域,上流的服务查询稿件服务查询状态,很不方便,稿件服务有更改稿件最后审核状态的接口,这些接口是不叫敏感的业务api接口,不敢给别人轻易的调用。于是毛剑就想着就做读写分析,需要另外一个DB去流式的更新稿件状态,然后将查询稿件结果的变成一个服务,以rpc的方式暴露出去。这就和CQRS的核心思想不谋而合。如图所示的架构:

稿件服务可以直接修改db中的结果,然后通过canal消息中间件订阅mysql的binlog,将订阅的binlog交给Kafka,有一个稿件服务的job订阅这些binlog然后将另一个存放稿件结果表的db进行update.来保证最后两个db的一致性。

在稿件服务演进过程中,我们发现围绕着创作稿件、审核稿件、最终发布稿件有大量的逻辑揉在一块,其中稿件本身的状态也有非常多种,但是最终前台用户只关注稿件能否查看,我们依赖稿件数据库 binlog 以及订阅 binlog 的中间件 canal,将我们的稿件结果发布到消息队列 kafka 中,最终消费数据独立组建一个稿件查阅结果数据库,并对外提供一个独立查询服务,来拆分复杂架构和业务。我们架构也从 Polling publisher -> Transaction log tailing 进行了演进(Pull vs Push)。--毛剑

3. Mircoservice 安全

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

·API Gateway -> BFF -> Service

Biz Auth -> JWT -> Request Args

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

比如说内部的grpc服务,依赖grpc证书可以知道调用者是谁,知道了调用者之后再去控制中心去查询权限,也就是根据RBAC去查询权限做认证。这样内部服务的身份认证和授权就完成了。授权根据信任度分成三个等级,全信任,半信任以及0信任,也就是所谓的裸奔。

·Full Trust

安全等级最高,服务于服务之间的通讯走tls,交互密钥,加密通讯。防止抓包嗅探和监听。

·Half Trust

服务于服务之间都知道对方是谁,但是通讯不加密。

·Zero Trust

这个就是裸奔了,谁都可以来向我发起请求。

要选择哪一种level完全取决于架构师自己咯,根据实际场景按需选择。

来源:https://www.icode9.com/content-4-858151.html

(0)

相关推荐

  • IP城域网究竟是个什么网

    提起网络,相信大家都不陌生.   每天打电话.刷新闻.看视频.在线上课.订外卖.网络购物等等,拿起手机.打开电脑,只要有网络,即使足不出户生活也没有任何问题.   那么你有没有想过,保障这一切正常运转 ...

  • 微服务设计模式

    https://www.shengchulai.com/blog-QEFWfPcRJ6.htm 微服务架构已经成为现代应用程序开发的主流.虽然说它能够解决某些问题,但却也不是万金油.而我们在使用这个体 ...

  • 如何把单体式应用拆解成微服务?【上】

    微服务是当下最流行的应用架构技术了,它跟容器服务.DevOps合称云时代的三剑客,可以帮我们化解业务发展过快导致的产品迭代压力,让我们可以自由选择最适合团队的技术栈,让系统能够承载互联网海量用户的访问 ...

  • 微服务架构师的道、法、术

    作者:李鑫 | 天弘基金移动直销平台技术负责人 出品:百林哲 导语: 这几年微服务的热度持续居高不下,企业纷纷向微服务架构转型.但微服务架构会对整个研发体系,包括开发.运维.团队协同.组织架构都带来冲 ...

  • 从SOA架构思想到中台和微服务,太多的基础概念需要澄清

    作者:人月神话,新浪博客同名 简介:多年SOA规划建设,私有云PaaS平台架构设计经验,长期从事一线项目实践 今天这篇文章作为对SOA,中台和微服务等大量基础概念的一次统一说明.我始终认为,当你在学习 ...

  • 微服务设计-服务组合和可视化编排思考

    今天再重新整理下我对服务组合和服务可视化编排的一些思考. 从整个服务分层的角度来说,微服务最底层首先提供的是原子服务,再朝上则可以提供更加粗颗粒度的组合服务能力. 为何要进行服务组合和编排? 简单来说 ...

  • 为什么在做微服务设计的时候需要DDD?

    记得之前在规划和设计微服务架构的时候,张队长给了我一个至今依然记忆深刻的提示:『你的设计蓝图里为什么没有看到DDD的影子呢?』 随着对充血模型的领域认知的加深,我越加感觉到DDD的重要性.但是DDD内 ...

  • 微服务架构下的API接口驱动开发,设计和集成

    今天谈下在微服务架构下,接口设计和开发方面的思考. 对于微服务架构,SOA和Http Rest API接口设计,在我前面的头条文章中均有专门的说明,因此对于基础方面的解释在本文不再重复.对于今天要写的 ...

  • Laravel 如何设计微服务架构,及如何进行微服务间沟通? | Laravel China 社区

    如题,我目前有需要用 Laravel 设计微服务架构的需求,但能找到的相关资料不多 目前已有的一个思考方向是使用 K8S 统合各个独立的 Laravel 小服务,再开放统一对外的 API Gatewa ...

  • 微服务架构设计实践系列之九:应用架构

    微服务架构设计实践  目    次1 序言2 微服务3 软件架构设计思想4 微服务架构设计实践4.1 项目概述4.2 架构准备阶段4.3 概念架构阶段4.4 细化架构阶段4.4.1 业务架构4.4.2 ...

  • 微服务分布式事务之LCN、TCC特点、事务补偿机制缘由以及设计重点

    在亿级流量架构之分布式事务解决方案对比中, 已经简单阐明了从本机事务到分布式事务的演变过程, 文章的最后简单说明了TCC事务, 这儿将会深入了解TCC事务是原理, 以及理论支持, 最后会用Demo举例 ...

  • 电商微服务体系中分层设计和领域的划分

    架构之美 67篇原创内容 公众号 -     前言    - 比起"高并发.多线程"."分布式CAP.一致性.Paxos"."高可用SLA" ...

  • 膜拜!来看大牛是如何设计微服务系统的,学会直接拥有架构师思维

    程序员高级码农II2020-08-12 07:07:00 前言 毫无疑问,如何设计微服务系统是本书所要讨论的核心话题.本节我们将从服务拆分.服务测试.服务注册.服务发现.负载均衡.服务部署.服务发布等 ...

  • 微服务数据库设计与拆分

    嫉妒是人性,不因为嫉妒而失态乃至报复则是修养.我们无法压制人性但可以做到有教养.--周国平 请简洁描述 MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别? SQL 标准定义 ...