2、安装依赖
注:不要安装spring-boot-starter-web依赖
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
3、主启动类
@SpringBootApplication
public class GatewayServerSampleApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServerSampleApplication.class, args);
}
}
4、bootstrap.yml配置网关
其中-id为路由Id;uri为转发的服务名称,也可以写成http://localhost:9090等;predicates为断言,即路由跳转时进行判断
server:
port: 8083 # 程序端口号
spring:
application:
name: gateway-server-sample # 应用名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*" # 允许的来源,*表示所有
allowedMethods: "*" # 允许的请求方式 *表示所有
allowedHeaders: "*" # 允许请求头 * 表示所有
httpclient:
connect-timeout: 5000 # 建立连接所用的时间 单位:毫秒
response-timeout: 4s # #建立连接后从服务器读取到可用资源所用的时间
discovery:
locator:
enabled: true
routes: #路由,可配置多个
- id: user_route # 路由id 唯一即可,默认是UUID
uri: lb://user-server-sample # 匹配成功后提供的服务的地址
order: 1 # 路由优先级,数值越小优先级越高,默认0
predicates:
- Path=/user/** # 断言,路径匹配进行路由
filters:
- User=0,1000
# - RedirectTo=302,http://localhost:8082//shop/findById?id=1
# - AddRequestParameter=id,1
- id: shop_route # 路由id 唯一即可,默认是UUID
uri: lb://shop-server-sample # 匹配成功后提供的服务的地址
order: 1 # 路由优先级,数值越小优先级越高,默认0
predicates:
- Path=/shop/** # 断言,路径匹配进行路由
至此大功告成
二、添加sentinel限流
1、安装依赖
com.alibaba.csp
sentinel-spring-cloud-gateway-adapter
2、路由维度进行限流
对应的是路由Id,新建SentinelRouteConfiguration类
package com.springcloudalibaba.gateway.conf;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.*;
@Configuration // 标记为配置类
public class SentinelRouteConfiguration {
private final List viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public SentinelRouteConfiguration(ObjectProvider> viewResolversProvider, // 构造函数
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@PostConstruct
public void initGatewayRules() { //初始化限流规则
Set rules = new HashSet<>();
GatewayFlowRule gatewayFlowRule = new GatewayFlowRule("user_route");// 资源名称,对应routeId的值 此处限流用户服务
gatewayFlowRule.setCount(1); // 限流阀值
gatewayFlowRule.setIntervalSec(1); // 统计时间窗口(单位:秒),默认是1秒
rules.add(gatewayFlowRule);
GatewayRuleManager.loadRules(rules); // 载入规则
}
@PostConstruct
public void initBlockHandlers() { // 自定义限流后的界面
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map result = new HashMap<>(); // 限流提示
result.put("code", "0");
result.put("message", "您已被限流");
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON_UTF8).
body(BodyInserters.fromObject(result));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { // 配置限流异常处理器
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() { //初始化一个限流的过滤器
return new SentinelGatewayFilter();
}
}
3、api维度进行限流
对应的是具体接口,新建SentinelApiGroupConfiguration类
package com.springcloudalibaba.gateway.conf;
import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.*;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.*;
@Configuration // 标记为配置类
public class SentinelApiGroupConfiguration {
private final List viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public SentinelApiGroupConfiguration(ObjectProvider> viewResolversProvider, // 构造函数
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@PostConstruct
public void initGatewayRules() {// 初始化限流规则
Set rules = new HashSet<>();
GatewayFlowRule gatewayFlowRule = new GatewayFlowRule("user_api");
gatewayFlowRule.setCount(1); // 限流阀值
gatewayFlowRule.setIntervalSec(1); // 统计时间窗口(单位:秒),默认是1秒
rules.add(gatewayFlowRule);
GatewayRuleManager.loadRules(rules); // 载入规则
}
@PostConstruct
public void initCustomizedApis() { // 自定义API分组
Set apiDefinitions = new HashSet<>();
ApiDefinition apiDefinition = new ApiDefinition("user_api") // user_api是api分组名称
.setPredicateItems(new HashSet() {
{
add(new ApiPathPredicateItem().setPattern("/user/group/**") // 匹配路径
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); // 匹配策略,匹配前缀
}
});
apiDefinitions.add(apiDefinition);
GatewayApiDefinitionManager.loadApiDefinitions(apiDefinitions); // 载入API分组定义
}
@PostConstruct
public void initBlockHandlers() { // 自定义限流后的界面
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map result = new HashMap<>(); // 限流提示
result.put("code", "0");
result.put("message", "您已被限流");
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON_UTF8).
body(BodyInserters.fromObject(result));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { // 配置限流异常处理器
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() { //初始化一个限流的过滤器
return new SentinelGatewayFilter();
}
}