gateway在微服务中起到路由网关的作用
配置
pom引包
会和spring-boot-starter-web
和spring-boot-starter-actuator
起冲突,所以需要去掉这两个包
<!--新增gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
pom完整内容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.hao.springcloud</groupId>
<artifactId>cloud-gateway-gateway9527</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--新增gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主启动类
package com.hao.springcloud.cloudgatewaygateway9527;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class CloudGatewayGateway9527Application {
public static void main(String[] args) {
SpringApplication.run(CloudGatewayGateway9527Application.class, args);
}
}
一、路由——Route
路由网关配置分两种,一种是加载bean配置;一种是yml配置
方式一:yml文件配置
server:
port: 9527
spring:
application:
#服务名
name: cloud-gateway
cloud:
#注册中心
nacos:
discovery:
###服务注册地址
server-addr: localhost:8848
#网关配置
gateway:
routes:
- id: payment_hystrix #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/hystrix/** #断言,路径相匹配的进行路由。注意是Path的P是大写
#可以配置多个路由指定不同的服务
- id: news_baidu
uri: http://news.baidu.com
predicates:
- Path=/**
方式二:bean配置(yml文件中nacos配置还是需要)
package com.hao.springcloud.cloudgatewaygateway9527.config;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.PredicateSpec;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.function.Function;
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
/*lambda表达式*/
routes.route("payment_hystrix",
r -> r.path("/payment/hystrix/**").uri("http://localhost:8001")).build();
routes.route("news_baidu", new Function<PredicateSpec, Route.AsyncBuilder>() {
@Override
public Route.AsyncBuilder apply(PredicateSpec predicateSpec) {
return predicateSpec.path("/**").uri("http://news.baidu.com");
}
}).build();
return routes.build();
}
}
效果:
通过注册中心配置服务名的方式配置路由网关
lb://serviceName是spring cloud gateway在微服务中自动为我们创建的负载均衡uri
server:
port: 9527
spring:
application:
#服务名
name: cloud-gateway
cloud:
#注册中心
nacos:
discovery:
###服务注册地址
server-addr: liguanghao.top:8848
#网关
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: cloud-payment-service #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #通过注册中心找到的8001的服务名。lb:负载均衡
predicates:
- Path=/payment/hystrix/** #断言,路径相匹配的进行路由
二、断言——Predicate
断言Predicate
的几种使用:
一、After Route Predicate
配置从什么时间之后才可以访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
# 2020年3月8号10:59:34之后才可访问
二、2.Before Route Predicate
配置什么时间之前才可以访问,超过此时间不可访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
# 2020年3月8号10:59:34之前可以访问,超过之后禁止访问
三、Between Route Predicate
配置可访问的时间区间
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-09T10:59:34.102+08:00[Asia/Shanghai]
# 2020年3月8号10:59:34-2020年3月9号10:59:34之间可访问
四、Cookie Route Predicate
Cookie 中携带指定的参数和值,才可访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Cookie=username,zzyy
# Cookie中必须有username参数,并且值为zzyy
测试
不带cookie或者带username但值不对访问都失败;带cokkie且值正常才访问成功
配置多条Cookie:
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Cookie=username,zzyy
- Cookie=token,aabb
五、Header Route Predicate
请求头中携带指定的参数,值可以通过正则表达是配置。才可访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Header=X-Request-Id, \d+
#请求头中要有X-Request-Id属性并且值为整数的正则表达式
六、Host Route Predicate
host中携带指定的参数才可访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Host=**.hao.com
七、Method Route Predicate
指定方法的请求方式,符合才可访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Method=GET
八、Query Route Predicate
请求参数的方法中要有指定的入参和正则表达式配置的值才可访问
routes:
- id: cloud-payment-service
uri: lb://cloud-payment-service
predicates:
- Query=userId, \d+ #要有参数名称并且值是正整数才能路由
#如:localhost:9527/getUser?userId=30
九、Path Route Predicate
符合指定路径才可访问
routes:
- id: cloud-payment-service #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: lb://cloud-payment-service #通过注册中心找到的8001的服务名
predicates:
- Path=/payment/hystrix/** #断言,路径相匹配的进行路由
三、过滤——Filter
gateway本身携带的filter
自定义filter
主要实现两个接口GlobalFilter
和Ordered
package com.hao.springcloud.cloudgatewaygateway9527.filter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter , Ordered{
/**
* 设置过滤条件
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("*********come in MyLogGateWayFilter: "+new Date());
//设置参数中必须含有token参数
String token = exchange.getRequest().getQueryParams().getFirst("token");
if(StringUtils.isEmpty(token)){
log.info("*****用户名为Null 非法用户,(┬_┬)");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//给人家一个回应
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 设置过滤器优先级
* @return
*/
@Override
public int getOrder() {
return 0;
}
}