spring-cloud-zuul及其应用

概述

网关为我们管理api接口提供的主要功能

  • 管理api接口
  • 适配协议
  • 安全认证
  • 转发路由
  • 限制流量
  • 监控日志
  • 防止爬虫
  • 灰度发布
  • 服务聚合

不建议使用zuul1作为线上网关使用,大家可以使用zuul2或者是spring-cloud-gateway作为微服务的网关

假如你使用zuul2作为网关的话,zuul1可以学习使用,其实基本功能类似,只是在底层改为netty去转发http请求

zuul1提供的功能

zuul的核心功能是过滤器,通过过滤器实现

  • 动态路由
  • 请求监控
  • 认证鉴权
  • 压力测试
  • 灰度发布

坑一

  • 注意zuul1和springboot的版本适配问题(zuul后面已经被spring-cloud干掉了,不在支持集成使用)
<dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>

基础的重定向,从path重定向到url

spring.application.name=zuul-gateway-static
server.port=9011
server.address=127.0.0.1

debug=true

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=ALWAYS

zuul.routes.test1.path=/abc/**
zuul.routes.test1.url=http://www.example.com/

zuul.routes.localpath.path=/a/**
zuul.routes.localpath.url=forward:/a

zuul.routes.userinfo.path=/user/**
zuul.routes.userinfo.service-id=zuul-user
zuul.routes.userinfo.stripPrefix=false
zuul.routes.userinfo.sensitive-headers=true
zuul.routes.userinfo.customSensitiveHeaders=true

zuul.retryable=true
ribbon.okhttp.enabled=true


eureka.instance.ip-address=127.0.0.1
eureka.client.serviceUrl.defaultZone=http://tom:123456@localhost:9010/eureka/
eureka.instance.preferIpAddress=true
eureka.instance.instance-id=${spring.application.name}:${server.address}:${server.port}
eureka.client.healthcheck.enabled=true
eureka.instance.lease-expiration-duration-in-seconds=20
eureka.instance.lease-renewal-interval-in-seconds=15

logging.config=classpath:logback.xml

查看所有routers的配置

  1. 访问服务:
  2. http://localhost:9011/abc/123
  3. 基础的匹配
zuul.routes.test1.path=/abc/**
zuul.routes.test1.url=http://www.example.com/
  1. 本地跳转zuul.routes.localpath.path=/a/**
    zuul.routes.localpath.url=forward:/a
  2. 使用eureka的匹配
  3. http://localhost:9011/user/1234
zuul.routes.userinfo.path=/user/**
zuul.routes.userinfo.service-id=zuul-user
zuul.routes.userinfo.stripPrefix=false
zuul.routes.userinfo.sensitive-headers=true
zuul.routes.userinfo.customSensitiveHeaders=true
  1. 自定义过滤器
  2. pre 请求被路由之前调用
  3. route 请求路由时调用
  4. post 在route和error过滤器之后调用
  5. error 在请求发生错误时调用

代码路径:

https://github.com/beckbikang/spring-cloud/tree/main/kzuul

实现动态路由的网关才是真正可用的网关

  1. 先上代码,基于redis存储了配置信息
  2. 继承SimpleRouteLocator类和实现了RefreshableRouteLocator接口

最最核心的代码了,如果需要实现动态路由,可以基于这个去改造了

package cn.beckbi.route;

import cn.beckbi.route.entity.ZuulEntity;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.*;


/**
 * @program: spring-cloud
 * @description:
 * @author: bikang
 * @create: 2022-08-14 13:04
 */
public class DynamicRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

    private static final String ZUUL_EKY = "LOCAL_ZUUL_RULES_REDIS_KEY";

    private ZuulProperties zuulProperties;

    public static String getRouteKey() {
        return ZUUL_EKY;
    }

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    public DynamicRouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties);
        this.zuulProperties = properties;
    }

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

    @Override
    protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
        Map<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap(20);

        zuulProperties.getRoutes().clear();

        routesMap.putAll(super.locateRoutes());

        routesMap.putAll(locateRoutesFromRedis());

        zuulProperties.getRoutes().putAll(routesMap);

        return routesMap;
    }

    private Map<? extends String, ? extends ZuulProperties.ZuulRoute> locateRoutesFromRedis() {
        LinkedHashMap routesMap = new LinkedHashMap();

        String routeData = stringRedisTemplate.opsForValue().get(ZUUL_EKY);
        List<ZuulEntity> zuulEntityList = JSONObject.parseObject(routeData, new TypeReference<List<ZuulEntity>>(){});

        for (ZuulEntity zuulEntity: zuulEntityList){
            routesMap.put(zuulEntity.getPath(),new ZuulProperties.ZuulRoute(
                    zuulEntity.getId(),
                    zuulEntity.getPath(),
                    zuulEntity.getServiceId(),
                    zuulEntity.getUrl(),
                    zuulEntity.isStripPrefix(),
                    zuulEntity.getRetryable(),
                    new LinkedHashSet(1)));
        }
        return routesMap;
    }

    @Override
    public Collection<String> getIgnoredPaths() {
        return super.getIgnoredPaths();
    }

    @Override
    public List<Route> getRoutes() {
        return super.getRoutes();
    }

    @Override
    public Route getMatchingRoute(String path) {
        return super.getMatchingRoute(path);
    }
}

刷新路由

直接转发

基于eureka的路由

具体代码可以看这个:

https://github.com/beckbikang/spring-cloud/tree/main/kzuul

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容