You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Zuul 2中仅通过代码声明路由(无需配置文件及Spring组件)

纯代码实现Zuul 2路由(无配置文件、无Spring/Eureka依赖)

基于Zuul 2的原生机制,我们可以通过自定义路由注册表+Ribbon负载均衡器初始化的方式,完全用代码替代配置文件声明路由,实现类似Spring Cloud Gateway的路由定义风格。以下是具体实现方案:


1. 定义路由模型与注册表

首先创建路由配置类和全局注册表,集中管理所有路由规则:

RouteConfig.groovy(路由模型)

package info.novatec.zuul2.config

class RouteConfig {
    // 路径匹配规则(支持**通配符)
    String pathPattern
    // 路由唯一标识(对应Ribbon的VIP)
    String vip
    // 后端服务器列表
    List<String> servers

    RouteConfig(String pathPattern, String vip, List<String> servers) {
        this.pathPattern = pathPattern
        this.vip = vip
        this.servers = servers
    }
}

RouteRegistry.groovy(路由注册表)

package info.novatec.zuul2.config

import java.util.regex.Pattern

class RouteRegistry {
    // 初始化所有路由规则,可按需扩展
    private static final List<RouteConfig> ROUTES = [
        new RouteConfig("/hello/**", "hello-service", ["localhost:8081"]),
        new RouteConfig("/test/**", "test-service", ["localhost:8080"])
    ]

    // 根据请求路径匹配路由
    static RouteConfig findMatchingRoute(String path) {
        return ROUTES.find { route ->
            Pattern.compile(route.pathPattern.replace("**", ".*")).matcher(path).matches()
        }
    }

    // 获取VIP与服务器列表的映射关系,供Ribbon初始化使用
    static Map<String, List<String>> getVipToServersMap() {
        return ROUTES.collectEntries { [(it.vip): it.servers] }
    }
}

2. 修改路由过滤器

替换原有的Routes.groovy,通过注册表匹配路由并设置Zuul上下文:

package info.novatec.zuul2.filters.inbound

import com.netflix.zuul.context.SessionContext
import com.netflix.zuul.filters.endpoint.ProxyEndpoint
import com.netflix.zuul.filters.http.HttpInboundSyncFilter
import com.netflix.zuul.message.http.HttpRequestMessage
import info.novatec.zuul2.config.RouteRegistry

class Routes extends HttpInboundSyncFilter {

    @Override
    HttpRequestMessage apply(HttpRequestMessage request) {
        SessionContext context = request.getContext()
        String path = request.getPath()

        RouteConfig matchedRoute = RouteRegistry.findMatchingRoute(path)
        if (matchedRoute) {
            // 设置代理端点
            context.setEndpoint(ProxyEndpoint.class.getCanonicalName())
            // 设置路由VIP,关联Ribbon负载均衡器
            context.setRouteVIP(matchedRoute.vip)
            // 可选:移除路径前缀(比如把/hello/api转为/api)
            // String newPath = path.replaceFirst(matchedRoute.pathPattern.replace("**", ""), "")
            // request.setPath(newPath)
        } else {
            // 无匹配路由时返回404
            context.setResponseStatusCode(404)
            context.setEndpoint(null)
        }

        return request
    }

    @Override
    int filterOrder() {
        return 0
    }

    @Override
    boolean shouldFilter(HttpRequestMessage request) {
        return true
    }
}

3. 初始化Ribbon负载均衡器

创建初始化类,在Zuul启动时为每个路由VIP绑定对应的服务器列表:

RibbonLoadBalancerInitializer.groovy

package info.novatec.zuul2.init

import com.netflix.client.config.DefaultClientConfigImpl
import com.netflix.loadbalancer.DynamicServerListLoadBalancer
import com.netflix.loadbalancer.LoadBalancerManager
import com.netflix.loadbalancer.Server
import com.netflix.loadbalancer.StaticServerList
import info.novatec.zuul2.config.RouteRegistry

class RibbonLoadBalancerInitializer {
    static void init() {
        def vipToServers = RouteRegistry.vipToServersMap()
        vipToServers.each { vip, servers ->
            // 将服务器地址转为Ribbon Server对象
            List<Server> serverList = servers.collect { new Server(it) }
            // 初始化Ribbon客户端配置
            DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl()
            clientConfig.loadProperties(vip)
            // 创建动态服务器列表负载均衡器
            DynamicServerListLoadBalancer<Server> loadBalancer = new DynamicServerListLoadBalancer<>(
                clientConfig, null, null, new StaticServerList<>(serverList), null
            )
            // 可选:自定义负载均衡策略(比如随机策略)
            // loadBalancer.setRule(new com.netflix.loadbalancer.RandomRule())
            // 将负载均衡器注册到Ribbon管理器
            LoadBalancerManager.getInstance().setLoadBalancer(vip, loadBalancer)
        }
    }
}

4. 修改Zuul启动类

在启动时先初始化Ribbon负载均衡器,再启动Zuul服务器:

package info.novatec.zuul2

import com.netflix.zuul.ZuulServer
import info.novatec.zuul2.init.RibbonLoadBalancerInitializer

class ZuulServerMain {
    static void main(String[] args) {
        // 初始化Ribbon负载均衡器
        RibbonLoadBalancerInitializer.init()
        // 启动Zuul服务器
        ZuulServer server = new ZuulServer()
        server.init()
        server.start()
    }
}

5. 清理配置文件

移除application.properties中所有路由和Eureka相关配置,最终配置如下:

zuul.server.port.main=9001

# 过滤器配置
zuul.filters.root=src/main/groovy/info/novatec/zuul2/filters
zuul.filters.locations=${zuul.filters.root}/inbound,${zuul.filters.root}/outbound,${zuul.filters.root}/endpoint
zuul.filters.packages=com.netflix.zuul.filters.common

@next=application-${@environment}.properties

方案说明

  • 完全脱离配置文件:路由规则、后端服务器列表均通过代码声明,可动态修改或扩展
  • 无Spring/Eureka依赖:基于Zuul 2和Ribbon原生API实现,无需引入Spring生态组件
  • 支持自定义扩展:可添加路径重写、负载均衡策略、路由动态刷新等功能

内容的提问来源于stack exchange,提问作者kanai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:57:36