第四章、可编程网关设计实践
一、网关和BFF 演化过程
无线BFF,为前端开发的后端,主要由 前端团队开发。
BFF 可以认为是一种 代理适配服务,它可以将后端服务进行 聚合、适配、裁剪、 这样可以为无线设备提供设备友好,方便无线设备接入访问后端的服务。
架构的好处:
- 无线APP 和内部服务 不强耦合,通过BFF可以两边独立变化。
- 前后端业务发生变化,可以通过BFF 减少前后端沟通成本。
- 无线APP 只需要知道无线BFF 的域名,不需要知道内部服务域名,域名也只需要一个BFF的,域名开销比较小。
- 内部服务躲在无线BFF 后面,不会暴露在公网上,提高了安全性。
随着业务的增加,带来的问题如下:
- 无线BFF 的单块,堆砌了大量不同业务逻辑,变得越来越臃肿。
- 根据康威法则,单块的无线BFF 和多团队之间沟通成本变高,交付效率变低。
- 引入了很多 跨横切面 的逻辑(即cross cutting),如安全认证,日志监控,限流熔断等。
- 无线BFF 始终是一个适配单点,如果有一个流量洪峰,则有可能出现无线集群宕机等风险。
二、 解决无线BFF 问题
- 1.单块BFF 进行解耦拆分,针对不同业务线,引入 独立的BFF 集群
- 2.在内部内部BFF 之前,再引入一层 网关(gateway),网关专门负责跨横切面的功能。
好处:
- 独立BFF 解耦后,每个业务团队可以独立开发自己的BFF。
- 网关由独立的团队开发,专注跨横切面 的功能,如路由、认证鉴权、监控性能、调用链监控、限流熔断、防爬虫等。
当代互联网架构
服务器端 BFF 也可以看做一种特殊BFF 层,只是他输出的是HTML,不是Json 而已。
三、网关和反向代理的区别
背景: web1.0、2.0 早期时代,主要是以网站形式呈现出来,大多采用 前置反向代理,主要就是 反向代理和负载均衡,典型的有Ngix
、HA Proxy
,这些产品成熟稳定性能高,一般由运维团队管理。
如今: 如今进入微服务时代,对 路由配置、安全要求很高,这个时候就出现了很多矛盾,如传统反向代理不灵活,传统运维方式效率低下,
研发人员无法做到自配置,为了解决这些问题,网关就诞生了。网关主要面向微服务,可以提供更灵活的,由研发团队自配置的能力,Netflix zuul
就是这样的网关。
注意: 反向代理能做的,网关也能做,由此就有了两套,但是随着技术的发展,对网关要求更高,不仅要求 动态可配置,
而且要求动态可编程,所以面向 云原生 的产品,出现了很多 统一代理 的概念,如 envoy
, Traefik
四、网关该不该分集群部署
说明: 早期、网关和反向代理是分开的,微服务躲在网关后面,单页应用和Web 应用一般躲在反向代理后面,网关一般可以分集群部署,如H5网关、web APP网关等,这种部署架构相对来说比较复杂,反向代理和网关都有,维护成本高,如果反向代理和网关不在同一个域 中,还要解决 跨域 的问题。
统一网关部署:
为了解决上述分两套的网关的问题,采用统一网关,架构就比较简单,所有应用同于部署,没有跨域问题,只要应用在同一个根域下。
对于Web 、单页应该、微服务来说,他们也有一些差异化需求的,如网关统一错误处理,web错误一般是错误页面,api出错,一般是json 数据,
要不要分集群,主要看你公司业务大小,业务小不建议分集群,逐步规模之后建议是要分集群。
五、Faraday 网关内核设计
路由映射表,是关键,常见的有基于域名,或者基于HTTP 头,或者基于请求参数,我们的是基于域名的路由,所以映射表里存放的是HTTP 头,
和路由映射表对应的,还有一个 Http Client 映射表,它里面存放了service服务 和实际访问的 http client 的映射关系。
如果路由表有更新,则Http Client也会有更新
路由配置表,例如本地的一个路由配置表
第五章、网站安全架构
一、单块阶段
1、认证阶段
1.1 什么是认证和授权?
- 认证:识别你是谁, 英文叫 Authorization,在网站上识别某个用户是否是合法的用户。
- 授权:授权就是指你能做什么,能有什么权限。
1.2 认证阶段具体过程
- 传统认证: 通过 服务器端session + 浏览器端cookie 来实现。 那么服务器是怎么知道用户需要登录,或者说用户登录后不需要再登录呢?
- 答: 用户通过浏览器,输入用户名密码,查表后通过校验后,会在服务器端写一个session,会写一个session ID 和用户的记录(类似hashtable),之后服务器端会给客户端把这个 session ID 给返回,浏览器端会以cookie的形式,种到浏览器端。
2、访问阶段
2.1 访问阶段具体过程
-
登录完当用户要去访问这个网站时,浏览器会自动会把这个session ID 以cookie的形式,发送到后端,后端一旦能校验通过这个session,
则认为是登录后的用户,不需要重新登录,直到session过期。 其中session是可以存储一些用户信息的,如userId 等。 -
如果session过期,则会强制让用户登录退出,下次登录重新更新session的过期时间,如果用户长期不刷新页面,则session过期后也会让用户重新登录。
3、粘性会话
3.1 V1 版本上线后,有一些Bug 出现,具体表现为:
-
登录随意退出:莫名其妙用户退出登录,原因是因为session每次只存在于一台服务器上,后台是集群的形式,跳server则找不到session导致退出登录。
-
解决这个问题的方案,有一种手段是粘性会话,将用户的会话,黏住在某一台服务器。
3.2 粘性会话的问题:
-
1.稳定性问题: 服务器正常升级时,或者down机,一波用户的会话则会瞬间消失,必须重新登录,造成用户体验差
-
2.部分用户访问慢: 某些用户感觉有时候很慢,大多数用户觉得是挺快的,原因是后台访问觉得慢的用户,被黏在那台慢的服务器上而下不来。
4、如何解决粘性会话
4.1 如何来解决粘性会话带来的问题呢?
-
1.会话同步复制: 每一台机器上的会话,都会同步到其他服务器上,不好的是引入复杂的状态同步机制,扩展性变差。
-
2.无状态会话法: 会话session不存在服务器端,而存储在浏览器端,通过请求响应捎带来传递数据,不好的是cookie存在浏览器中是有风险的,一般需要加密,在一个cookie不能存储大数据,一般最大4K。
-
3.集中会话技术,如下图:
通过缓存Redis,将用户的会话存储在后台的一个Redis缓存中,好处是 LB 和 server集群都不用去存储会话,当需要session ID 时,只需要去Redis中去获取即可,这样server集群的水平扩展性提高了。
二、微服务阶段
1、微服务应用场景
2、微服务3.0认证体系
2.1 登录认证抽成一个独立的service,依赖独立的DB:
这个service独立承担如下职责:
- 登录认证
- 令牌颁发、令牌校验
- 会话管理
服务鉴权: 服务鉴权认证主要是使用了token作为校验,这个令牌是一个透明令牌,所谓透明令牌,就是一个随机的无异议的字符串,和一次会话相互关联,下次访问也可以通过这个令牌访问。
登录的整个流程:
- 1.用户通过某种平台登录,通过后,调用Auth Service,校验通过后在服务器上建立一个session(有过期时间),并生成令牌。
- 2.校验通过颁发令牌,拿到颁发好的令牌,将token令牌 种到客户端,根据不同平台,例如种到cookie中。
- 3.客户端使用token,去调用后端微服务。
- 4.后端微服务拿到token后去调用 Auth Service 校验Auth token是否合法。
- 5.校验token合法后,可以拿到一些user info的信息,去后台service做一些业务逻辑,如Auth 鉴权。
- 6.将处理好的业务逻辑的response 返回。
-
好处:
- 1.认证鉴权全部放到单独的 Auth Service,通过扩展后,还可以实现SSO (单点登录)
- 2.引入令牌,类似session ID
-
不好:
- 1.每个微服务,都要实现认证授权的功能,给开发方带来一定复杂性,不能让开发方很好的聚焦业务逻辑。
- 2.认证鉴权放到每个微服务中,开发不统一,不容易规范,容易出错。
3、解决3.0中问题,V3.5
引入网关 gateway 来解决上述问题,
3.1.认证授权集中在网关上做
- 网关可以截获令牌,并且集中到auth service上集中校验。
- 网关可以从Auth Service 上获取请求相关的 user info,再接着向后台转发,因为网关和微服务之间是相互信任的,微服务就不需要单独去Auth Service 上认证鉴权了。
不好处:
- 框架比较重,实现比较复杂。
- 对Auth Service 的压力比较大,每次认证授权都得过Auth Service。
4、轻量级 JWT 认证
Auth Service 的本质,还是一个集中状态认证架构,这种架构适合于大部分比较严格的微服务认证场景,这种框架的劣势是 Auth Service 的压力会比较大,很可能造成网站性能瓶颈。对于 安全要求不太高的场景,可以采用 JWT 令牌校验。
3.2.重构后的V3.6 架构
- JWT 不是一个透明令牌,它是自包含数据和签名信息的。
- 优化后,如第4步,网关不需要再去 Auth Service 做认证,因为JWT 自包含数据和签名,网关就只去解析这个JWT 令牌就可以了,不需要再去
Auth Service 中去认证再去拿 user info 等动作,从而减小了 Auth Service 的压力。
说明:总体是一种 高性能、可扩展 的认证架构,适用于安全要求不太高的场景。
5、 JWT 原理
概念: JWT 即 Json Web Token,它是 RFC7519 定义的一个开放标准,它定义了一个 紧凑的信息传输方式,通过他可以在多个系统间安全的传递信息,它是 可信任 的,主要用于 认证授权、信息交互。
结构: Header + Payload(消息体) + Signature(签名),中间使用 .
来区分
JWT 令牌是公开可见的,任何人拿到JWT 令牌,都可以去 jwt.io
上面去解密,看到其中内容,所以 JWT不能保证信息的保密性,
但是他可以 保证信息的 可依赖性 和 不可篡改性,类似现实生活中的支票签名。
6、JWT 的流程
6.1.HMAC 流程
注意: Auth Server 和 Resource Server(微服务)需要提前声明一个用于解签的 secret,必须严格保密。
- 1.用户通过client发送登录请求
- 2.Auth Server 校验通过后,生成JWT数据结构,使用 HMAC 算法 生成 JWT token,返回给客户端。
- 3.客户端将token存储起来,如cookie存储,在请求后台微服务,一般会带上这个JWT,调用后台service。
- 4.resource(后台service)在拿到这个token后通过声明好的secret 进行解签,拿到 JWT 信息后处理逻辑后返回数据到client。
6.2.RSA 流程
与HMAC 区别就在于,secret采用 RSA 公钥和私钥 这种签名算法(公私钥成对出现)
- Auth Server 使用 private key 私钥
- resource Server 使用 public key 公钥
注意: 只有在 Auth Server 上保存私钥,保密性好,公钥在 是公开的,resource server拿到公钥,最多可以做解签校验,不能够篡改,加签,相比来说,HMAC 比 RSA 要简单。
JWT 优劣###
-
好处:
-
- 紧凑轻量,尤其适合无线传输的场景。
-
- 对Auth Server 压力小。
-
- 简化Auth Server 的实现,微服务可以不用再Auth Server 上去校验令牌,因为他是自校验的。
-
-
不足:
-
- 无状态和吊销无法两全,比方说黑客在攻击,很难吊销他的JWT,只能等到令牌过期后吊销。假设Auth Server 上更新了令牌,老的令牌必须等到自然过期之后重新登录,才能用到新的令牌。
-
- JWT 内容大会 影响网络传输,过大会影响性能。
-
总结: JWT 更适合 安全不敏感 场景,而透明令牌(引用令牌)更适合 安全敏感场景
第六章、 微服务架构分层(Spring boot)
一、Spring boot 应用分层
1、服务层(Service层),service 和 domain 层两者共同实现业务逻辑
- 胖领域模型:业务逻辑主要包含在领域对象内(domain),服务层(service)只是作为和业务逻辑domain的一个协调器。
- 瘦领域模型: 业务逻辑主要在 service层内,而domain层只是一些状态字段等,不包含业务逻辑,也叫 平学领域模型。
胖瘦领域模型孰好孰坏,业界有争论。
2、数据持久层 Repository ,主要负责数据库对象存储逻辑,底层一般是 ORM 框架,如 hibernate
或 mybatis
,Repository 是 领域驱动设计( DDD 即 Domain-Driven Design
)的一种设计模式。
二、测试分类
1、组件测试
-
说明:集成测试、单元测试,都不能保证一个微服务的功能完整性,在微服务场景下,更多推荐组件测试。
-
组件测试:所谓组件测试,就是把一个微服务看成是一个独立的组件,而不去关心内部的细节,把他看成一个黑箱,仅对暴露的接口进行测试,一般来说我们需要把这个service依赖的外部 API全部mock掉,这样才能保证一个微服务的独立性。
微服务测试一般需要mock数据,常见的mock分为
- mock 数据分类:
- 内部mock:内部模块之间mock数据,如Repository mock数据等。
- 外部mock:mock一个微服务所依赖的外部数据。
2、端到端测试(End To End)
端到端测试:(End to End)所谓端到端测试,将整个系统看成一个黑盒子,一般通过其接口,如Api 对整体业务线做整体测试。
3、测试总结
三、测试金字塔
说明: 所谓 测试金字塔,就是说我们在某个测试环节所应关注的 关注度是多少
- 推荐多做 单元测试 和 集成测试, 原因和测试特性有关联,从上到下来看测试力度变细,越往下越稳定、越往下测试越快。
- 端到端测试: 建议力度放少,因为成本比较高,而且不稳定,好处是他的覆盖面比较广,实践上一般绕不开的,一定要去做。
注意: 不是每一种测试都要去追求力度,而是主要要遵循测试金字塔的力度指导。
四、灰度测试 + 生产监控
注意: 线下测试做的再多,也不能完全模拟线上,所以一般到了线上,我们一般要做 灰度测试 + 生产监控
- 灰度测试: 一部分新功能,让少量用户来测,如果测试过了我再切流量到 100%
- 生产监控: 监控线上环境,互联网应用一般认为是一种生产测试。
第七章、可运维架构生产实践
一、何谓生产就绪 Production Ready
1.1、传统经典编程过程
1.2、现代互联网交付过程
1.3、何谓生产就绪
说明:所谓生产就绪,就是在上线交付到客户手中,要完成如下部分:
- Metrics 监控: 如调用数、调用延迟、出错数、CPU指标
- 健康检查(healthy check),Nginx或者负载均衡器(LB)看到你不存活,就会把你拉出集群,保证用户体验。
- 调用链监控: 调用记录、谁调用你,你调用谁,也可以统计调用链性能问题。
- 安全性考量: 如用户下单、支付等,这些最起码得登录,还要有一点的安全check,权限校验等。
- 高可用考量: 一个实例挂,能不能提供另一个实例服务,一般无状态服务,是可以水平扩展的(HPA),有状态的服务,要考量主备机制。
- 扩展升级考量: 如流量上来了,能不能顺利扩展,增加一些实例,升级扩展要考虑上线是不是平滑的,升级的难易程度等,比如说我上线要灰度测试,蓝绿部署等。
1.4、有状态和无状态服务
-
无状态服务: 就是没有 特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息)
-
有状态服务: 与之相反, 有状态服务在服务端保留之前请求的信息, 用以处理当前请求,比如 session 等
典型的无状态服务的例子就是 http 协议。
有状态服务举例:
-
例如: 有状态服务,服务会存储请求上下文相关的数据信息,先后的 请求,是可以有关联 的。例如,要实现一种计数服务,每次请求都要对之前请求处理的数据结果进行+1 的操作,这就需要在服务端存储维护计数的数据,这样的服务就属于有状态的服务。
-
例如: 在Web 应用中,经常会使用 Session 来维系登录用户的上下文信息。 虽然http 协议是无状态的,但是 借助于Cookie 和Session,可以使 http 服务转换为有状态服务。
第九章、云原生(Cloud Native)
一、何谓云原生?
说明:云原生就是基于 微服务 原理而开发的应用,以 容器 云方式打包。在运行时,容器由运行于 云基础设施 之上的平台进行调度。应用开发采用 持续交付 和 Devops 实践。
- 应用要以微服务方式构建
- 微服务一开始就要面向容器云部署,通过如K8S等一键部署环境。
二、何谓:CI/CD?
- CI 即 持续集成,CD 即 持续交付 。
原文链接:https://www.cnblogs.com/vpersie2008/p/14449903.html
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/17701