Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Micro Service Gateway practice-- Spring Cloud Gateway

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

Guide reading

As a substitute for Netflix Zuul, Spring Cloud Gateway is a very practical micro-service gateway, which plays a very important role in the Spring Cloud micro-service architecture. This article combs the common usage scenarios of Spring Cloud Gateway, hoping to provide some help to micro-service developers.

Micro service gateway SpringCloudGateway1. Overview

Spring cloud gateway is an official gateway developed by spring based on Spring 5.0, Spring Boot2.0 and Project Reactor. Spring Cloud Gateway aims to provide simple, effective and unified API routing management for micro-service architectures. Spring Cloud Gateway, as a gateway in Spring Cloud ecosystem, aims to replace Netflix Zuul. It not only provides a unified routing method, but also provides the basic functions of the gateway based on Filer chain. For example: safety, monitoring / burying point, current restriction and so on.

two。 Core concept

The gateway provides API fully managed services and rich API management functions to assist enterprises in managing large-scale API to reduce management costs and security risks, including protocol adaptation, protocol forwarding, security policy, anti-brushing, traffic, monitoring logs and so on. Generally speaking, the URL or interface information exposed by the gateway is collectively referred to as routing information. If you have developed gateway middleware or used Zuul, you will know that the core of the gateway is Filter and Filter Chain (Filter chain of responsibility). Sprig Cloud Gateway also has the concept of routing and Filter. Here are a few important concepts in Spring Cloud Gateway.

Routing. Routing is the most basic part of the gateway, and the routing information consists of an ID, a destination URL, a set of assertions, and a set of Filter. If you assert that the route is true, the requested URL matches the configuration

Assert. Assertion function in Java8. The input type of the assertion function in Spring Cloud Gateway is ServerWebExchange in the Spring5.0 framework. The assertion function in Spring Cloud Gateway allows developers to define matches to any information from the http request, such as request headers and parameters.

Filter. A standard Spring webFilter. Filter in Spring cloud gateway is divided into two types of Filter, Gateway Filter and Global Filter. The filter Filter will modify the request and response

As shown in the figure above, Spring cloudGateway makes a request. The route matching the request is then found in Gateway Handler Mapping and sent to Gateway web handler. Handler then sends the request to our actual service to execute the business logic through the specified filter chain, and then returns.

Getting started

Take the development of Spring Boot framework as an example, start a Gateway service module (with Consul as the registry) and a back-end service module. The client-side request routes the request to the back-end service via the gateway service.

Prerequisites:

Consul: version 1.5.0.

Spring bot: version 2.1.5.

Spring cloud: version Greenwich.SR1.

Redis: version 5.0.5. 1. Micro service development

Here, take the development of a micro-service using the Spring Boot framework as an example, start a service and register with Consul.

Introduce dependencies:

Org.springframework.cloud spring-cloud-starter-consul-discovery

Register the service to Consul, and the configuration file is as follows:

Spring: application: name: service-consumer cloud: consul: host: 127.0.0.1 port: 8500 discovery: service-name: service-consumer

Define RestController as follows, and publish the HTTP API.

