有一些微服务可能放置于防火墙后或其他访问限制,直接访问会不可达
所以出现了API网关,它是介于客户端和服务端之间的桥梁,所有外部请求都会先给过网关层再路由到相应的微服务进行处理,根据这一特性我们一般会在网关层用来处理安全,性能,监控等通用的功能等,而不会用来处理业务逻辑.
网关的优势及选型
网关技术选型
下面我们主要以spring cloud gateway为例来讲网关.
Spring cloud gateway包含spring 5,spring boot 2,project reactor,它提供一种简单有效的路由转发请求,并提供横切关注点,如安全性,监控/指标和弹性等,它的特性如下:
spring cloud gateway重要概念
实践:
application.yaml
server:
port: ${port:8180}
ipAddr: ${ipAddr:127.0.0.1}
spring:
zipkin:
base-url: http://127.0.0.1:9411
discovery-client-enabled: false #
sleuth:
sampler:
probability: 1.0 #采样百分比 range[0.1~1.0]
application:
name: service-gateway
cloud:
gateway:
discovery:
locator:
enabled: true
lowerCaseServiceId: true
# lower-case-service-id: true
routes:
- id: service_product
uri: lb://service-product
order: 1 #数字越小,越先执行,即优先级越高
predicates:
- Path=/api/product/**
filters:
- StripPrefix=1
- id: service_order
uri: lb://service-order
order: 1 #数字越小,越先执行,即优先级越高
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
globalcors:
cors-configurations:
‘[/**]‘:
allow-credentials: true #允许携带认证信息
allowed-origins: #允许跨域的源(域名和IP),设置*为全部
- ‘*‘
allowed-headers: ‘*‘ # 允许跨域请求里的header字段,*为全部
allowed-methods: #允许跨域的方法
- GET
- POST
- OPTIONS
max-age: 3600 # 跨域允许的有效期
nacos:
discovery:
server-addr: ${server.ipAddr}:8848
namespace: 31885c53-49eb-4031-9450-89e78cfb48fa
logging:
level:
root: info
# pattern:
# console: ‘[%-5level] %clr(%d{HH:mm:ss}){cyan} %logger - %clr(%msg){green} [%clr(%thread{20}){cyan}]%n‘
上述配置文件包括应用名称,端口号以及注册中心的配置和配置中心的配置,跨域请求配置.日志打印级别及控制台打印格式,还可以指定日志文件存储等,最核心的是路由的配置.注意uri是使用lb:// 这里使用了负载均衡.
我们还会在代码中实现一个token过滤器,代码片段如下:
@Value("${auth.skip.urls:skip urls not config yet}")
private String[] skipAuthUrls; //忽略验证的urls
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath().trim();
Assert.notEmpty(skipAuthUrls, "skip auth urls is not null");
//如果当前路径不需要验证就放行
if (Stream.of(skipAuthUrls).anyMatch(url -> url.equalsIgnoreCase(path.trim()))) {
log.debug("{} 不需要鉴权,its order {}", path.trim(), getOrder());
return chain.filter(exchange);
}
//TODO 获取客户端 传来的token信息进行安全鉴定
//TODO 比如使用token去redis里查看是否过期,是否在黑名单 中等
//TODO 验证通过后走过滤器链即可
//TODO 验证未通过 直接返回客户端 相应的提示信息
return chain.filter(exchange);
}
/**
* Get the order value of this object.
* <p>Higher values are interpreted as lower priority. As a consequence,
* the object with the lowest value has the highest priority (somewhat
* analogous to Servlet {@code load-on-startup} values).
* <p>Same order values will result in arbitrary sort positions for the
* affected objects.
*
* @return the order value
* @see #HIGHEST_PRECEDENCE
* @see #LOWEST_PRECEDENCE
*/
@Override
public int getOrder() {
return -100;
}
以上代码片段处理了需要跳过鉴权的url,比如 注册,登录等
还通过Order接口指定了执行的顺序,这里的Order,数字越小,优先级越高.
以及鉴权过程,这里为了脱敏只写了TODO 提示.
完整代码 请参照github.com/gisonwin
原文:https://blog.51cto.com/8745668/2491035