资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

Spring Cloud Gateway实战之二:更多路由配置方式

来源:公司资讯 | 2021.08.17

本文是《Spring Cloud Gateway实战》系列的第二篇,经过前文我们了解到Spring Cloud Gateway的中心是路由装备,然后在本地application.yml中装备了一条路由,但这种修改本地装备文件的办法缺少灵敏性,未必能满意灵敏多变的事务需求,因此,本篇的意图就是找出本地装备之外的其他装备办法来,满意各种实践需求;
总的来说以下三种办法都是常用的:
方针地址支撑用服务名(替代之前的IP+端口);
支撑在nacos上装备;
支撑写代码的办法装备;
别的还有一种愈加灵敏的装备办法:动态署理,由于涉及到不少的代码所以会单独出一篇文章详细介绍
源码下载
本篇实战中的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git库房地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的库房地址,https协议
git库房地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的库房地址,ssh协议
这个git项目中有多个文件夹,本篇的源码在spring-cloud-tutorials文件夹下,如下图红框所示:

准备工作
正式开端前需要再做一点准备工作,整个《Spring Cloud Gateway实战》系列中,一切请求最后都会被路由到provider-hello这个web上去,该服务现在只有一个web接口/hello/str,现在我们再给它添加一个,后边的实战会用到
新添加的web接口来自LBTest.java,可见非常简略:
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
     */
    @GetMapping("/str")
    public String helloStr() {
        return Constants.LB_PREFIX + ", " + dateStr();
    }
}

上述代码中的Constants.LB_PREFIX来自子工程common:
package com.bolingcavalry.common;

public interface Constants {
    String HELLO_PREFIX = "Hello World";
    String LB_PREFIX = "Load balance";
}

写完代码后,先保证nacos现已发动
在发动provider-hello工程,发动成功后去看nacos,承认现已注册:

准备结束,可以开端实战了
方针地址支撑用服务名(替代之前的IP+端口)
我们从最简略的开端,先看前文的路由装备,如下图红框,方针地址是IP+端口:

玩过Spring Cloud的您天然看出了问题所在:没有注册发现,确实,这样将地址和端口写死在装备文件中是不合适的,我们先来处理这个问题;
新增名为gateway-by-loadbalance的子工程,其pom.xml中的依靠情况如下,可见重点是spring-cloud-starter-loadbalancer:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
       
   

发动类的代码省去了(和前文的一样)
装备信息如下,重点是uri的值lb://provider-hello,用了前缀lb:,后边的provider-hello就是在nacos注册的服务名:
server:
  #服务端口
  port: 8085
spring:
  application:
    name: gateway-by-loadbalance
  cloud:
    nacos:
      # 注册中心的装备
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**

单元测验类:
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()
                // 验证状况
                .expectStatus().isOk()
                // 验证成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }

运行单元测验,经过,可见上述装备可以经过前缀lb:精确找到服务:


支撑在nacos上装备
将一切装备信息写在application.yml中有个问题:不能长途装备,这在应用数量较多的场景就不方便了,好在nacos供给了长途装备的才能,应用发动后可以从nacos获得自己的装备信息,我们来试试
新增名为gateway-nacos-config的子工程,其pom.xml中的依靠情况如下,请留意里边的中文注释,每指明了每一个依靠的作用:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-bootstrap
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-config
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
      

本地的装备文件bootstrap.yml,非常简略,就是nacos的地址和长途装备信息:
spring:
  application:
    name: gateway-nacos-config
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
        group: DEFAULT_GROUP

 


接下来再nacos添加一个装备文件,操作如下图红框:

添加一个装备,要留意的地方如下(装备信息的文本稍后给出,便于仿制):

上图中完整的装备信息如下:
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/**

测验类中的两个测验办法如下所示,和前面没有任何区别:
@Test
    void testHelloPredicates() {
        webClient.get()
                .uri("/hello/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 验证状况
                .expectStatus().isOk()
                // 验证成果,留意成果是字符串格局
                .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()
                // 验证状况
                .expectStatus().isOk()
                // 验证成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }

 


运行单元测验类,测验经过,证明从nacos获取装备文件成功:

写代码的办法装备
前面的几个例子,路由信息都是写在装备文件中的,其实还有一种办法:写代码装备路由,能自己写代码来装备,这灵敏性就更强了
新增名为gateway-by-code的子工程,其pom.xml文件参照前面工程的即可
接下来的本例的重点,在装备类中添加一个RouteLocator类型的bean,经过以下代码即可添加一个路由:
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(
                            // 第一个参数是路由的唯一身份
                        "path_route_lb",
                            // 第二个参数是个lambda实现,
                            // 设置了配套条件是依照请求路径匹配,以及转发地址,
                            // 留意lb://表示这是个服务名,要从
                            r -> r.path("/lbtest/**").uri("lb://provider-hello")
                )
                .build();
    }
}

 


上述代码只装备了一个路由,还有一个在装备文件中,这样就能验证代码和装备文件能不能同时收效了:
server:
  #服务端口
  port: 8084
spring:
  application:
    name: gateway-by-code
  cloud:
    nacos:
      discovery:
        # nacos服务地址
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**

 


测验类和之前工程的一模一样,就不占用篇幅了,依旧是两个测验办法testHelloPredicates和testLoadBalance
履行单元测验可以顺利经过,证明代码装备路由没有问题:

至此,负载均衡、nacos装备、代码装备的实例我们都测验过了,它们合起来会给实践生存环境的装备带来很大的方便,期望可以给您一些参阅
————————————————
版权声明:本文为CSDN博主「程序员欣宸」的原创文章,遵从CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/boling_cavalry/article/details/119592175本篇概览
本文是《Spring Cloud Gateway实战》系列的第二篇,经过前文我们了解到Spring Cloud Gateway的中心是路由装备,然后在本地application.yml中装备了一条路由,但这种修改本地装备文件的办法缺少灵敏性,未必能满意灵敏多变的事务需求,因此,本篇的意图就是找出本地装备之外的其他装备办法来,满意各种实践需求;
总的来说以下三种办法都是常用的:
方针地址支撑用服务名(替代之前的IP+端口);
支撑在nacos上装备;
支撑写代码的办法装备;
别的还有一种愈加灵敏的装备办法:动态署理,由于涉及到不少的代码所以会单独出一篇文章详细介绍
源码下载
本篇实战中的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git库房地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的库房地址,https协议
git库房地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的库房地址,ssh协议
这个git项目中有多个文件夹,本篇的源码在spring-cloud-tutorials文件夹下,如下图红框所示:

准备工作
正式开端前需要再做一点准备工作,整个《Spring Cloud Gateway实战》系列中,一切请求最后都会被路由到provider-hello这个web上去,该服务现在只有一个web接口/hello/str,现在我们再给它添加一个,后边的实战会用到
新添加的web接口来自LBTest.java,可见非常简略:
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
     */
    @GetMapping("/str")
    public String helloStr() {
        return Constants.LB_PREFIX + ", " + dateStr();
    }
}

