第一次见凌晨四点的帝都:spring cloud zuul动态路由设置

前情提要:在追一个讲spring cloud的课,讲到zuul动态路由的时候,老师只是大概说了说思路,没有具体讲细节,于是我自己搞了一下,实现一个非常简陋的zuul动态路由。大概从凌晨十二点多搞到凌晨三点多的样子,简要记录一下。

zuul是干嘛用的:个人理解就是个类似拦截器+过滤器的作用,设置一个路由表,对不同的请求,将其转发到不同的微服务进行处理。
什么是动态路由:个人理解就是不用重启了,改完路由配置直接生效。

项目结构:
在这里插入图片描述

pom文件结构如下:

<modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wmx</groupId>
    <artifactId>api-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>api-gateway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- config依赖,动态路由用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <!-- bus自动刷新配置 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</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>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

zuul的配置文件是放在我的github上了,由统一配置中心进行加载,github部分配置如下:
在这里插入图片描述
统一配置中心这边就不说了
我这个zuul配置文件,自己定义了一个路由规则,/myProduct/**匹配的所有请求都会被转发到product这个微服务上。ignored-patterns的配置表示排除某些接口,这些被排除的接口不能被外部请求所访问到,会报404。

如何配置zuul动态路由,首先获取配置文件被修改之后新的属性:

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

    //动态路由配置,即自动刷新zuul配置
    @ConfigurationProperties("zuul")
    @RefreshScope
    public ZuulProperties zuulProperties(){
        return new ZuulProperties();
    }

}

zuul已经封装好了一个对象ZuulProperties,这样每次spring bus配置自动刷新之后,就会把新的配置属性存入这个对象中。

然后将ZuulProperties对象里的属性值读出来,进行路由表的配置:

public class ZuulRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

    public ZuulRouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties);
    }

    //刷新路由
    @Override
    public void refresh() {
        doRefresh();
    }
}

这里需要注意一点,我写的是最最简单的动态路由配置,直接调用父类默认的方法就行了。像我参考的那篇博客,他的路由规则是存在数据库里的,这时候就需要自己重新覆盖一个locateRoutes()方法,把路由规则从数据库读出来,配到一个map对象中,有需要的可以参考那一篇。

接下来将ZuulRouteLocator配置成bean,供最后一步用:

@Configuration
public class CustomZuulConfig {

    @Autowired
    ZuulProperties zuulProperties;

    @Bean
    public ZuulRouteLocator routeLocator() {
        ZuulRouteLocator routeLocator = new ZuulRouteLocator(null, this.zuulProperties);
        return routeLocator;
    }

}

最后配置路由刷新监听事件,这样就可以把新的路由规则配置生效了:

@Service
public class RefreshRouteService {

    @Autowired
    ApplicationEventPublisher publisher;

    @Autowired
    RouteLocator routeLocator;

    public void refreshRoute() {
        RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
        publisher.publishEvent(routesRefreshedEvent);
    }

}

启动eureka,config,zuul和微服务进行测试。
一开始的配置文件中,/**/product/listForOrder的请求都会被拦住,返回404。
修改配置文件,把拦截请求换成另一个,然后用postman发一个/actuator/bus-refresh的POST请求(webhook自动刷新在我这里有问题,还需要再查),注意请求头里要加Content-Type:application/json这个属性,配置文件自动更新之后,zuul的项目就会监听到事件从而自动刷新路由表,新的路由规则就生效了。
具体图我就不截了。。。

参考博客:https://blog.csdn.net/u013815546/article/details/68944039
感谢大佬

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值