RestController@RequestMapping ("/ user") public class UserController {@ Resource private UserService userService; @ GetMapping (value = "/ info") public User info () {return userService.info ();}

Note: this is the server configuration, and the request is routed to the service by Gateway.

two。 Gateway configuration

Create a Gateway service and introduce the following dependencies:

Org.springframework.cloud spring-cloud-starter-gateway org.springframework.cloud spring-cloud-starter-consul-discovery

The startup class is configured as follows:

@ SpringBootApplication@EnableDiscoveryClientpublic class GatewayApplication {public static void main (String [] args) {SpringApplication.run (GatewayApplication.class, args);}}

Spring Cloud Gateway acts as a routing function for client requests. The main configurations are as follows:

Server: port: 8098spring: application: name: service-gateway cloud: gateway: discovery: locator: enabled: true lower-case-service-id: true consul: host: 127.0.0.1 # Register gateway gateway to consul port: 8500 discovery: service-name: service-gateway

When the http://localhost:8089/service-consumer/user/info is used to access the service, the gateway can route and forward the service and forward the request to the specific back-end service. At this point, the url prefix service-consumer used in url is the string after the service name registered by the back-end service in Consul is converted to lowercase letters.

Best practice 01 Gateway Gateway configuration

The configuration of the gateway for routing and forwarding is defined in the development specification in the second part of this article. In addition to the above configuration, you can also use the following methods:

Gateway: discovery: locator: enabled: true lower-case-service-id: true routes:-id: service_consumer uri: lb://service-consumer predicates:-Path= / consumer/** filters:-StripPrefix=1

In the above configuration, a predicat of Path is configured. All requests starting with / consumer/** will be forwarded to the address where uri is lb://service-consumer. Lb://service-consumer (the name of the service in the registry) is the load balancer address of the service-consumer service, and the filter of StripPrefix will be used to remove / consumer before forwarding. At the same time, change the spring.cloud.gateway.discovery.locator.enabled to false, and if you don't change it, the previous request address such as http://localhost:8081/service-consumer/user/info can be accessed normally, because two router have been created for each service.

The second part of this article and this section describe a total of two configurations, both of which can achieve the function of request routing and forwarding. The parameter spring.cloud.gateway.discovery.locator.enabled is true, which means that Gateway enables service registration and discovery, and Spring Cloud Gateway automatically creates a router for each service based on service discovery, and this router forwards the request path starting with the service name to the corresponding service. Spring.cloud.gateway.discovery.locator.lowerCaseServiceId configures the service name on the request path to be lowercase (because when the service is registered, the service name is changed to uppercase when registering with the registry).

Gateway: discovery: locator: enabled: true lower-case-service-id: true02 Gateway cross-domain access

Spring Cloud Gateway is also designed for cross-domain access, and the following configurations can be used to solve cross-domain access problems:

Spring: cloud: gateway: globalcors: corsConfigurations:'[/ *]': allowedOrigins: "https://docs.spring.io" allowedMethods:-GET allowHeaders:-Content-Type

In the above example, the get request from https://docs.spring.io is allowed to be accessed, and it is indicated that the server allows the field Content-Type in the request header.

03 Gateway filter

Spring Cloud Gateway's filter life cycle is not as rich as Zuul, it has only two: "pre" and "post":

Pre: this filter is called before the request is routed. You can use this filter to authenticate, select the requested micro-service in the cluster, and record debugging information.

Post: this filter is executed after routing to the server. This filter can be used to add HTTP Header, statistics and metrics to the response, send the response from the microservice to the client, and so on.

There are two kinds of filter for Spring Cloud gateway: GatewayFilter and Globalfilter. GlobalFilter will be applied to all routes, while Gatewayfilter will be applied to a single route or a packet route.

Using Gatewayfilter, you can modify the request or response of the requested http, or make some special restrictions based on the request or response. More often, you can use Gatewayfilter to do some specific routing configuration.

The following configuration is related to AddRequestParameter Gatewayfilter.

Spring: application: name: service-gateway cloud: gateway: discovery: locator: enabled: true routes:-id: parameter_route uri: http://localhost:8504/user/info filters:-AddRequestParameter=foo, bar predicates:-Method=GET

The forwarding address is specified in the above configuration, and all GET methods will automatically add foo=bar. When the request meets the above routing conditions, you can receive the parameters added by the Gateway gateway on the backend service.

In addition, a more commonly used filter, namely StripPrefix gateway filter, is introduced.

The configuration is as follows:

Spring: cloud: gateway: routes:-id: stripprefixfilter uri: lb://service-consumer predicates:-Path=/consumer/** filters:-StripPrefix=1

When the client side uses the http://localhost:8098/consumer/user/info path to make the request, if you configure Gateway according to the above, the request will be converted to http://localhost:8098/service-consumer/user/info. Use this as the final destination of the front-end request.

04 Gateway request match

Gateway gateways can match in different ways to distribute requests to different back-end services.

Match through header and distribute the request to different services. The configuration is as follows:

Spring: cloud: gateway: routes:-id: header_route uri: http://baidu.com predicates:-Header=X-Request-Id,\ d+

Through the curl test: curl http://localhost:8080-H "X-Request-Id:666666", the return page code proves that the match is successful.

If the match is based on Host, the configuration is as follows:

Spring: cloud: gateway: routes:-id: host_route uri: http://baidu.com predicates:-Host=**.baidu.com

Pass the curl http://localhost:8098-H "Host: www.baidu.com" test, and the page code returned will be forwarded successfully.

It can be routed in different ways, such as POST, GET, PUT, DELTE, etc.

Spring: cloud: gateway: routes:-id: method_route uri: http://baidu.com predicates:-Method=GET

After testing through curl http://localhost:8098, the return page code indicates success.

The above is a single match for routing. If multiple matches are matched together for routing, all routes must meet the conditions before routing is carried out.

05 Gateway fuse

Spring Cloud Gateway can also take advantage of the circuit breaker feature of Hystrix to downgrade the service when the traffic is too large, and the dependence of Hystrix must be added to the project.

Org.springframework.cloud spring-cloud-starter-netflix-hystrix

Once configured, Gateway generates a HystrixCommand object using fallbackcmd as its name for fusing processing. If you want to add the callback content after the circuit breaker, you need to add the following configuration:

Spring: cloud: gateway: routes:-id: hystrix_route uri: lb://consumer-service predicates:-Path=/consumer/** filters:-name: Hystrix args: name: fallbackcmd fallbackUri: forward:/fallback-StripPrefix=1hystrix: command: fallbackcmd: execution: isolation: Thread: timeoutInMilliseconds: 5000 # timeout If the timeout is not set, the fuse may not be triggered.

The return path after the circuit breaker is given in the above configuration, so the / fallback path is added to the Gateway service module as the return path in the event of a service circuit breaker.

@ RestControllerpublic class GatewayController {@ RequestMapping (value = "/ fallback") public String fallback () {return "fallback nothing";}}

FallbackUri: forward:/fallback configures the path to be tuned when fallback is called. When the fallback calling Hystrix is called, the request will be forwarded to the URI / fallback, and the return value of this path will be used as the return result.

06 Gateway retry the router

With simple configuration, Spring Cloud Gateway can support the ability to request retries.

Spring: cloud: gateway: routes:-id: header_route uri: http://localhost:8504/user/info predicates:-Path=/user/** filters:-name: Retry args: retries: 3 status: 503-StripPrefix=1

Retry GatewayFilter controls the retry mechanism with four parameters, which are described as follows:

Retries: the number of retries. The default value is 3.

The status return code of statuses:HTTP. For more information, please see org.springframework.http.HttpStatus.

Methods: specifies which method requests need to be retried. The default value is GET method. For more information, please see org.springframework.http.HttpMethod.

Series: status code configuration of some columns. Value reference: org.springframework.http.HttpStatus.Series. Only a certain section of status code that matches will retry the logic. The default value is SERVER_ERROR, and the value is 5, that is, 5XX (status code starting with 5). There are 5 values in total.

Using the above configuration for testing, when the backend service is not available, you will see the log requested three times in the console, which proves that this configuration is valid.

07 Gateway current limit operation

Spring Cloud Gateway itself integrates the current limit operation, and you need to add Redis dependencies in the Redis,pom file for Gateway current restriction:

Org.springframework.boot spring-boot-starter-data-redis-reactive

The configuration file is as follows:

Spring: cloud: gateway: routes:-id: rate_limit_route uri: lb://service-consumer predicates:-Path=/user/** filters:-name: RequestRateLimiter args: key-resolver: "# {@ hostAddrKeyResolver}" redis-rate-limiter.replenishRate: 1 redis-rate-limiter.burstCapacity: 3 -StripPrefix=1 consul: host: 127.0.0.1 port: 8500 discovery: service-name: service-gateway instance-id: service-gateway-233 redis: host: localhost port: 6379

In the above configuration question price, the information of Redis is configured, and the current limiting filter of RequestRateLimiter is configured, which needs to be configured with three parameters:

BurstCapacity: the total capacity of the token bucket.

ReplenishRate: the average rate of token pass fill per second.

Key-resolver: the name of the Bean object of the parser used to limit the current. It uses the SpEL expression # {@ beanName} to get the bean object from the Spring container.

Note: the name under filter must be RequestRateLimiter.

The bean after the Key-resolver parameter needs to be implemented on its own and then injected into the Spring container. KeyResolver needs to implement the resolve method. For example, to limit the current according to ip, you need to use hostAddress to judge. After you implement KeyResolver, you need to register the Bean of this class with the Ioc container. Current limit can also be based on uri, which is the same as hostname current limit. For example, take ip current limit as an example, add the following implementation to the gateway module:

Public class HostAddrKeyResolver implements KeyResolver {@ Override public Mono resolve (ServerWebExchange exchange) {return Mono.just (exchange.getRequest () .getRemoteAddress () .getAddress () .getHostAddress ());} public HostAddrKeyResolver hostAddrKeyResolver () {return new HostAddrKeyResolver ();}}

Inject this class into the spring container:

@ SpringBootApplication@EnableDiscoveryClientpublic class GatewayApplication {public static void main (String [] args) {SpringApplication.run (GatewayApplication.class, args);} @ Bean public HostAddrKeyResolver hostAddrKeyResolver () {return new HostAddrKeyResolver ();}}

Based on the above configuration, the request for ip-based access can be restricted.

08 Custom Gatewayfilter

Spring Cloud Gateway has built-in filters to meet the needs of many scenarios. Of course, you can also customize the filter. In Spring Cloud Gateway custom filters, filters need to implement two interfaces, GatewayFilter and Ordered.

The following example implements Gatewayfilter, which records the time spent on each request in the form of a log log, as follows:

Public class RequestTimeFilter implements GatewayFilter, Ordered {private static final Log log = LogFactory.getLog (GatewayFilter.class); private static final String REQUEST_TIME_BEGIN = "requestTimeBegin"; @ Override public Mono filter (ServerWebExchange exchange, GatewayFilterChain chain) {exchange.getAttributes () .put (REQUEST_TIME_BEGIN, System.currentTimeMillis ()) Return chain.filter (exchange) .then (Mono.fromRunnable (()-> {Long startTime = exchange.getAttribute (REQUEST_TIME_BEGIN)) If (startTime! = null) {log.info ("request path:" + exchange.getRequest () .getURI () .getRawPath () + "elapsed time:" + (System.currentTimeMillis ()-startTime) + "ms");}}));} @ Override public int getOrder () {return 0 }}

The filter you implement is defined in the above code. The int getOrder () method of Ordered is used to prioritize the filter, and the higher the value, the lower the priority. There is also a filter (ServerWebExchange exchange, GatewayFilterChain chain) method, in which the start time of the request is recorded and saved in ServerWebExchange, where there is a filter of type "pre". Then the run () method in the inner class of chain.filter () is the equivalent of a "post" filter, where the time elapsed by the request is printed.

Next, register the filter with router, as follows.

@ Bean public RouteLocator customerRouteLocator (RouteLocatorBuilder builder) {return builder.routes () .route (r-> r.path ("/ user/**") .route (f-> f.filter (new RequestTimeFilter ()) .addResponse Header ("X-Response-Default-Foo") "Default-Bar") .uri ("http://localhost:8504/user/info") .order (0) .id (" customer_filter_router ")) .build () }

In addition to the way the above code configures our custom filter, it can also be configured directly in the application.yml file, which is not discussed here.

Start the program, and the request elapsed time will be printed through the curl http://localhost:8098/user/info console. The log is as follows:

.. 2019-05-22 15 INFO 1331.221 INFO 19780-[ctor-http-nio-4] o.s.cloud.gateway.filter.GatewayFilter: request path: / user/info consumption time: 54ms...2019-05-22 16purl 46V 23.785 INFO 29928-[ctor-http-nio-1] o.s.cloud.gateway.filter.GatewayFilter: request path: / user/info3 consumption time: 5ms. 09 Custom GlobalFilter

According to the scope of action, Spring Cloud Gateway is divided into GatewayFilter and GlobalFilter. The differences between the two are as follows:

GatewayFilter: it needs to be configured under specific routes through spring.cloud.routes.filters, only on the current route or globally through spring.cloud.default-filters, and on all routes.

GlobalFilter: the global filter, which does not need to be configured in the configuration file, acts on all routes, and is finally packaged into a filter recognized by GatewayFilterChain through GatewayFilterAdapter. It is the core filter for the request service and the routed URI to be converted into the request address of the real business service. It does not need to be configured. It is loaded when the system is initialized and acts on each route.

Gatewayfilter is defined in the previous section, and Globalfilter is implemented as follows:

Public class TokenFilter implements GlobalFilter, Ordered {Logger logger= LoggerFactory.getLogger (TokenFilter.class); @ Override public Mono filter (ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest (). GetQueryParams () .getFirst ("token"); if (token = = null | | token.isEmpty ()) {logger.info ("token is empty and cannot be accessed."); exchange.getResponse () .setStatusCode (HttpStatus.UNAUTHORIZED) Return exchange.getResponse () .setComplete ();} return chain.filter (exchange);} @ Override public int getOrder () {return 0;}}

The above code implements Globalfilter, and the specific logic is to determine whether the parameter token is included in the request. If not, the verification fails and is valid for all requests. If it contains token, it will be forwarded to the specific back-end service. If not, the verification will not pass.

Access through curl http://localhost:8098/user/info, because the path does not contain the parameter token, it cannot pass the verification. The log is printed as follows:

2019-05-22 15 com.song.gateway.TokenFilter 27charge 11.078 INFO 5956-[ctor-http-nio-1] com.song.gateway.TokenFilter: token is empty and cannot be accessed.

When accessing through curl http://localhost:8098/user/info?token=123, you can get the result returned by the back-end service.

This article is originally published by Boyun Research Institute. Please indicate the source when reproduced.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report