007SpringCloud--Zuul路由网关

目录

Zull路由网关

什么是zuul?

Zuul 能干嘛?

07-springcloud-zuul-9527

1.pom.xml

2.application.yml

3.ZuulApplication_9527

测试1:

解决方法

BeanPostProcessor

 测试2:


Zull路由网关

概述

什么是zuul?

Zull包含了对请求的路由(用来跳转的)和过滤两个最主要功能:

其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。

在这里插入图片描述

注意:Zuul 服务最终还是会注册进 Eureka

提供:代理 + 路由 + 过滤 三大功能!

Zuul 能干嘛?

  • 路由
  • 过滤

官方文档:https://github.com/Netflix/zuul/

案例

07-springcloud-zuul-9527

1.pom.xml

        <!--zull路由网官-->
        <!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-zuul -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    <dependencies>

        <!--zull路由网官-->
        <!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-zuul -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

        <!--hystrix-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

        <!--hystrix-dashboard 监控-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix-dashboard -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

        <!--Eureka: Ribbon需要从Eureka服务中心获取要拿什么-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--新加入-->

        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-loadbalancer</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-core</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-ribbon</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

        <!--新加入-->

        <!--实体类 + web -->
        <dependency>
            <groupId>com.gh</groupId>
            <artifactId>01-springcloud-api</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>


    </dependencies>

2.application.yml

server:
  port: 9527

spring:
  application:
    name: springcloud-zuul-gateway
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7001.com:7002/eureka/,http://eureka7001.com:7003/eureka/
  instance:
    # 修改eureka上的默认描述信息
    instance-id: springcloud-zuul
    prefer-ip-address: true

info:
  app.name: gh-springcloud
  compony.name: blog.gh.com

management:
  info:
    env:
      enabled:
  endpoints:
    web:
      exposure:
        include: "*"
zuul:
  routes:
    mydept.serviceId: 02-SPRINGCLOUD-PROVIDER-DEPT-8001 #自己服务名
    mydept.path: /mydept/**
      # ignored-services : springcloud-provider-dept 不能使用springcloud-provider-dept这个访问了
#  ignored-services: springcloud-provider-dept
  ignored-services: "*"   # "*"表示全部
  prefix: /gh  #设置公共前缀

3.ZuulApplication_9527

@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication_9527 {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication_9527.class,args);
    }
}

测试1:

会出现500

解决思路:

 找不到ErrorController中的getErrorPath()方法

解决方法

方法一: 使用低版本spring boot兼容spring-cloud-starter-netflix-zuul

使用spring boot 2.4.8可以兼容spring-cloud-starter-netflix-zuul

方法二: 创建BeanPostProcessor拦截 lookupHandler 方法的调用

BeanPostProcessor

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Fix for Zuul configuration with Spring Boot 2.5.x + Zuul - "NoSuchMethodError: ErrorController.getErrorPath()":
 */
@Configuration
public class ZuulConfiguration {
  /**
   * The path returned by ErrorController.getErrorPath() with Spring Boot < 2.5
   * (and no longer available on Spring Boot >= 2.5).
   */
  private static final String ERROR_PATH = "/error";
  private static final String METHOD = "lookupHandler";

  /**
   * Constructs a new bean post-processor for Zuul.
   *
   * @param routeLocator    the route locator.
   * @param zuulController  the Zuul controller.
   * @param errorController the error controller.
   * @return the new bean post-processor.
   */
  @Bean
  public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator,
                                             @Autowired ZuulController zuulController,
                                             @Autowired(required = false) ErrorController errorController) {
    return new ZuulPostProcessor(routeLocator, zuulController, errorController);
  }

  private enum LookupHandlerCallbackFilter implements CallbackFilter {
    INSTANCE;

    @Override
    public int accept(Method method) {
      if (METHOD.equals(method.getName())) {
        return 0;
      }
      return 1;
    }
  }

  private enum LookupHandlerMethodInterceptor implements MethodInterceptor {
    INSTANCE;

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
      if (ERROR_PATH.equals(args[0])) {
        // by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the 
        // NoSuchMethodError 
        return null;
      }
      return methodProxy.invokeSuper(target, args);
    }
  }

  private static final class ZuulPostProcessor implements BeanPostProcessor {

    private final RouteLocator routeLocator;
    private final ZuulController zuulController;
    private final boolean hasErrorController;

    ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) {
      this.routeLocator = routeLocator;
      this.zuulController = zuulController;
      this.hasErrorController = (errorController != null);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      if (hasErrorController && (bean instanceof ZuulHandlerMapping)) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(ZuulHandlerMapping.class);
        enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler
        enhancer.setCallbacks(new Callback[] {LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE});
        Constructor<?> ctor = ZuulHandlerMapping.class.getConstructors()[0];
        return enhancer.create(ctor.getParameterTypes(), new Object[] {routeLocator, zuulController});
      }
      return bean;
    }
  }
}

 测试2:

在这里插入图片描述

上图是没有经过Zull路由网关配置时,服务接口访问的路由,可以看出直接用微服务(服务提供方)名称去访问,这样不安全,不能将微服务名称暴露!

zuul:
  routes:
    mydept.serviceId: 02-SPRINGCLOUD-PROVIDER-DEPT-8001 #自己服务名
    mydept.path: /mydept/**     # 别名
      # ignored-services : 02-SPRINGCLOUD-PROVIDER-DEPT-8001 不能使用02-SPRINGCLOUD-PROVIDER-DEPT-8001这个访问了
#  ignored-services: 02-SPRINGCLOUD-PROVIDER-DEPT-8001
  ignored-services: "*"   # "*"表示全部
  prefix: /gh  #设置公共前缀

所以经过Zull路由网关配置后,访问的路由为:

在这里插入图片描述

我们看到,微服务名称被替换并隐藏,换成了我们自定义的微服务名称mydept,同时加上了前缀haust,这样就做到了对路由fan访问的加密处理!

http://www.gh-xiaohe.com:9527/gh/mydept/dept/1

http://www.gh-xiaohe.com:9527/02-springcloud-provider-dept-8001/dept/list

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gh-xiaohe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值