API网关与链路追踪
一 微服务网关
Api网关是一个服务器,是系统对外的唯一入口,API网关封装系统内部架构,为每个客户端提供了一个定制的API。API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问的API。服务端通过API-GW注册和管理服务
1.1 基于Nginx的微服务网关
1.1.1 Nginx介绍
Nginx(客户端负载均衡)是一段自由的,开源的、高性能的HTTP服务器和反向代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现
1.1.2 Nginx提到的正向/反向
正向代理
它代理的是客户端,代客户端发出请求,是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并制定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端,客户端必须要进行一些特别的设置才能使用正向代理
反向代理
请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,此时Nginx扮演的就是一个反向代理角色。客户端是无感知代理的存在的,反向代理对外都是透 明的,访问者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。反向代 理,"它代理的是服务端,代服务端接收请求",主要用于服务器集群分布式部署的情况下,反向代理隐 藏了服务器的信息
1.1.3 具体实现中重点注意⚠️
- 增减一个nginx的配置文件中的location属性
eg:
location /api-order {
proxy_pass http://127.0.0.1:9001/;
}
location /api-product {
proxy_pass http://127.0.0.1:9002/;
}
将URL换成你微服务地址
1.2 基于Zuul的微服务网关
1.2.1 相关概念
1.2.1.1 Zuul是个啥?
ZUUL是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,Zuul组件的 核心是一系列的过滤器
1.2.1.2 过滤器功能是啥?
- 动态路由:动态将请求路由到不同后端集群
- 压力测试:逐渐增加指向集群的流量,以了解性能 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
- 静态响应处理:边缘位置进行响应,避免转发到内部集群
- 身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求。
1.2.2 搭建Zuul网关服务器注意事项
- 使用@EnableZuulProxy开启Zuul网关功能
- 配置文件中的配置
server:
port: 8080 #服务端口
spring:
application:
name: api-gateway #指定服务名
1.2.3 Zuul网关中的路由转发
1.2.3.1 路由
“路由”是指根据请求URL,将请求分配到对应的处理程序。在微服务体系中,Zuul负责接收所有的请求。根据不同的URL匹配规则,将不同的请求转发到不同的微服务处理。
1.2.3.2 面向服务路由(与Eureka集成)
1.2.3.2.1 概念
Zuul支持与Eureka整合开发,根据ServiceID自动的从注册中心中获取服务地址并转发请求,这样做的 好处不仅可以通过单个端点来访问应用的所有服务,而且在添加或移除服务实例的时候不用修改Zuul的 路由配置。
1.2.3.2.1 实现步骤
(1)添加Eureka客户端依赖
(2)开启Eureka客户端发现功能
(3)添加Eureka配置,获取服务信息
(4)修改映射配置,通过服务名称获取
简化的路由配置
配置语法:zuul.routes.=
默认的路由规则
默认情况下,一切服务的映射路径就是服务名本身。
例如服务名为 shop-service-product: ,则默认的映射路径就是/shop-service-product/**
1.2.3.3 zuul加入后的架构图
1.2.4 Zuul网关的过滤器
1.2.4.1 作用
过滤器功能则负责对请求的处 理过程进行干预,是实现请求校验、服务聚合等功能的基础。
1.2.4.2 过滤器简介
Zuul 中的过滤器总共有 4 种类型,且每种类型都有对 应的使用场景。
1. PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请 求的微服务、记录调试信息等。
2. ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用 Apache HttpClient或Netfilx Ribbon请求微服务。
3. POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
4. ERROR:在其他阶段发生错误时执行该过滤器。
1.2.4.3 过滤器的实现
Zuul提供了自定义过滤器的功能实现起来也十分简单,只需要编写一个类去实现zuul提供的接口。
接口包含的方法:
1、shouldFilter :返回一个 Boolean 值,判断该过滤器是否需要执行。返回true执行,返回false
不执行。
2、run :过滤器的具体业务逻辑。
3、filterType :返回字符串,代表过滤器的类型。包含以下4种:
pre :请求在被路由之前执行
routing :在路由请求时调用
post :在routing和errror过滤器之后调用
error :处理请求时发生错误调用
4、filterOrder :通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。
1.2.5 搭Zuul网关存在的问题
- Zuul1x版本本质上就是一个同步Servlet,采用多线程阻塞模型进行请求转发
- 不支持任何长连接,如websocket
1.3基于GateWay的微服务网关
1.3.1 Gateway基础
1.3.1.1 Gateway简介
1.3.1.1.1 Gateway是个啥
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开 发的网关,旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式,统一访问接口。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 Netflix ZUUL,其不仅提供统一的路 由方式,并且基于 Filter 链的方式提供了网关基本的功能;
1.3.1.1.1 Gateway中相关名词解释
- 路由(route) 路由是网关最基础的部分,路由信息由一个ID、一个目的URL、一组断言工厂和一 组Filter组成。如果断言为真,则说明请求URL和配置的路由匹配。
- 断言(predicates) Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是 Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定 义匹配来自Http Request中的任何信息,比如请求头和参数等。
- 过滤器(filter) 一个标准的Spring webFilter,Spring Cloud Gateway中的Filter分为两种类型, 分别是Gateway Filter和Global Filter。过滤器Filter可以对请求和响应进行处理
1.3.1.2 入门案例
1.3.1.2.1 入门案例
- 入门案例的配置文件中编辑内容
server:
port: 8080 #服务端口
spring:
application:
name: api-gateway #指定服务名 cloud:
gateway:
routes:
- id: product-service
uri: http://127.0.0.1:9002
predicates:
- Path=/product/**
1.3.1.2.1 路由规则
在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件 匹配到对应的路由。
1.3.1.2.1 动态路由
将gateway注册到eureka注册中心,然后修改配置文件,将原先的uri配置中,替换为lb://微服务名称
demo:
server:
port: 8080 #服务端口
spring:
application:
name: api-gateway #指定服务名 cloud:
gateway:
routes:
- id: product-service
uri: lb://shop-service-product
predicates:
- Path=/product/**
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/ registry-fetch- interval-seconds: 5 # 获取服务列表的周期:5s
instance:
preferIpAddress: true
ip-address: 127.0.0.1
1.3.1.2.1 重写转发路径
- 修改 application.yml ,将匹配路径改为 /product-service/**
- 修改配置文件
添加:RewritePath=/product-service/(?.*), /${segment}
spring:
application:
name: api-gateway #指定服务名 cloud:
gateway:
routes:
- id: product-service
uri: lb://shop-service-product
predicates:
- Path=/product-service/**
filters:
- RewritePath=/product-service/(?<segment>.*), /$\{segment}
1.3.1.3 过滤器
1.3.1.3.1 基础
(1)过滤器的生命周期
只有两个:“pre” 和 “post”。
1. PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择 请求的微服务、记录调试信息等。
2. POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等
(2) 过滤器类型
1. 局部过滤器
应用到单个路由或者一个分组的路由上。
是针对单个路由的过滤器。可以对访问的URL过滤,进行切面处理
2. 全局过滤器
应用到所有的路由上。
通过全局过滤器可以实现对权限的统一校验,安全性验证等功 能,并且全局过滤器也是程序员使用比较多的过滤器。
1.3.1.3.1 高级
统一鉴权
1. 鉴权逻辑
1、当客户端第一次请求服务时,服务端对用户进行信息
2、认证(登录) 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证
3、以后每次请求,客户端都携带认证的token
4、服务端对token进行解密,判断是否有效
3. 代码实现
1. 自定义全局过滤器需要实现GlobalFilter和Ordered接口。
2. 在filter方法中完成过滤器的逻辑判断处理
3. 在getOrder方法指定此过滤器的优先级,返回值越大级别越低
4. ServerWebExchange 就相当于当前请求和响应的上下文,存放着重要的请求-响应属性、请求实 例和响应实例等等。一个请求中的request,response都可以通过ServerWebExchange 获取
5. 调用 chain.filter 继续向下游执行
网关限流
常见的限流算法
计数器
漏桶算法
令牌桶算法
基于Filter的限流实现
(1) 环境搭建
(2) 修改application.yml配置文件
(3) 配置KeyResolver
基于Sentinel的限流
(1)环境搭建
(2) 编写配置类
(3)网关配置
(4)自定义异常提示
当触发限流后页面显示的是Blocked by Sentinel: FlowException。为了展示更加友好的限流提示,Sentinel支持自定义异常处理
(5) 参数限流
(6) 自定义API分组
1.3.2 Gateway的核心处理流程
Spring Cloud Gateway 核心处理流程,Gateway的客户端向 Spring Cloud Gateway 发 送请求,请求首先被 HttpWebHandlerAdapter 进行提取组装成网关上下文,然后网关的上下文会传递 到 DispatcherHandler 。 DispatcherHandler 是所有请求的分发处理器, DispatcherHandler 主要 负责分发请求对应的处理器。比如请求分发到对应的 RoutePredicateHandlerMapping (路由断言处 理映射器)。路由断言处理映射器主要作用用于路由查找,以及找到路由后返回对应的
FilterWebHandler 。 FilterWebHandler 主要负责组装Filter链并调用Filter执行一系列的Filter处理, 然后再把请求转到后端对应的代理服务处理,处理完毕之后将Response返回到Gateway客户端
1.4微服务网关的高可用
网关高可用
高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计 减少系统不能提供服务的时间。我们都知道,单点是系统高可用的大敌,单点往往是系统高可用最大的 风险和敌人,应该尽量在系统设计的过程中避免单点。方法论上,高可用保证的原则是“集群化”,或者 叫“冗余”:只有一个单点,挂了服务会受影响;如果有冗余备份,挂了还有其他backup能够顶上。
二 链路追踪
1.1 是个啥
分布式链路追踪(Distributed Tracing),就是将一次分布式请求还原成调用链路,进行日志记录,性 能监控并将 一次分布式请求的调用情况集中展示。比如各个服务节点上的耗时、请求具体到达哪台机器 上、每个服务节点的请求状态等等
1.2 常见的链路追踪系统
底层都是基于google发表的Dapper
- Zipkin
- 鹰眼
- Mtrace
- Cat
1.3 常用的链路追踪涉及技术
1.3.1 Sleuth
1.3.1.1 简介
主要功能就是在分布式系统中提供追踪解决方案,并且兼容支持了 zipkin,你只 需要在pom文件中引入相应的依赖即可。
1.3.1.2 相关概念
Span:基本工作单元 ==》spanId
Trace:一系列spans组成的一个树状结构 =〉traceId
Annotation:用来及时记录一个事件的存在
1.3.1.3 链路追踪sleuth入门
配置文件配置
logging:
level:
root: INFO
org.springframework.web.servlet.DispatcherServlet: DEBUG
org.springframework.cloud.sleuth: DEBUG
由于看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,通过Zipkin可以将日 志聚合,并进行可视化展示和全文检索。
1.3.2 Zipkin
1.3.2.1 Zipkin概述
Zipkin 是 Twitter 的一个开源项目,它基于 Google Dapper 实现,它致力于收集服务的定时数据,以 解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。 我们可以使用它来收集各个服务 器上请求链路的跟踪数据,并通过它提供的 REST API 接口来辅助我们查询跟踪数据以实现对分布式系 统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发 的 API 接口之外,它也提供了方便的 UI 组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,
1.3.2.2 Zipkin核心组件
1、Collector:收集器组件,它主要用于处理从外部系统发送过来的跟踪信息,将这些信息转换为 Zipkin 内部处理的 Span 格式,以支持后续的存储、分析、展示等功能。
2、Storage:存储组件,它主要对处理收集器接收到的跟踪信息,默认会将这些信息存储在内存中, 我们也可以修改此存储策略,通过使用其他存储组件将跟踪信息存储到数据库中。
3、RESTful API:API 组件,它主要用来提供外部访问接口。比如给客户端展示跟踪信息,或是外接 系统访问以实现监控等。
4、Web UI:UI 组件,基于 API 组件实现的上层应用。通过 UI 组件用户可以方便而有直观地查询和 分析跟踪信息。
Zipkin 分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务的应用
1.3.2.3 ZipkinServer部署与配置
要点
- 启动命令:在命令行输入 java -jar zipkin-server-2.12.9-exec.jar 启动 Zipkin Server
- 默认端口: 默认Zipkin Server的请求端口为 9411
1.3.2.2 Zipkin+sleuth整合
V1.0 基础
要点:配置文件的修改
zipkin:
base-url: http://127.0.0.1:9411/ #zipkin server的请求地址 sender:
type: web #请求方式,默认以http的方式向zipkin server发送追踪数据 sleuth:
sampler:
probability: 1.0 #采样的百分比
V2.0 将得到的信息保存到数据库中
要点: 启动命令
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql –
MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=12345678
V3.0 在zipkin客户端与zipkin服务端中间加一个消息中间件
将客户端发送的信息,先暂存到消息中间件红,然后当服务端启动后,会自动去拉取消息中间件中的相关消息
要点:使用前需要先将服务端启动,以至于能够在ribbitMQ中创建一个队列
启动命令:java -jar zipkin-server-2.12.9-exec.jar --RABBIT_ADDRESSES=127.0.0.1:5672