Spring Cloud(六):Zuul API网关测试

Zuul

API 网关

  • 微服务系统统一的调用入口
  • 统一的权限校验
  • 集成ribbon
  • 集成hystrix
    Spring Cloud(六):Zuul API网关测试_第1张图片
    zuul API 网关,为微服务应用提供统一的对外访问接口。
    zuul 还提供过滤器,对所有微服务提供统一的请求校验。

统一的调用入口

  1. zuul 依赖、eureka client依赖、sp01
    Spring Cloud(六):Zuul API网关测试_第2张图片

  2. yml

# 配置调用转发规则
# 下面是 zuul 默认的转发规则
# 如果不手动配置,zuul可以根据注册表的注册信息进行自动配置
zuul:
  routes:
    item-service: /item-service/**
    user-service: /user-service/**
    order-service: /order-service/**
  1. 启动类注解: @EnableZuulProxy
    Spring Cloud(六):Zuul API网关测试_第3张图片

zuul 请求过滤

统一权限校验

通过 zuul 过滤器,可以判断用户是否有权限访问后台服务,如果没有权限可以阻止用户继续访问

判断用户是否登录,登录猜允许访问商品服务
http://localhost:3001/item-service/u45y45435 没有登录不允许访问

http://localhost:3001/item-service/u45y45435?token=y45343t4 有token认为登录过,允许访问

Spring Cloud(六):Zuul API网关测试_第4张图片

添加过滤器代码

1.继承ZuulProxy
2.添加@Component注解
zuul会对过滤器进行自动配置

package cn.tedu.sp11.filter;

import cn.tedu.sp01.util.JsonResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
@Slf4j
public class AccessFilter extends ZuulFilter {

    //设置过滤器的类型:pre,routing,post,error
    @Override
    public String filterType() {
        //设置成前置过滤器
        return FilterConstants.PRE_TYPE;
    }

    //设置过滤器的顺序号
    @Override
    public int filterOrder() {
        //默认有5个过滤器了,把它放到第6个
        return 6;
    }

    /*
    对当前请求进行判断
    针对当前请求,是否要执行过滤代码
     */
    @Override
    public boolean shouldFilter() {
        //如果调用item-service,执行过滤代码判断权限
        //否则不执行过滤代码
        //获取调用的服务id
        RequestContext ctx=RequestContext.getCurrentContext();
        String serviceId=(String)ctx.get(FilterConstants.SERVICE_ID_KEY);
        //判断是不是item-service
        return "item-service".equals(serviceId);
    }

    //过滤代码
    @Override
    public Object run() throws ZuulException {
        //获取request对象
        RequestContext ctx=RequestContext.getCurrentContext();
        HttpServletRequest request=ctx.getRequest();
        //接收token参数
        String token=request.getParameter("token");
        //如果没有收到token参数,认为用户没有登录,组织继续调用
        if(StringUtils.isBlank(token)){
            //阻止继续嗲用
            ctx.setSendZuulResponse(false);

            //从网关直接返回,设置向客户端发送的响应
            ctx.addZuulResponseHeader("Content-type", "application/json");

            ctx.setResponseBody(JsonResult.err().msg("not login").toString());
        }
        return null; //在当前zull版本中,这个返回值没有任何作用
    }
}

重启服务器测试:
未提交token时:
Spring Cloud(六):Zuul API网关测试_第5张图片
提交token时:
Spring Cloud(六):Zuul API网关测试_第6张图片

zuul 集成 ribbon

默认启用了 ribbon 的负载均衡

默认不启用重试,zuul不推荐启用重试

启用重试:

  1. spring-retry 依赖
		<dependency>
            <groupId>org.springframework.retrygroupId>
            <artifactId>spring-retryartifactId>
        dependency>
  1. yml
   zuul.retryable=true
  1. 重试参数

    有默认参数,可以根据需要进行调整

zuul 集成 hystrix

0配置,已经启用了hystrix

添加降级代码

  1. 实现 FallbackProvider 接口,在子类中实现降级代码
  2. @Component

zuul的自动配置,会自动配置降级类
Demo:

package cn.tedu.sp11.fallback;

import cn.tedu.sp01.util.JsonResult;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import javax.xml.ws.spi.http.HttpHandler;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Component
public class ItemFB implements FallbackProvider {

    /*
    返回service—id
    针对那个服务进行降级
     */

    /**
     * 返回:
     * "*"   -针对所有服务进行降级
     * null  -针对所有服务进行降级
     * @return
     */
    @Override
    public String getRoute() {
        return "item-service";
    }

    /**
     * 设置向客户端返回的降级响应
     * @param route
     * @param cause
     * @return
     */
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.OK.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.OK.getReasonPhrase();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                //JsonResult - {code:200,msg:"调用后台商品服务失败",data:null}
                String json=JsonResult.ok().msg("调用后代服务商品失败").toString();
                return new ByteArrayInputStream(json.getBytes("UTF-8"));
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders header=new HttpHeaders();
                header.add("Content-Type", "application/json;charset=UTF-8");
                return header;
            }
        };
    }
}

Zuul 和 Feign场景

  • 都可以调用后台服务
  • 都可以集成 ribbon
  • 都可集成 hystrix

zuul

  • 部署在所有微服务项目之前

  • 网关一般是一个独立的服务,与业务无关

  • 不推荐启用重试
    会造成后台服务压力翻倍
    重试尽量不部署在最前面,越往后越好

feign

  • 部署在微服务内部,服务和服务之间调用

  • 不推荐启用 hystrix
    一般在最前面进行降级和熔断,类似于电箱断路器,只在入户位置部署,
    不在微服务内部部署hystrix,否则会引起混乱

你可能感兴趣的:(spring,cloud,spring,cloud,微服务,java,过滤器,网关)