编程知识 cdmana.com

Spring cloud gateway practice 2: more routing configuration methods

Welcome to visit mine GitHub

https://github.com/zq2599/blog_demos

Content : All original articles classified summary and supporting source code , involve Java、Docker、Kubernetes、DevOPS etc. ;

An overview of this article

  • This article is about 《Spring Cloud Gateway actual combat 》 The second part of the series , We learned from the foregoing that Spring Cloud Gateway The core of is routing configuration , And then locally application.yml A route is configured in , But this way of modifying the local configuration file lacks flexibility , May not be able to meet the flexible business needs , therefore , The purpose of this article is to find other configuration methods other than local configuration , Meet various practical needs ;
  • In general, the following three methods are commonly used :
  • The target address supports using the service name ( Replace the former IP+ port );
  • Support in nacos On the configuration ;
  • Support code writing configuration ;
  • There is also a more flexible configuration :<font color="blue"> A dynamic proxy </font>, Because it involves a lot of code, a separate article will be introduced in detail

Source download

  • The complete source code of this actual combat can be found in GitHub Download to , The address and link information is shown in the following table (https://github.com/zq2599/blo...):
name link remarks
Project home page https://github.com/zq2599/blo... The project is in progress. GitHub Home page on
git Warehouse address (https) https://github.com/zq2599/blo... The warehouse address of the source code of the project ,https agreement
git Warehouse address (ssh) git@github.com:zq2599/blog_demos.git The warehouse address of the source code of the project ,ssh agreement
  • This git Multiple folders in project , The source code of this article is in <font color="blue">spring-cloud-tutorials</font> Under the folder , As shown in the red box below :

 Insert picture description here

preparation

  • A little more preparation needs to be done before the official start , Whole 《Spring Cloud Gateway actual combat 》 In the series , All requests will eventually be routed to <font color="blue">provider-hello</font> This web Up , The service currently has only one web Interface <font color="blue">/hello/str</font>, Now let's add another , The actual combat will use
  • Newly increased web Interface from LBTest.java, So it's very simple :
package com.bolingcavalry.provider.controller;

import com.bolingcavalry.common.Constants;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@RequestMapping("/lbtest")
public class LBTest {

    private String dateStr(){
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    }

    /**
     *  Return string type 
     * @return
     */
    @GetMapping("/str")
    public String helloStr() {
        return Constants.LB_PREFIX + ", " + dateStr();
    }
}
  • In the above code <font color="blue">Constants.LB_PREFIX</font> From subproject <font color="red">common</font>:
package com.bolingcavalry.common;

public interface Constants {
    String HELLO_PREFIX = "Hello World";
    String LB_PREFIX = "Load balance";
}
  • After writing the code , Make sure nacos Has been launched
  • Start up <font color="blue">provider-hello</font> engineering , After successful startup, go to see nacos, Confirm that you have registered :

 Insert picture description here

  • Ready , It's time to start fighting

The target address supports using the service name ( Replace the former IP+ port )

  • Let's start with the simplest , Let's look at the previous routing configuration , The red box is shown below , The destination address is IP+ port :

 Insert picture description here

  • Yes Spring Cloud Of course you see the problem : No registration found , exactly , It is not appropriate to write the address and port in the configuration file , Let's solve this problem first ;
  • The new name is <font color="blue">gateway-by-loadbalance</font> The sub project of , Its pom.xml The dependencies in are as follows , It can be seen that the focus is <font color="red">spring-cloud-starter-loadbalancer</font>:
<dependencies>
        <dependency>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--  The routing strategy uses lb The way is , This dependence must have  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--nacos: Registry Center -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
  • The code to start the class eliminates ( As before )
  • The configuration information is as follows , The key is uri Value <font color="red">lb://provider-hello</font>, Prefix used <font color="blue">lb:</font>, hinder <font color="blue">provider-hello</font> Is in the nacos Registered service name :
server:
  # Service port 
  port: 8085
spring:
  application:
    name: gateway-by-loadbalance
  cloud:
    nacos:
      #  Configuration of registry 
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**
  • Unit test class :
package com.bolingcavalry.gateway;

import com.bolingcavalry.common.Constants;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.junit.jupiter.api.Assertions.assertTrue;

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureWebTestClient
public class HelloTest {

    @Autowired
    private WebTestClient webClient;

    @Test
    void testLoadBalance() {
        webClient.get()
                .uri("/lbtest/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                //  Verify the status 
                .expectStatus().isOk()
                //  The verification results , Notice that the result is in string format 
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }
}
  • Run unit tests , adopt , It can be seen that the above configuration can be through the prefix <font color="blue">lb:</font> Accurately find the service :

 Insert picture description here

Support in nacos On the configuration

  • Write all configuration information in application.yml There is a problem in : Cannot configure remotely , This is inconvenient in scenarios with a large number of applications , Fortunately nacos Provides remote configuration capabilities , After the application starts, you can start from nacos Get your own configuration information , Let's try
  • The new name is <font color="blue">gateway-nacos-config</font> The sub project of , Its pom.xml The dependencies in are as follows , Please pay attention to the Chinese notes inside , Each indicates the role of each dependency :
<dependencies>
        <dependency>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--  Use bootstrap.yml When , This dependence must have  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!--  The routing strategy uses lb The way is , This dependence must have  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--nacos: Configuration center -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--nacos: Registry Center -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
  • Local configuration file <font color="blue">bootstrap.yml</font>, It's simple , Namely nacos Address and remote configuration information :
spring:
  application:
    name: gateway-nacos-config
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
        group: DEFAULT_GROUP
  • And then nacos Add a profile , The operation is shown in the red box below :

 Insert picture description here

  • Add a configuration , The points to note are as follows ( The text of the configuration information will be given later , Easy to copy ):

 Insert picture description here

  • The complete configuration information in the figure above is as follows :
server:
  port: 8083
spring:
  cloud:
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**
  • The two test methods in the test class are as follows , There is no difference from the previous :
@Test
    void testHelloPredicates() {
        webClient.get()
                .uri("/hello/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                //  Verify the status 
                .expectStatus().isOk()
                //  The verification results , Notice that the result is in string format 
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.HELLO_PREFIX)));
    }

    @Test
    void testLoadBalance() {
        webClient.get()
                .uri("/lbtest/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                //  Verify the status 
                .expectStatus().isOk()
                //  The verification results , Notice that the result is in string format 
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }
  • Run the unit test class , The test passed , Proof from nacos Get configuration file succeeded :

 Insert picture description here

Write code to configure

  • The previous examples , The routing information is written in the configuration file , There is actually another way : Write code to configure routing , Can write their own code to configure , This makes it more flexible
  • The new name is <font color="blue">gateway-by-code</font> The sub project of , Its pom.xml The file can refer to the previous project
  • The focus of this next example , Add a... In the configuration class RouteLocator Type of bean, You can add a route through the following code :
package com.bolingcavalry.gateway.cofig;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customizeRoute(RouteLocatorBuilder builder) {
        return builder
                .routes()
                .route(
                            //  The first parameter is the unique identity of the route 
                        "path_route_lb",
                            //  The second parameter is lambda Realization ,
                            //  The matching condition is set to match according to the requested path , And forwarding address ,
                            //  Be careful lb:// Indicates that this is a service name , From you to 
                            r -> r.path("/lbtest/**").uri("lb://provider-hello")
                )
                .build();
    }
}
  • The above code only configures one route , There is also one in the configuration file , This will verify that the code and configuration file can work at the same time :
