日常工作中,难免会遇到临危受命的情况,虽然没有这么夸张,但是也可能会接到一个陌生的任务,也许只是对这个概念有所耳闻。也许这个时候会感到一丝的焦虑,生怕没法完成领导交给的测试任务。其实也没有必要那么紧张,面对一个陌生的被测对象,我们只需要去了解清楚它的应用场景、内部原理、实现逻辑,结合开发的设计需求,一样也能完成好测试任务,积累经验。这次就分享一些从0到1学习如何测试API网关的经验。
API网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部的客户端可能需要调用多个服务的接口才能完成一个业务需求,这个时候系统结构会显得非常错综复杂,会出现许多问题:
微服务网关是微服务架构中的一个关键角色,用来保护,增强和控制对于微服务的访问,微服务网关是一个处于应用程序或服务之前的系统,用来管理授权,访问控制和流量限制等,这样微服务就会被微服务网关保护起来对所有的调用者透明。因此,隐藏在微服务网关后面的业务系统就可以更加专注于业务本身。
Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Zuul,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
说到底predicate就是为了实现一组匹配规则,方便让请求过来找到对应的Route进行处理,而spring cloud gateway内置了几种predicate的使用。
1、通过时间匹配
Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。比如我们现在设置只有在 2018 年 1 月 20 日才会转发到我的网站,在这之前不进行转发,我就可以这样配置:
spring:
cloud:
gateway:
routes:
- id: time_route
uri: http://youknowit.com
predicates:
- After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
2、通过cookie匹配
Cookie Route Predicate 可以接收两个参数,一个是 Cookie name , 一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://youknowit.com
predicates:
- Cookie=youknowit, value
3、通过请求路径匹配
Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://x.x.x.x:8022/
predicates:
- Path=/foo/{segment}
如果请求路径符合要求,则此路由将匹配,例如:/foo/1或者/foo/bar。
当然内置的匹配规则还有很多,通过请求参数,请求方式,请求IP地址等去匹配,也可以组合使用。
注意:
一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
本次提测版本,开发使用spring-cloud-gateway来将平台业务侧引入网关, 将网关作为调用PaaS的唯一入口,便于维护,同时利用网关的能力实现限流,熔断,鉴权,灰度验证等功能。第一期只接入统一前装,充分验证后后续接入其他应用。因此,本次测试的重点在路由转发功能。
spring:
cloud:
gateway:
httpclient:
connect-timeout: 5000
response-timeout: 5s
ssl:
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0
handshake-timeout-millis: 10000
useInsecureTrustManager: true
routes:
# gis
- id: gis_route
predicates:
- Path=/gis/**
uri: http://x.x.x.x:8022/
知道了网关的基础知识和基本原理之后,对于我们如何测试它,作为一名测试人员心中已经有了大概的思路,接下来就是根据我们实际的需求去列出测试点,并进一步转换为用例去执行。从上面开发给出的配置能知道,此次开发提测主要是实现了基于路径匹配的路由转发功能,其余功能暂未引入,这样想来就简单了许多。
常见请求正常转发
API网关插件各个公司根据不同的需求有不同的插件,此次提测也没有涉及,所以收集整理了一些常见的通用插件,例如降级,限流,熔断,跨域,abtest插件等,提供一些测试思路。
基本概念: 客户端请求太多,超出了服务端的承受能力,导致服务端不可用或无法响应,耗尽服务端资源甚至是服务崩溃。解决方案:服务端对客户端进行限流,保护服务端资源。对各类请求设置最高的QPS阈值,当请求高于阈值时直接阻断。
限流插件测试思路:可以在API网关平台为对应测试接口配置限流策略。根据不同时间,使用压测工具进行阶段性的压力测试,并统计阻断接口数,具体的数值可以根据自身业务场景进行测试。
基本概念:服务降级是指当服务器压力剧增的情况下,根据实际业务情况,将一些不重要的接口换种简单的方式处理,从而将服务器资源释放给当前的核心业务使其可以高效运作。
降级插件测试思路:降级策略主要看开发如何选择,有的就是让请求无法访问到后端服务,借口暂停使用,当接口配置降级插件。插件开关打开,返回API网关所配置的响应信息状态码等,接口是无法真正的请求到后端服务。
基本概念: 微服务架构中,各个微服务之间相互依赖非常普遍,因此在整个链路中 ,有一个环节出现问题,都会造成整个上下游服务调用出现问题,服务出现宕机。也就是说,熔断就是调用方发起服务调用时,如果被调用方返回的错误率超过一定的阈值,那么后续的请求不会真正发起请求,而是调用方直接返回错误。两个关键点,判断何时熔断和何时从熔断状态恢复。
熔断插件测试思路: 不同的网关有不同的熔断策略,例如针对5xx的返回,根据不同的入参控制返回,可返回2xx,4xx,5xx,当规定的时间5xx数达到阈值,服务是否开启熔断。熔断恢复测试也是一样,比如10s,允许部分请求通过,你可以继续控制请求,若这部分请求都成功,恢复熔断。具体的case设计还是要根据自身业务为准。
基本概念: 跨域是指,只要协议,域名,端口有任何一个不相同,都被当作是不同的域。所谓同源策略就是指,协议,域名和端口都要相同,其中有一个不同都会产生跨域。
跨域测试思路: CORS是一种基于HTTP头的机制,该机制通过允许服务器标识除了自己以外的其他origin,这样浏览器可以访问加载这些资源。浏览器必须首先使用OPTIONS方法发起一个预检请求,从而获知服务端是否允许该垮源请求。服务器允许之后,才发起实际的HTTP请求。在预检请求的返回中,服务端也可以通知客户端,是否需要携带身份凭证。测试时,我们就可以通过是否需要携带参数,身份凭证等;各种参数组合,不同请求等方面去设计case。
注意: 数据库down,因为有本地缓存,验证本地缓存是否生效,所以数据库重启或者down掉,不能影响已经生效的路由和插件;后端服务down掉一台,验证eureka是否有将死掉的节点删除,若eureka并没有将死掉的节点删除,则会报错。添加新的节点,需要看请求是否有轮询;redis主要用于限流,在redis down掉限流策略失效,但是其他插件功能及路由应该不受影响;eureka是注册中心,注册中心在启动的时候会将所有资源加载本地,所以eureka挂一台或者多台,不影响已经加载到本地的。总上所述,总结来说就是API网关的所有依赖都可以down,但是gateway不可以不用。
注意: 项目资源的作用是进行线程隔离,每个项目资源分配应该是固定的,不能抢占其他项目资源而导致其他服务不可用,进行负载测试时,增加压力,增加和减少后端服务节点,请求应该不报错。
上述内容,是对一些网关通用功能的测试思路总结。由于本次开发提测网关版本并没有涉及过多的功能,例如还有集群的热加载,插件在集群项目与API间的运用,API的发布,下线,插件的随时切换,监控等需求,亲身实践还不够,只能提供一些思路,还需要具体结合项目的业务进行更为准确的case设计。