Zuul API网关

Zuul API网关_第1张图片
zuul API网关,为微服务应用提供统一的对外访问接口
zuul 还提供过滤器,对所有微服务提供统一的请求校验

Zuul API 网关

1.新建项目

Zuul API网关_第2张图片
Zuul API网关_第3张图片

2.pom.xml还需要添加公共commons配置类

3.application.yml

  • zuul 路由配置可以省略,缺省以服务id作为访问路径
spring:
  application:
    name: zuul
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

zuul:
  routes:
    item-service: /item-service/**
    user-service: /user-service/**
    order-service: /order-service/**

4.主程序添加注解

添加 @EnableZuulProxy@EnableDIscoverClient 注解

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

}

5.启动服务访问测试

zuul+ribbon负载均衡

  • zuul已经集成了ribbon, 默认已经实现了负载均衡

1.zuul+ribbon重试

pom.xml添加spring-retry依赖

  • 需要导入spring-retry依赖
<dependency>
	<groupId>org.springframework.retry</groupId>
	<artifactId>spring-retry</artifactId>
</dependency>

配置zuul开启重试,并配置 ribbon重试参数

  • 需要开启重试,默认不开启
  • zuul.retryable=true
spring:
  application:
    name: zuul
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

zuul:
  retryable: true

#  routes:
#    item-service: /item-service/**
#    user-service: /user-service/**
#    order-service: /order-service/**
    
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 1000
  MaxAutoRetriesNextServer: 1
  MaxAutoRetries: 1

zuul+hystrix降级

0配置,已经启用了hystrix

降级代码:

实现FallbackProvider接口,实现降级代码

只需要添加 @Component 注解

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500

1.创建降级类

  • getRoute() 方法中指定应用此降级类的服务id,星号或null值可以通配所有服务
@Component
public class ItemFallback implements FallbackProvider {

    /**
     * 当前降级类,对那个服务有效
     * 如果返回 "item-service" , 那么当前降级类只对商品服务有效
     * 如果返回 * 或者null,那么对所有服务都有效
     * @return
     */
    @Override
    public String getRoute() {
        return "item-service";
    }

    @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 {
                // JsonRest : {code:400,msg:"获取商品列表失败!" , data:null}
                String s = JsonResult.err().msg("获取商品列表失败!").toString();
                ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
                return in;
            }

            @Override
            public HttpHeaders getHeaders() {
                // Content-Type:  application-json
                HttpHeaders h = new HttpHeaders();
                h.setContentType(MediaType.APPLICATION_JSON);
                return h;
            }
        };
    }
}

2.降低hystrix超时时间,以便测试降级

spring:
  application:
    name: zuul
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

zuul:
  retryable: true
    
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 2000
  MaxAutoRetriesNextServer: 1
  MaxAutoRetries: 1
  
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500

3.启动服务,测试降级

http://localhost:3001/item-service/35
在这里插入图片描述

zuul 请求过滤

Zuul API网关_第4张图片
添加过滤器,继承ZuulFilter ,按照规则实现过滤方法. 不用做任何配置,只需要添加@Component 注解

1.定义过滤器,继承 ZuulFilter

@Component
public class AccessFilter extends ZuulFilter {
    /**
     * 过滤器的类型 : 前置 ,后置, 路由,  错误
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 过滤器添加的位置
     * 返回6 ,加到第6个位置
     * @return
     */
    @Override
    public int filterOrder() {
        return 6;
    }

    /**
     * 针对当前请求进行判断,判断当前请求是否要执行这个过滤器的过滤代码
     * 如果访问 item-service 要检查权限
     * 如果访问其他服务则不检查权限,直接访问
     * @return
     */
    @Override
    public boolean shouldFilter() {
        RequestContext ctx= RequestContext.getCurrentContext();
        //获取当前请求的服务id
        String serviceId=(String)ctx.get(FilterConstants.SERVICE_ID_KEY);
        if(serviceId.equals("item-service")){
            return true;//要执行权限过滤
        }
        return false;//跳过过滤代码不执行
    }
    /**
     * 过滤代码,对用户权限进行检查
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx= RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token)){
            //没有token,阻止继续调用
            ctx.setSendZuulResponse(false);
            //发送提示,提示没有用户登录
            ctx.setResponseStatusCode(JsonResult.NOT_LOGIN);
            ctx.setResponseBody(JsonResult.err().code(JsonResult.NOT_LOGIN).msg("not login!").toString());
        }
        return null;  //zuul过度设计,返回值在现在的版本中没有使用
    }
}

2.访问测试

  • 没有token参数不允许访问
  • 有token参数可以访问

你可能感兴趣的:(SpringCloud)