天天看点

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

目录

  • 一站式微服务架构SpringCloud-Netflix网关路由Zuul
    • 项目中使用Zuul
    • 自定义路由规则
    • 禁用服务名访问项目和添加项目前缀
    • 过滤器
      • 自定义过滤器
      • 禁用过滤器
      • 网关异常处理
    • zuul的熔断降级

一站式微服务架构SpringCloud-Netflix网关路由Zuul

项目中使用Zuul

创建zuul项目

添加依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
           

配置文件

server.port=90

spring.application.name=springcloud-zuul
#每2秒向服务端发送一次心跳,证明自己存活
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,10秒之内没有发送心跳,就代表故障了
eureka.instance.lease-expiration-duration-in-seconds=10
#以IP作为链接
eureka.instance.prefer-ip-address=true
#实例名称
eureka.instance.instance-id=springcloud-zuul
#Eureka链接地址
eureka.client.service-url.defaultZone=http://47.110.157.82:8761/eureka,http://47.110.157.82:8762/eureka,http://47.110.157.82:8763/eureka
#设置zuul超时时间        
zuul.host.connect-timeout-millis=5000
           

启动类添加@EnableZuulProxy

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

测试:

通过Eureka的spring.application.name访问项目

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul
一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

自定义路由规则

配置文件中添加

#路由规则,producer是自己随便定义的
zuul.routes.producer.service-id=springcloud-producer
#?:匹配多个字符。*:匹配单层路径。 **:匹配:多层路径,/producer/**自己随便定义
zuul.routes.producer.path=/producer/**

           

测试:

将springcloud-producer替换成producer

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

禁用服务名访问项目和添加项目前缀

#忽略服务,禁止使用该服务名访问
#zuul.ignored-services=springcloud-producer
#忽略所有服务
zuul.ignored-services=*
#路径中存在save不能访问
zuul.ignored-patterns=/**/save/**
#添加前缀
zuul.prefix=/api

           

测试:

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

服务名无法访问

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul
一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

过滤器

自定义过滤器

@Component
public class MyFilter extends ZuulFilter {

    /**
     * 过滤器类型
     * ERROR_TYPE = "error"; 过滤出错
     * POST_TYPE = "post"; 过滤后
     * PRE_TYPE = "pre";   过滤前
     * ROUTE_TYPE = "route"; 过滤时
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.ROUTE_TYPE;
    }

    /**
     * 过滤器优先级
     *  DEBUG_FILTER_ORDER = 1;
     *  FORM_BODY_WRAPPER_FILTER_ORDER = -1;
     *  PRE_DECORATION_FILTER_ORDER = 5;
     *  RIBBON_ROUTING_FILTER_ORDER = 10;
     *  SEND_ERROR_FILTER_ORDER = 0;
     *  SEND_FORWARD_FILTER_ORDER = 500;
     *  SEND_RESPONSE_FILTER_ORDER = 1000;
     *  SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
     *  SERVLET_30_WRAPPER_FILTER_ORDER = -2;
     *  SERVLET_DETECTION_FILTER_ORDER = -3;
     * @return
     */
    @Override
    public int filterOrder() {
        return FilterConstants.SEND_ERROR_FILTER_ORDER;
    }


    /**
     * 是否开启过滤器
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 执行方法
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        String serverName = request.getServerName();
        System.out.println("访问地址"+serverName+request.getRequestURI());
        return null; //返回值无意义
    }
}
           

测试

访问路由URL:http://localhost:90/api/producer/get

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

禁用过滤器

配置文件添加

#禁用过滤器。Myfilter过滤器类,route过滤器类型
zuul.Myfilter.route.disable=true
           

网关异常处理

关闭zuul自带异常处理

自定义异常处理类

@Component
public class ErrorFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.ERROR_TYPE;
    }

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

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

    @Override
    public Object run() throws ZuulException {
        try {
            RequestContext currentContext = RequestContext.getCurrentContext();
            ZuulException  exception=(ZuulException) currentContext.getThrowable();
            System.out.println("进入系统异常拦截"+exception.getMessage());
            HttpServletResponse response = currentContext.getResponse();
            response.setContentType("application/json; charset=utf8");
            response.setStatus(exception.nStatusCode);
            PrintWriter writer=null;
            try{
                writer=response.getWriter();
                writer.print("{code:"+exception.nStatusCode+",message:\""+exception.getMessage()+"\"}");

            }catch (IOException e){
                e.printStackTrace();
            }finally {
                if(writer!=null){
                    writer.close();
                }
            }
        }catch (Exception e){
            ReflectionUtils.rethrowRuntimeException(e);
        }
        return null;
    }
}
           

在自定义过滤器MyFilter中制造异常

/**
     * 执行方法
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        String serverName = request.getServerName();
        System.out.println("访问地址"+serverName+request.getRequestURI());
        int a=10/0; //制造异常
        return null; //返回值无意义
    }
           

测试

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

zuul的熔断降级

创建zuul的降级类

@Component
public class ZuulFallBack implements FallbackProvider {
    /**
     * 配置需要降级的路由规则
     * @return
     */
    @Override
    public String getRoute() {
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {


            /**
             * 响应头
             * @return
             */
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type", "text/html;charset=UTF-8");

                return headers;
            }

            /**
             * 响应体
             * @return
             * @throws IOException
             */
            @Override
            public InputStream getBody() throws IOException {
                // 当出现服务调用错误之后返回的内容
                // 服务端死掉,会自动找zuul的失败回退服务降级
                return new ByteArrayInputStream("系统正在维护,请稍后再试!".getBytes());
            }
            /**
             * 状态码
             * @return
             * @throws IOException
             */
            @Override
            public HttpStatus getStatusCode() throws IOException {

                return HttpStatus.BAD_REQUEST;
            }

            /**
             * 状态码值
             * @return
             * @throws IOException
             */
            @Override
            public int getRawStatusCode() throws IOException {

                return HttpStatus.BAD_REQUEST.value();
            }
            /**
             * 状态码值文本
             * @return
             * @throws IOException
             */
            @Override
            public String getStatusText() throws IOException {

                return HttpStatus.BAD_REQUEST.getReasonPhrase();
            }
            @Override
            public void close() {
                // TODO Auto-generated method stub

            }
        };
    }
}
           

测试:

关闭zuul中的服务,然后通过zuul来访问服务

一站式微服务架构SpringCloud-Netflix网关路由Zuul一站式微服务架构SpringCloud-Netflix网关路由Zuul

继续阅读