springcloud搭建实战<十>【zuul网关】

ZUUL基础知识

zuul是spring cloud提供的一个通用api网关组件

springcloud搭建实战<十>【zuul网关】_第1张图片

 

ZUUl过滤器

1、4种类型

pre、routing、post、error

顺序:pre>routing>post

springcloud搭建实战<十>【zuul网关】_第2张图片

 springcloud搭建实战<十>【zuul网关】_第3张图片

2、参数配置

 注意:

/zuul 路径下网关会跳过dispatcherServlet  而由zuulServlet处理

3、实现服务降级

zuul包下是带hystrix包

#ribbonTimeout = (ReadTimeout + ConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000

实战环境

工具:IntelliJ IDEA 2019.2.4

JDK:1.8

父项目以及注册中心、服务方详见之前博客。

【消费方与之前服务方步骤一致,以下文章步骤基本一致】

步骤

1、打开父项目,file->new module  

springcloud搭建实战<十>【zuul网关】_第4张图片

 2、填写项目信息、next

springcloud搭建实战<十>【zuul网关】_第5张图片

 3、pom文件新增连个依赖包

      
        org.springframework.cloud
            spring-cloud-starter-netflix-zuul
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        

4、yml文件:

server:
  port: 8000

spring:
  application:
    name: cloud-zuul

eureka:
  client:
    service-url:
      defaultZone: http://user:123456@localhost:8080/eureka
    healthcheck:
      enabled: true  #健康检查(需要spring-boot-starter-actuator依赖)
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 10  # 续约更新时间间隔(默认30秒)
    lease-expiration-duration-in-seconds: 10  # 续约到期时间(默认90秒)


#zuul代理配置  zuul.routes.服务名.path,服务名要与注册的一致
zuul:
  routes:
    api-provider:
      path: /api-provider/**
      service-id: cloud-provider  #应用名映射
    api-consumer:
      path: /api-consumer/**
      service-id: cloud-consumer  #应用名映射
  ignored-patterns: /**/admin/** #过滤掉匹配URL
  sensitive-headers:     #默认会过滤 "Cookie", "Set-Cookie", "Authorization" 会影响统一授权
#  strip-prefix: true    #默认时或true时 转发到服务的请求是/**,如果stripPrefix=false,转发的请求是直接/api-consumer/**
#  prefix: /api #会对所有的path增加一个/api前缀

5、application加入Zuul注解

@EnableZuulProxy

6.启动,查看注册中心

springcloud搭建实战<十>【zuul网关】_第6张图片

7、通过ZUUL调用

访问provider

http://localhost:8000/api-provider/sayHi

springcloud搭建实战<十>【zuul网关】_第7张图片

访问:consumer

http://localhost:8000/api-consumer/houseManage//queryCustomerInfoByTel?tel=232

springcloud搭建实战<十>【zuul网关】_第8张图片

8、新增权限校验AcessFiltler

 访问:http://localhost:8000/api-consumer/houseManage/queryCustomerInfoByTel?tel=232&acessToken=123

 

package com.cloud.zuul.filter;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.http.HttpStatus;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 10450
 * @description 权限token校验
 * @date 2022/9/2 14:45
 */
@Component
public class AcessFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 2;//最前进行校验
    }

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

    @Override
    public Object run() throws ZuulException {
        //1、获取request对象
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        //2、获取token参数
        String token = request.getParameter("acessToken");

        //3、对比token
        if(token == null || !("123".equals(token))){//假设token查到为123
            //4、token校验失败,直接响应数据
            Map result = new HashMap<>();
            result.put("code",HttpStatus.SC_UNAUTHORIZED);
            result.put("msg","存在SQL注入风险");
            ctx.getResponse().setContentType("text/html;charset=UTF-8");
            ctx.setResponseBody(JSONObject.toJSONString(result));
            ctx.setSendZuulResponse(false);//不响应
//            ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);//401
        }
        return null;
    }
}

9、新增服务降级

package com.cloud.zuul.fallback;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author 10450
 * @description ZUUL实现降级
 * @date 2022/9/2 14:36
 */
@Component
public class ZuulFallback implements FallbackProvider {
    @Override
    public String getRoute() {
        return "*"; //指定全部出现问题的服务都走这个降级方法
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {//route表示服务名
        System.out.println("降级的服务:"+route);
        cause.printStackTrace();//问题打印
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.value(); //500状态码
            }

            @Override
            public String getStatusText() throws IOException {
                //指定错误信息
                return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                String msg = "当前服务:"+ route + ",出现问题";
                return new ByteArrayInputStream(msg.getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                //指定响应头信息
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

你可能感兴趣的