server:
  # Service port 
  port: 8084
spring:
  application:
    name: gateway-by-code
  cloud:
    nacos:
      discovery:
        # nacos Service address 
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**
  • The test class is as like as two peas , It doesn't take up space , There are still two test methods <font color="blue">testHelloPredicates</font> and <font color="blue">testLoadBalance</font>
  • Executing unit tests can pass , Prove that the code configuration routing has no problem :

 Insert picture description here

  • thus , Load balancing 、nacos To configure 、 We've all tried examples of code configuration , Together, they will bring great convenience to the configuration of the actual living environment , I hope I can give you some reference

Defects and solutions

  • Although there are many configurations above , But there is a common problem : Every time the configuration changes ,Gateway The application needs to be restarted to take effect , This is not acceptable in a production environment that requires continuous production
  • In order to make the latest routing configuration available in Gateway The application takes effect without restarting , In the next article, let's explore <font color="blue"> Dynamic routing </font> How is it realized

You are not alone , Xinchen's original works are accompanied all the way

  1. Java series
  2. Spring series
  3. Docker series
  4. kubernetes series
  5. database + Middleware family
  6. DevOps series

Welcome to the official account : Xinchen, programmer

WeChat search 「 Xinchen, programmer 」, I'm Xinchen , Looking forward to traveling with you Java The world ...
https://github.com/zq2599/blog_demos

版权声明
本文为[Programmer Xinchen]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/11/20211109091141879U.html

Scroll to Top