美文网首页SpringCloud
【SpringCloud】Zuul的使用

【SpringCloud】Zuul的使用

作者: 扮鬼之梦 | 来源:发表于2019-08-09 15:38 被阅读0次

一、zuul作用

1.微服务网关

2.全局拦截

3.局域网透过

4.限流

二、微服务网关

1.新建zull项目

2.添加yml配置

server:
  port: 80
spring:
  application:
    name: demo-zuul
eureka:
  client: 
    enabled: true #该客户端是否可用
    service-url: 
      defaultZone: http://localhost:8761/eureka #注册中心地址
    register-with-eureka: true #注册该服务,默认为true
    fetch-registry: true #获取服务列表,默认为true

3.开启网关功能(启动类添加@EnableZuulProxy注解),配置动态路由规则

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy//开启网关功能
public class DemoZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoZuulApplication.class, args);
    }

    //配置动态路由规则
    @Bean
    public PatternServiceRouteMapper getPatternServiceRouteMapper() {
        return new PatternServiceRouteMapper("(?<name>^.+)", "${name}");
    }
}

4.启动项目

通过网关地址+微服务名可以访问到在注册中心注册了的微服务。


例如现在有一个demo-zuul网关,两个demo-member服务。
通过访问网关的地址(http://localhost)来访问demo-member服务的接口。
访问地址为:http://localhost/demo-member/user/loadBalance
这里会先通过url中的/demo-member 路由到demo-member服务中,再到demo-member服务里面去找/user/loadBalance接口。


这边我启动了两个demo-member服务,顺便测试了下使用zuul来访问微服务的负载均衡能力。

三、全局拦截

1.添加一个验证token有效性的拦截器


package com.thy.filter;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

@Component
public class TokenFilter extends ZuulFilter {
    /**
     * 是否拦截
     */
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        // RequestContext ctx = RequestContext.getCurrentContext();
        // ctx.getBoolean("isOk");
        HttpServletRequest request = ctx.getRequest();
        String requestURI = request.getRequestURI();
        //排除拦截的url
        if (requestURI.equals("/demo-member/user/loadBalance")) {
            return false;
        }
        return true;
    }

    /**
     * 拦截下来干嘛
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        // ctx.set("isOk",true); // 可以在上下文里面设置一个key,在下一次拦截时,就可以获取到
        if (null == token) {
            ctx.setResponseBody("token is null");
            ctx.setResponseStatusCode(400);
            ctx.setSendZuulResponse(false);
            return null;
        }
        if (!"123456".equals(token)) {
            ctx.setResponseBody("token is error");
            ctx.setResponseStatusCode(400);
            ctx.setSendZuulResponse(false);
            return null;
        }
        ctx.setSendZuulResponse(true);
        return null;
    }
    
    /**
     * 拦截类型 pre route前拦截 route route时拦截 post 两者之间 error 发现错误拦截
     */
    @Override
    public String filterType() {
        // TODO Auto-generated method stub
        return "pre";
    }
    
    /**
     * 拦截的次序 越小,越先执行
     */
    @Override
    public int filterOrder() {
        // TODO Auto-generated method stub
        return 0;
    }
    
}

四、局域网透过


Nginx也可以做

五、跨域请求

1.介绍


html代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Page Title</title>
        <script src="jquery.js"></script>
    </head>
    <body>
        <h1>跨域请求测试</h1>
    </body>
    <script>
        $.get("http://localhost/demo-member/user/loadBalance?token=123456",function(res){
        alert(res.data);
        })
    </script>
</html>

会有跨域访问的问题


2.跨域问题解决方案

(1).Jsonp(都可以)
(2).CorsMapping(web-mvc)
(3).CorsFilter(zuul)
(4).Spring安全(Spring安全框架)

zuul配置CorsFilter解决跨域请求问题

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class ZuulFilterConfig {
    // 在zuul里面解决跨域请求,有2 种方法,第一种就是注入一个CorsFilter ,2:spring 自带的安全框架
    @Bean
    public CorsFilter getCorsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名
        config.addAllowedOrigin("*");
        //允许所有请求头
        config.addAllowedHeader("*");
        //允许所有方法
        config.addAllowedMethod("*");
        //允许cookie
        config.setAllowCredentials(true);
        //预检请求的缓存时间,在此时间内,相同的跨域请求不在验证
        config.setMaxAge(7200*100l);
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(urlBasedCorsConfigurationSource );
    }
}

六、限流

1.介绍

DDOS:(没法避免,只能通过限流来解决)
分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。
限流:
一个客户端,1 min访问我100(恶意的)
拦截用户的请求,看这个ip,1 min访问了我100次就拦截

2.导入依赖

<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>1.7.2.RELEASE</version>
</dependency>

3.添加配置

zuul:
  ratelimit: 
    enabled: true #开启限流
    #repository: REDIS   #选择存储的位置,默认在内存里面的HashMap存储
    behind-proxy: true #代理之后
    default-policy-list: #可选 - 针对所有的路由配置的策略,除非特别配置了policies
      - limit: 10 #可选 - 每个刷新时间窗口对应的请求数量限制
        quota: 1000 #可选-  每个刷新时间窗口对应的请求时间限制(秒)
        refresh-interval: 60 # 刷新时间窗口的时间,默认值 (秒)
        type: #可选 限流方式
          - user
          - origin
          - url

4.结果

因为配置中limit配置的是10,refresh-interval是60,所以在60s内第11次访问接口时会抛出以下异常。


相关文章

网友评论

    本文标题:【SpringCloud】Zuul的使用

    本文链接:https://www.haomeiwen.com/subject/gclhjctx.html