Spring cloud gateway practice 2: more routing configuration methods

Programmer Xinchen 2021-11-25 17:26:29

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 :
  1. The target address supports using the service name ( Replace the former IP+ port );
  2. Support in nacos On the configuration ;
  3. Support code writing configuration ;
  • There is also a more flexible configuration : A dynamic proxy , 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/blog_demos):
name link remarks
Project home page https://github.com/zq2599/blog_demos The project is in progress. GitHub Home page on
git Warehouse address (https) https://github.com/zq2599/blog_demos.git The warehouse address of the source code of the project ,https agreement
git Warehouse address (ssh) [email protected]: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 spring-cloud-tutorials 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 provider-hello This web Up , The service currently has only one web Interface /hello/str, 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 Constants.LB_PREFIX From subproject common
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 provider-hello 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 gateway-by-loadbalance The sub project of , Its pom.xml The dependencies in are as follows , It can be seen that the focus is spring-cloud-starter-loadbalancer

<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 lb://provider-hello, Prefix used lb:, hinder provider-hello 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 lb: 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 gateway-nacos-config 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 bootstrap.yml, 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 gateway-by-code 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 testHelloPredicates and testLoadBalance

  • 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 Dynamic routing 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

Please bring the original link to reprint ,thank
Similar articles

2021-11-25

2021-11-25

2021-11-25

2021-11-25

2021-11-25

2021-11-25

2021-11-25

2021-11-25