Spring Cloud Services Gateway: Gateway

table of Contents

1 traditional routing

1.1 pom.xml

1.2 startup class

1.3 routing

1.3.1 encoding

1.3.2 configuration

1.4 Operation and results

2 service-oriented approach

2.1 pom.xml

2.2 application.properties

2.3 operation and results

3 Predicate and Filter

3.1 Predicate

3.1.1 Time match

3.1.2 Request matable

3.1.3 requested path matching

3.1.4 Request parameter matching

3.2 Filter

3.2.1 hello-service

3.2.2 feign-consumer

3.2.3 application.properties

3.2.4 Operation and results


Due to the constant bouncing Zuul 2.x, Spring Cloud own R & D the other a service gateway products: Spring Cloud Gateway, and is recommended in the latest version, so the cause of Gateway is to appear in place of Zuul. Compared Zuul, Gateway is a product of the system in the Spring, and Spring integration better. Obstruction and multiple threads at the same time compared to the Zuul 1.x, Gateway uses Netty non-blocking asynchronous model, a smaller footprint, performance advantage. While increasing the Predicate and current limiting functions.

I use a version of Java jdk-8u201, IDE using IntelliJ IDEA 2019.2 x64, version of Spring Boot is 2.1.7.RELEASE, Spring Cloud version is Greenwich.SR2. At the same time follow the author wrote before the project code used herein, the article "Spring Cloud Services Governance: Eureka + OpenFeign" in the project code, and continue to develop on this basis.


1 traditional routing

Create a Spring Boot project named api-gateway.

1.1 pom.xml

<?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 http://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.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hys</groupId>
    <artifactId>api-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>api-gateway</name>
    <description>Demo project for Spring Cloud</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

1.2 startup class

package com.hys.apigateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApiGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }

}

1.3 routing

There are two types of routing Gateway, respectively, and encoding mode configuration.

1.3.1 encoding

Add the following custom RouteLocator in the above method may be startup class:

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("route_a", r -> r.path("/hello")
                        .uri("http://localhost:8081/"))
                .build();
    }

1.3.2 configuration

The above commented methods custom RouteLocator, enter the following in application.properties file:

spring.application.name=api-gateway
server.port=5555
spring.cloud.gateway.routes[0].id=route_a
spring.cloud.gateway.routes[0].uri=http://localhost:8081/
spring.cloud.gateway.routes[0].predicates[0]=Path=/hello

SUMMARY effect wherein the last three rows of the encoding configuration and implementation is the same.

1.4 Operation and results

Here by way of the configuration file to run, make sure to build before the eureka-server, hello-service and feign-consumer projects are up and running, start this project, page enter HTTP: // localhost: 5555 / the Hello , results are as follows:

Visit http: // localhost: 5555 / hello will be automatically routed to the HTTP: // localhost: 8081 / the Hello , thus validate the routing forwarding success.


2 service-oriented approach

Evident that traditional routing configuration more complicated, especially if a route under many circumstances, it will be very troublesome to maintain. To this end, Gateway and Eureka can be together, so do not write specific mapping url, url to Eureka service discovery mechanism to automatically maintain.

2.1 pom.xml

pom follow the above configuration, the following is added just need to rely on Eureka:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2.2 application.properties

spring.application.name=api-gateway
server.port=5555
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lowerCaseServiceId=true
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/,http://peer3:1113/eureka/

Spring.cloud.gateway.discovery.locator.enabled which is set to true to turn routing forwarding function through registry, spring.cloud.gateway.discovery.locator.lowerCaseServiceId set to true means to access the service by name in lowercase.

2.3 operation and results

 Restart the project, respectively page visit http: // localhost: 5555 / feign -consumer / Feign-Consumer , http: // localhost: 5555 / feign -consumer / Feign-consumer2 and http: // localhost: 5555 / feign -consumer / Feign-consumer3 , results are as follows:

It can be seen, and the results of previously visited by OpenFeign consumers is the same, routing forwarding is successful.


3 Predicate and Filter

Predicate and Filter Gateway is the core of, Predicate is to choose which requests need to be addressed, and Filter to selected requests to make some changes, such as processing parameters and security check and so on.

3.1 Predicate

Create a Spring Boot project named test-gateway, pom file dependency and above in section 1.1 of the pom-dependent consistency. Here we use Postman to see the results.

3.1.1 Time match

spring.application.name=gateway-test
server.port=5556
spring.cloud.gateway.routes[0].id=route_test
spring.cloud.gateway.routes[0].uri=https://www.baidu.com/
spring.cloud.gateway.routes[0].predicates[0]=After=2019-08-12T12:00:00+08:00[Asia/Shanghai]

After the above representation can be routed in the request after at 12:12 on the August 2019 day while Before behalf before the specified time may be routed, Between represents within the specified time segment of the route can be:

