Zuul网关的快速使用

2022-12-21 09:10:12 浏览数 (2)

导包

SpringBoot和SpringCloud的依赖就不提及了,相信你自己都导入了,注意版本对应关系

代码语言:javascript复制
    <dependencies>
<!--        zuul-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
<!--        eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

启动类添加 @EnableZuulProxy 注解和Eureka的注解

代码语言:javascript复制
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy //开启Zuul的网关功能
@EnableDiscoveryClient //开启Eureka客户端发现功能
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

编写配置文件

代码语言:javascript复制
server:
  port: 10010 #服务端口
spring:
  application:
    name: api-gateway #指定服务名

zuul: #混淆写法,也是最简洁的写法
  ignored-services:
    - eureka-server	# Eureka的服务名称
  prefix: /api	#添加的前缀

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

访问 http://localhost:10010/api/user-consumer/方法地址,测试

Zuul的过滤器使用

完成上面的操作可以用前缀 服务名称 服务地址访问,但有一个问题,加上api就可以直接访问服务的方法,这样是不安全的,所有要用到了Zuul的过滤器ZuulFilter ZuulFilter是过滤器的顶级父类,这里看一下其中定义的4个最重要的方法:

代码语言:javascript复制
public abstract ZuulFilter implements IZuulFilter{

    abstract public String filterType();  // 类型 前置 路由中 路由后  error类型

    abstract public int filterOrder();   // 过滤器的执行顺序 这个返回值越小就越先执行
    
    boolean shouldFilter();// 来自IZuulFilter   是否要进入到run方法中

    Object run() throws ZuulException;// IZuulFilter  核心方法
}

以上方法和其他方法:

  • filterType方法:返回字符串,代表过滤器的类型。包含以下4种:
  • pre方法:请求在被路由之前执行
  • route方法:在路由请求时调用
  • post方法:在routing和errror过滤器之后调用
  • error方法:处理请求时发生错误调用
  • filterOrder方法:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高
  • shouldFilter方法:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行
  • run方法:过滤器的具体业务逻辑

自定义过滤器

新建一个包:filters 包里新建一个类并extends ZuulFilter类并重写方法 案例:

必须传来一个 access-token 参数,没有就返回一个401状态码

代码语言:javascript复制
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class LoginFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FORM_BODY_WRAPPER_FILTER_ORDER-1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        // 获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        // 获取request对象
        HttpServletRequest request = ctx.getRequest();
        // 获取请求参数
        String token = request.getParameter("access-token");
        // 判断是否存在
        if(StringUtils.isBlank(token)){
            // 不存在,未登录,拦截
            ctx.setSendZuulResponse(false);
            // 设置返回状态码
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;  // 什么都不做 直接进入到微服务中
    }
}

测试一下,没有access-token 是进不去的

负载均衡和熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动在配置文件加上:

代码语言:javascript复制
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000
ribbon:
  ConnectTimeout: 1000 # 连接超时时长 
  ReadTimeout: 2000 # 数据通信超时时长
  MaxAutoRetries: 0  # 当前服务器的重试次数
  MaxAutoRetriesNextServer: 1 # 重试多少次服务,连接的服务如果有集群可以多写几个,可以找到另一个服务,但注意超时时间

0 人点赞