zuul 动态网关路由

介绍: zuul的主要功能是路由和过滤器。

第一步:pom加入依赖包
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
   <groupId>com.marcosbarbero.cloud</groupId>
   <artifactId>spring-cloud-zuul-ratelimit</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-zuul</artifactId>
   <version>1.4.2.RELEASE</version>
</dependency>
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
</dependency>
第二步:zuul初始配置类
import com.example.route.ZuulRouteLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/7/23
 * @Description: 路由初始化
 **/
@Configuration
public class ZuulConfig {

    @Autowired
    private ZuulProperties zuulProperties;
    @Autowired
    private ServerProperties server;

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

}
第三步:动态路由类
import com.example.constant.ZuulRouteEnum;
import com.example.pojo.vo.ZuulRouteVO;
import com.example.tools.RedisTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/7/23
 * @Description: 动态路由
 **/
@Slf4j
public class ZuulRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private ZuulProperties properties;

    public ZuulRouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties);
        this.properties = properties;
        log.info("servletPath:{}", servletPath);
    }


    @Override
    public void refresh() {
        doRefresh();
    }

    @Override
    protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
        LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
        //从application.properties中加载路由信息
        routesMap.putAll(super.locateRoutes());
        //从redis中加载路由信息
        routesMap.putAll(locateRoutesFromRedis());
        log.info("网关路由配置 --> {}", routesMap);
        //优化一下配置
        LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
        for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
            String path = entry.getKey();
            if (!path.startsWith("/")) {
                path = "/" + path;
            }
            if (StringUtils.hasText(this.properties.getPrefix())) {
                path = this.properties.getPrefix() + path;
                if (!path.startsWith("/")) {
                    path = "/" + path;
                }
            }
            values.put(path, entry.getValue());
        }
        return values;
    }

    /**
     * @Author: 凉白开不加冰
     * @Date: 2018/7/23 18:14
     * @Description: 从redis获取路由信息
     **/
    private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromRedis() {
        Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
        List<ZuulRouteVO> results = RedisTools.hget(stringRedisTemplate,ZuulRouteEnum.ZUUL_ROUTE_LIST.getKey(), ZuulRouteVO.class);
        if(results==null){
            return routes;
        }
        for (ZuulRouteVO result : results) {
            if (StringUtils.isEmpty(result.getPath())) {
                continue;
            }
            if (!result.getEnabled()) {
                continue;
            }
            ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
            try {
                BeanUtils.copyProperties(result, zuulRoute);
            } catch (Exception e) {
                log.error("=============加载网关路由失败==============", e);
            }
            routes.put(zuulRoute.getPath(), zuulRoute);
        }
        return routes;
    }

}
路由限流枚举
import lombok.Getter;
import lombok.Setter;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/7/23
 * @Description: 路由限流枚举
 **/
public enum ZuulRouteEnum {

    /**
     * 路由枚举
     */
    ZUUL_ROUTE_LIST("zuul:route:list");

    @Getter
    @Setter
    private String key;

    ZuulRouteEnum(String key) {
        this.key = key;
    }

    public static ZuulRouteEnum get(String key) {
        for (ZuulRouteEnum c : ZuulRouteEnum.values()) {
            if (c.key == key) {
                return c;
            }
        }
        return null;
    }
}
路由参数
import lombok.Data;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/7/23
 * @Description: 路由参数
 **/
@Data
public class ZuulRouteVO {
    /**
     * id主键
     */
    private String id;

    /**
     * 网关路由访问地址
     */
    private String path;

    /**
     * 服务地址
    **/
    private String url;

    /**
     * 服务id
     */
    private String serviceId;

    /**
     * 是否启用 true启用 false不启用
     */
    private Boolean enabled;

}
redis工具类
import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/11/20
 * @Description: redis工具类
 **/
public class RedisTools {

    public static <T> List<T> hget(StringRedisTemplate stringRedisTemplate,String key,Class<T> clazz){
        List<Object> list = stringRedisTemplate.opsForHash().values(key);
        return JSON.parseArray(list.toString(), clazz);
    }

    public static void hset(StringRedisTemplate stringRedisTemplate,String h,String key,String value){
        stringRedisTemplate.opsForHash().put(h,key,value);
    }

    public static Boolean existsHash(StringRedisTemplate stringRedisTemplate,String h,String key){
        return stringRedisTemplate.opsForHash().hasKey(h,key);
    }

}

服务启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class MicromserviceZuulApplication {

   public static void main(String[] args) {
      SpringApplication.run(MicromserviceZuulApplication.class, args);
   }
}
路由刷新接口
/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/7/23
 * @Description: 刷新路由
 **/
public interface RefreshRouteService {
    /**
     * @Author: 胡成
     * @Date: 2018/7/23 16:35
     * @Description: 刷新路由
     **/
    void refreshRoute();
}
路由刷新实现类
import com.example.service.RefreshRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2018/7/23
 * @Description: 路由刷新业务
 **/
@Service
public class RefreshRouteServiceImpl implements RefreshRouteService {

    @Autowired
    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteLocator routeLocator;

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

第五步:redis中存放路由信息

{
   "id": "test",
   "serviceId": "",
   "path": "/order/**",
   "url": "http://192.168.0.111:9092",
   "enabled": true
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot Zuul是一个在微服务架构中用于网关路由和过滤的组件。它允许我们通过定义动态路由配置来控制请求的转发。 要在Spring Boot Zuul中配置动态路由转发,我们需要执行以下几个步骤: 1. 添加Zuul依赖:在pom.xml文件中添加Zuul的依赖,以便我们可以使用它的功能。 2. 创建Zuul配置类:创建一个Java类来配置Zuul。在该类上添加`@EnableZuulProxy`注解,以启用Zuul代理和路由功能。可以使用`@Configuration`注解标记该类为配置类。 3. 配置动态路由:在配置类中,使用`@ConfigurationProperties`注解来加载动态路由的配置,如下所示: ```java @ConfigurationProperties("zuul") public class ZuulConfig { private List<Route> routes; // Getters and setters public static class Route { private String path; private String url; private boolean stripPrefix; // Getters and setters } } ``` 在`ZuulConfig`类中,我们定义了一个内部类`Route`,它表示一条动态路由。我们需要配置每个路由的`path`、`url`和`stripPrefix`属性。 4. 启用动态路由配置:在配置类中添加`@Bean`注解来创建一个`ZuulConfiguration` bean,并使用它来启用动态路由配置。代码如下所示: ```java @Configuration public class ZuulConfig { // ... @Bean public ZuulConfiguration zuulConfiguration() { ZuulConfiguration zuulConfiguration = new ZuulConfiguration(); zuulConfiguration.setRoutes(this.routes); return zuulConfiguration; } } ``` 在`zuulConfiguration()`方法中,我们创建了一个`ZuulConfiguration`对象,并将动态路由配置赋值给它。 5. 测试路由转发:完成以上步骤后,我们可以通过访问定义的动态路由来测试路由转发是否正常工作。根据配置的`path`属性,Zuul将会把请求转发到相应的`url`。 这是使用Spring Boot Zuul配置动态路由转发的基本步骤。通过配置动态路由,我们可以动态地将请求转发到不同的后端服务,并根据路由规则对请求进行过滤和重定向。这使得网关服务在微服务架构中起到关键的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值