一起来学SpringCloud 服务网关Zuul

序言

​ 路由是微服务体系结构的一个组成部分。例如 / 可以映射到您的Web应用程序,/api/order映射到用户服务,/api/product映射到商店服务。 Zuul 默认和 Ribbon 结合实现了负载均衡的功能。

此文章仅限入门 SpringCloud版本为 Greenwich

2016 年前后基于 NIO 的 Zuul2 开始开发,一直到 2018 年才发布,彼时,市场上类似产品层出不穷,Zuul 已经失去了它的先发优势,Spring Cloud 甚至到现在都没有对 Zuul2 提供支持,Spring Cloud Gateway 等产品的出现和 Zuul2 的频繁跳票,便秘式发布也让 Zuul 走下神坛,逐渐沦落为性能一般,需要被替换的代名词。 好吧,但是基本的生产使用也是没有什么问题的。

使用

首先呢加入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- eureka server-->
        <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>
    </dependencies>

然后在yml里配置下

# 增加 Zuul 配置
spring:
  application:
    name: spring-cloud-action-zuul
    
server:
  port: 8080

zuul:
  routes:
    api-a:
      path: /api/order/**
      serviceId: spring-cloud-action-server-order
    api-b:
      path: /api/product/**
      serviceId: spring-cloud-action-server-product


eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
    hostname: localhost
  client:
    service-url:
      # defaultZone 千万别写成 default-zone
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/

在yml中呢 path: /api/order/** 意思就是把 spring-cloud-action-server-order 服务下的接口资源全部代理到 **

比如http://spring-cloud-action-server-order/getOrder 就代理到http://api/order/getOrder

然后是启动类

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

过滤器

假设调用服务需要传递token,那么在网关这里就可以做请求,把那些没有传token的请求统统过滤掉。


/**
 * 网关认证过滤器(Demo演示,实际根据自身业务考虑实现)
 *
 * @author
 */
@Component
public class GatewayZuulFilter extends ZuulFilter {

    /**
     * per:路由之前,如实现认证、记录调试信息等
     * routing:路由时
     * post:路由后,比如添加HTTP Header
     * error:发生错误时调用
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器顺序,类似@Filter中的order
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        if (token == null) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(404);
            ctx.setResponseBody("token cannot be empty");
        }
        return null;
    }
}

然后呢在匹配不到路由的时候呢可以去配置一个路由的失败回调器

/**
 * @program: spring-cloud-some-project
 * @author: fulin
 * 配置网关路由失败时的回调
 * @create: 2019-10-29 10:26
 **/
@Component
public class ServerFeignFallback implements FallbackProvider {
    @Override
    public String getRoute() {
        // ServiceId,如果需要所有调用都支持回退,则 return "*" 或 return null
        return null;
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        /**
         * 网关向 api 服务请求失败了,但是消费者客户端向网关发起的请求是成功的,
         * 不应该把 api 的 404,500 等问题抛给客户端
         * 网关和 api 服务集群对于客户端来说是黑盒
         * @return
         * @throws IOException
         */
        return new ClientHttpResponse() {****};
    }
}


跨域

默认情况下,Zuul将所有跨源请求(CORS)路由到服务。如果您希望Zuul处理这些请求,可以通过提供自定义WebMvcConfigurer 来完成 ,配置这样一个bean就可以了

@Bean
public WebMvcConfigurer corsConfigurer() {
   return new WebMvcConfigurer() {
      public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "POST")
            .allowedHeaders("*");
      }
   };
}

此文章仅限入门,切记啊不会用找不到多去官网看文档!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值