After=2019-08-12T12:00:00+08:00[Asia/Shanghai]
Before=2019-08-12T12:00:00+08:00[Asia/Shanghai]
Between=2019-08-12T12:00:00+08:00[Asia/Shanghai], 2019-08-13T12:00:00+08:00[Asia/Shanghai]

3.1.2 Request matable

spring.application.name=gateway-test
server.port=5556
spring.cloud.gateway.routes[0].id=route_test
spring.cloud.gateway.routes[0].uri=https://www.baidu.com/
spring.cloud.gateway.routes[0].predicates[0]=Method=GET

Above represents only a GET request to be successfully routed the following results, visit Postman:

Status code of 200, indicating a successful visit, then we changed the POST request, come visit:

Status code 404, indicating access failure.

3.1.3 requested path matching

spring.application.name=gateway-test
server.port=5556
spring.cloud.gateway.routes[0].id=route_test
spring.cloud.gateway.routes[0].uri=https://www.baidu.com/
spring.cloud.gateway.routes[0].predicates[0]=Path=/foo/{segment}

By the configuration of the request path matches, Postman visit HTTP: // localhost: 5556 / foo / 1 , visit a success:

Access HTTP: // localhost: 5556 / foo / 1/2 , access failure:

3.1.4 请求参数匹配

spring.application.name=gateway-test
server.port=5556
spring.cloud.gateway.routes[0].id=route_test
spring.cloud.gateway.routes[0].uri=https://www.baidu.com/
spring.cloud.gateway.routes[0].predicates[0]=Query=p1

上述配置了请求参数中必须含有p1参数才能路由成功,Postman访问http://localhost:5556/?p1=1,路由成功:

访问http://localhost:5556/?p2=2,路由失败:

Query的值还可以使用正则表达式来进行匹配,如下面的例子:

spring.application.name=gateway-test
server.port=5556
spring.cloud.gateway.routes[0].id=route_test
spring.cloud.gateway.routes[0].uri=https://www.baidu.com/
spring.cloud.gateway.routes[0].predicates[0]=Query=p1, 1.

上面配置了参数中的键必须含有p1,同时它所对应的值是以1开头的两个字符,Postman访问http://localhost:5556/?p1=1s,路由成功:

Postman访问http://localhost:5556/?p1=1,路由失败:

3.2 Filter

这里只演示AddRequestParameter的用法,更多的用法详见Spring官网。

AddRequestParameter是在请求的路径中添加相应的参数,我们继续使用上述的api-gateway项目。

3.2.1 hello-service

首先需要对之前的hello-service项目做些更改,在其中的HelloController中添加一个foo方法如下所示:

    @RequestMapping("/foo")
    public String foo(String foo) {
        return foo;
    }

3.2.2 feign-consumer

然后在feign-consumer项目中的ConsumerController中添加下面的方法:

    @RequestMapping("/foo")
    public String foo(String foo) {
        return helloService.foo(foo);
    }

在IHelloService中添加下面的方法:

    @RequestMapping("/foo")
    String foo(@RequestParam("foo") String foo);

在相应的HelloServiceImplFallback降级类中填入下面的降级方法:

    @Override
    public String foo(String foo) {
        return "访问超时,请重新再试!";
    }

3.2.3 application.properties

api-gateway网关的配置文件需要做些修改:

spring.application.name=api-gateway
server.port=5555
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
spring.cloud.gateway.routes[0].id=add_request_parameter_route
spring.cloud.gateway.routes[0].uri=lb://hello-service
spring.cloud.gateway.routes[0].predicates[0]=Method=GET
spring.cloud.gateway.routes[0].filters[0]=AddRequestParameter=foo, bar
eureka.client.service-url.defaultZone=http://peer2:1112/eureka/,http://peer3:1113/eureka/

其中,uri表示配置路由转发到hello-service的服务提供者。filters表示给匹配的请求中添加了一个foo=bar的参数。需要注意的是,filters必须和predicates联用,否则项目启动会失败。

3.2.4 运行及结果

随后分别启动eureka-server、hello-service和feign-consumer项目,然后启动api-gateway网关项目,首先页面访问http://localhost:9001/foo,以OpenFeign消费者的方式来访问服务:

由上可以看到,当没有使用网关来访问服务的时候,页面上没有结果,也就是说服务提供者没有接收到foo参数。然后我们访问http://localhost:5555/foo,以网关的方式来访问服务:

以上可知,页面上显示了bar,foo参数被成功接收,在请求中会添加一个foo=bar的参数。

发布了62 篇原创文章 · 获赞 80 · 访问量 7万+

Guess you like

Origin blog.csdn.net/weixin_30342639/article/details/99303710