上述代码中的Constants.LB_PREFIX来自子工程common:
package com.bolingcavalry.common;

public interface Constants {
    String HELLO_PREFIX = "Hello World";
    String LB_PREFIX = "Load balance";
}

写完代码后,先保证nacos现已发动
在发动provider-hello工程,发动成功后去看nacos,承认现已注册:

准备结束,可以开端实战了
方针地址支撑用服务名(替代之前的IP+端口)
我们从最简略的开端,先看前文的路由装备,如下图红框,方针地址是IP+端口:

玩过Spring Cloud的您天然看出了问题所在:没有注册发现,确实,这样将地址和端口写死在装备文件中是不合适的,我们先来处理这个问题;
新增名为gateway-by-loadbalance的子工程,其pom.xml中的依靠情况如下,可见重点是spring-cloud-starter-loadbalancer:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
       

发动类的代码省去了(和前文的一样)
装备信息如下,重点是uri的值lb://provider-hello,用了前缀lb:,后边的provider-hello就是在nacos注册的服务名:
server:
  #服务端口
  port: 8085
spring:
  application:
    name: gateway-by-loadbalance
  cloud:
    nacos:
      # 注册中心的装备
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**

单元测验类:
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()
                // 验证状况
                .expectStatus().isOk()
                // 验证成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }
}

运行单元测验,经过,可见上述装备可以经过前缀lb:精确找到服务:

支撑在nacos上装备
将一切装备信息写在application.yml中有个问题:不能长途装备,这在应用数量较多的场景就不方便了,好在nacos供给了长途装备的才能,应用发动后可以从nacos获得自己的装备信息,我们来试试
新增名为gateway-nacos-config的子工程,其pom.xml中的依靠情况如下,请留意里边的中文注释,每指明了每一个依靠的作用:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-bootstrap
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-config
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
       

本地的装备文件bootstrap.yml,非常简略,就是nacos的地址和长途装备信息:
spring:
  application:
    name: gateway-nacos-config
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
        group: DEFAULT_GROUP

接下来再nacos添加一个装备文件,操作如下图红框:

添加一个装备,要留意的地方如下(装备信息的文本稍后给出,便于仿制):

上图中完整的装备信息如下:
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/**

测验类中的两个测验办法如下所示,和前面没有任何区别:
@Test
    void testHelloPredicates() {
        webClient.get()
                .uri("/hello/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 验证状况
                .expectStatus().isOk()
                // 验证成果,留意成果是字符串格局
                .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()
                // 验证状况
                .expectStatus().isOk()
                // 验证成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }

运行单元测验类,测验经过,证明从nacos获取装备文件成功:

写代码的办法装备
前面的几个例子,路由信息都是写在装备文件中的,其实还有一种办法:写代码装备路由,能自己写代码来装备,这灵敏性就更强了
新增名为gateway-by-code的子工程,其pom.xml文件参照前面工程的即可
接下来的本例的重点,在装备类中添加一个RouteLocator类型的bean,经过以下代码即可添加一个路由:
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(
                            // 第一个参数是路由的唯一身份
                        "path_route_lb",
                            // 第二个参数是个lambda实现,
                            // 设置了配套条件是依照请求路径匹配,以及转发地址,
                            // 留意lb://表示这是个服务名,要从
                            r -> r.path("/lbtest/**").uri("lb://provider-hello")
                )
                .build();
    }
}

上述代码只装备了一个路由,还有一个在装备文件中,这样就能验证代码和装备文件能不能同时收效了:
server:
  #服务端口
  port: 8084
spring:
  application:
    name: gateway-by-code
  cloud:
    nacos:
      discovery:
        # nacos服务地址
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**

测验类和之前工程的一模一样,就不占用篇幅了,依旧是两个测验办法testHelloPredicates和testLoadBalance
履行单元测验可以顺利经过,证明代码装备路由没有问题:

至此,负载均衡、nacos装备、代码装备的实例我们都测验过了,它们合起来会给实践生存环境的装备带来很大的方便,期望可以给您一些参阅

 

—— 灵通云微信公众号 ——

热门标签

上一条———————

下一条———————

十七年 建站经验

多一份参考,总有益处

联系灵通云,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

业务热线:400-688-6062 / 大客户专线   南通:15818561755