1. Gateway configuration
1. Create a new gateway submodule
2. Installation dependencies
Note: Do not install spring-boot-starter-web dependencies
<!--Gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- Service registration service discovery needs to be introduced --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
3. The main startup class
@SpringBootApplication public class GatewayServerSampleApplication { public static void main(String[] args) { SpringApplication.run(GatewayServerSampleApplication.class, args); } }
4. Bootstrap.yml configures the gateway
Among them, -id is the route Id; uri is the name of the forwarded service, which can also be written as http://localhost:9090, etc.; predicates is the assertion, that is, the judgment is made when the route jumps
server: port: 8083 # program port number spring: application: name: gateway-server-sample # application name cloud: nacos: discovery: server-addr: 127.0.0.1:8848 gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "*" # Allowed origins, * means all allowedMethods: "*" # Allowed request methods * means all allowedHeaders: "*" # Allow request headers * means all httpclient: connect-timeout: 5000 # The time it takes to establish a connection Unit: milliseconds response-timeout: 4s # #The time it takes to read the available resources from the server after the connection is established discovery: locator: enabled: true routes: #routing, can configure multiple - id: user_route # route id can be unique, the default is UUID uri: lb://user-server-sample # The address of the service provided after the match is successful order: 1 # Routing priority, the smaller the value, the higher the priority, default 0 predicates: - Path=/user/** # Assertion, path matching for routing filters: -User=0,1000 # - RedirectTo=302,http://localhost:8082//shop/findById?id=1 # - AddRequestParameter=id,1 - id: shop_route # The routing id can be unique, the default is UUID uri: lb://shop-server-sample # The address of the service provided after the matching is successful order: 1 # Routing priority, the smaller the value, the higher the priority, default 0 predicates: - Path=/shop/** # Assertion, path matching for routing
so far you’re done
2. Add sentinel current limiting
1. Installation dependencies
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId> </dependency>
2. Current limiting in routing dimension
Corresponding to the route Id, create a new SentinelRouteConfiguration class
package com.springcloudaliba.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 // marked as a configuration class public class SentinelRouteConfiguration { private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; public SentinelRouteConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, // constructor ServerCodecConfigurer serverCodecConfigurer) { this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); this.serverCodecConfigurer = serverCodecConfigurer; } @PostConstruct public void initGatewayRules() { //Initialize current limiting rules Set<GatewayFlowRule> rules = new HashSet<>(); GatewayFlowRule gatewayFlowRule = new GatewayFlowRule("user_route");// resource name, corresponding to the value of routeId, flow-limiting user service here gatewayFlowRule.setCount(1); // flow limit threshold gatewayFlowRule.setIntervalSec(1); // Statistical time window (unit: second), the default is 1 second rules. add(gatewayFlowRule); GatewayRuleManager.loadRules(rules); // load rules } @PostConstruct public void initBlockHandlers() { // Customize the interface after the current limit BlockRequestHandler blockRequestHandler = new BlockRequestHandler() { @Override public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { Map<String, String> result = new HashMap<>(); // current limit prompt result. put("code", "0"); result.put("message", "You have been restricted"); 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() { // configure current limit exception handler return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); } @Bean @Order(Ordered. HIGHEST_PRECEDENCE) public GlobalFilter sentinelGatewayFilter() { //Initialize a current-limiting filter return new SentinelGatewayFilter(); } }
3. Limit the flow in the api dimension
Corresponding to the specific interface, create a new SentinelApiGroupConfiguration class
package com.springcloudaliba.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 // marked as a configuration class public class SentinelApiGroupConfiguration { private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; public SentinelApiGroupConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, // constructor ServerCodecConfigurer serverCodecConfigurer) { this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); this.serverCodecConfigurer = serverCodecConfigurer; } @PostConstruct public void initGatewayRules() {// Initialize current limiting rules Set<GatewayFlowRule> rules = new HashSet<>(); GatewayFlowRule gatewayFlowRule = new GatewayFlowRule("user_api"); gatewayFlowRule.setCount(1); // flow limit threshold gatewayFlowRule.setIntervalSec(1); // Statistical time window (unit: second), the default is 1 second rules. add(gatewayFlowRule); GatewayRuleManager.loadRules(rules); // load rules } @PostConstruct public void initCustomizedApis() { // Customize API grouping Set<ApiDefinition> apiDefinitions = new HashSet<>(); ApiDefinition apiDefinition = new ApiDefinition("user_api") // user_api is the api group name .setPredicateItems(new HashSet<ApiPredicateItem>() { { add(new ApiPathPredicateItem().setPattern("/user/group/**") // matching path .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); // matching strategy, matching prefix } }); apiDefinitions. add(apiDefinition); GatewayApiDefinitionManager.loadApiDefinitions(apiDefinitions); // load API group definition } @PostConstruct public void initBlockHandlers() { // Customize the interface after the current limit BlockRequestHandler blockRequestHandler = new BlockRequestHandler() { @Override public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { Map<String, String> result = new HashMap<>(); // current limit prompt result. put("code", "0"); result.put("message", "You have been restricted"); 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() { // configure current limit exception handler return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); } @Bean @Order(Ordered. HIGHEST_PRECEDENCE) public GlobalFilter sentinelGatewayFilter() { //Initialize a flow-limiting filter return new SentinelGatewayFilter(); } }