api网关是应用程序接口网关,在微服务架构中有许多微服务,通过api网关为用户提供一致服务
搭建网关的好处:
1、可以对外提供一致的调用接口,简化客户端调用。
2、可以将多个微服务的调用进行聚合,减少客户端请求。
3、网关对外部和内部进行了隔离,保障了后台服务的安全。
4、减少客户端和服务的耦合
5、方便进行应用层面的扩展
网关的功能:
1、性能:api接口高可用,负载均衡,容错机制。
2、搭配安全框架:权限身份认证,后端签名(保证后端可信调用),黑名单(非法调用)
3、记录日志:分布式全链路跟踪
4、监控功能:记录请求响应的数据,api接口的耗时分析,性能监控
5、限流功能:进行流量控制,定义多种限流规则。
6、路由功能:动态路由规则
网关和Nginx搭配使用:
1、前端页面调用接口请求Nginx服务器,如果是静态资源,则返回Nginx上缓存的资源
2、Nginx负载均衡调用后端的网关(网关服务多台部署,高可用)
3、网关做身份验证,服务路由,日志记录等等操作,
4、网关调用业务接口后,返回业务数据到页面。
Spring cloud gateway和zuul比较:
Spring cloud gateway:是spring-cloud-gateway-core包下的,基于springboot2.x响应式的,非阻塞式的api,支持websocket
zuul:是spring-cloud-netflix-zuul包下的,使用的是阻塞式的 API,不支持 websockets长连接。
搭建api网关步骤:
1、引入pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2、配置文件添加
#logger
logging.level.org.springframework.cloud.gateway = debug
#routes
#路由的id,参数配置不要重复,如不配置,gateway会使用生成一个uuid代替。
spring.cloud.gateway.routes[0].id=sumengnan
#路由的目标地址。注意:uri地址后面不要加 " / "
spring.cloud.gateway.routes[0].uri=http://192.168.1.12
#断言(判断)满足条件再转发。有以下几种转发方式:
#1、Path路径方式匹配转发。只有路径相同才被转发,可以使用*通配符,如:Path=/getUser,只有/getUser路径的请求被转发
#1、Before方式匹配转发。某一个时间点之前允许访问,过时后则不允许转发。如:Before=2019-05-01T00:00:00+08:00[Asia/Shanghai]
#2、After方式匹配转发。和上面正好相反。
#3、Between方式匹配转发。上面组合也以完成。例如:Between=2019-04-29T00:00:00+08:00[Asia/Shanghai], 2019-05-01T00:00:00+08:00[Asia/Shanghai]
#4、Cookie方式匹配转发。根据Cookie值的方式匹配转发。如:Cookie=sessionid, sumengnan,访问时携带"sessionid=sumengnan"Cookie信息的请求会被转发
#5、Header方式匹配转发。
#6、Host方式匹配转发。如:Host=**.sumengnan.com
#7、请求方式方式匹配。如:Method=POST,则只允许post请求被转发
#8、请求参数方式匹配。如:Query=user,sumengnan,则只有参数user的值为sumengnan时才允许转发
spring.cloud.gateway.routes[0].predicates[0]=Path=/get
#过滤器,具体参考下面的“api网关之过滤器详细”
#spring.cloud.gateway.routes[0].filters[0]=SetPath=/get
到此简单的网关就配置好了。如果需要eureka和负载均衡就继续。
整合Eureka和负载均衡
1、引入pom
<!-- eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!-- 负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2、配置文件添加
#eureka
spring.application.name=gateway
#注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
#把路由地址改成服务名
spring.cloud.gateway.routes[0].uri=lb://sumengnan
3、在启动类中定义负载均衡规则(可省略,默认为轮询规则)
@Bean//负载均衡的规则,下面的是其中之一:随机,还有权重,轮询等
public IRule initIRule() {
return new RandomRule();
}
api网关之断言详细:
api网关之过滤器详细:
作用:过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。过滤器可以限定作用在某些特定请求路径上。
类别:根据作用范围划分为GatewayFilter(网关过滤器)和GlobalFilter(全局过滤器),如下:
一、GatewayFilter(网关过滤器) : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上
Spring Cloud Gateway包含许多内置的GatewayFilter工厂。
觉得这些不够用?可以
1、自定义过滤器,需实现GatewayFilter和 Ordered接口(此处省略代码,和下面的GlobalFilter全局过滤器类似,可供参考,缺点就是只能在代码中使用f.filter()配置,不能在配置文件中配置)
2、自定义过滤器工厂,继承AbstractGatewayFilterFactory抽象类(实现了顶级接口GatewayFilterFactory)(可以在配置文件中配置)
自定义过滤器工厂步骤:
1、创建类继承AbstractGatewayFilterFactory
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
private static final Log log = LogFactory.getLog(MyGatewayGatewayFilter.class);
private static final String KEY = "param";
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(KEY);
}
public MyGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
//逻辑
})
);
};
}
//用来接收配置文件的参数
public static class Config {
private boolean param;
public boolean isParam() {
return param;
}
public void setParam(boolean param) {
this.param= param;
}
}
}
2、在启动类中注册
@Bean
public MyGatewayFilterFactory myGatewayFilterFactory() {
return new MyGatewayFilterFactory();
}
3、在配置文件中配置:spring.cloud.gateway.routes[0].filters[0]=My=true
二、GlobalFilter (全局过滤器): 不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。
Spring Cloud Gateway框架内置的GlobalFilter如下:
觉得这些不够用?,也可以自定义全局过滤器。例如token判断,需实现GlobalFilter和 Ordered接口
步骤:
1、创建一个类实现GlobalFilter和 Ordered接口。
public class TokenFilter implements GlobalFilter, Ordered {
Logger logger=LoggerFactory.getLogger( TokenFilter.class );
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (token == null || token.isEmpty()) {
logger.info( "token是空的..." );
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
//设定优先级别,值越大则优先级越低。
@Override
public int getOrder() {
return 0;
}
}
2、在启动类中添加
@Bean
public TokenFilter tokenFilter(){
return new TokenFilter();
}
3、完毕