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

本文介绍了如何使用Spring Cloud Zuul作为API网关,包括Zuul过滤器的四种类型及其执行顺序,配置参数,以及如何实现服务降级。通过实战步骤展示了创建Zuul模块、配置YML文件、添加Zuul注解,以及设置权限校验和降级处理的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ZUUL基础知识

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

在这里插入图片描述

ZUUl过滤器

1、4种类型

pre、routing、post、error

顺序:pre>routing>post

 

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  

 2、填写项目信息、next

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

      <dependency>
        <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

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.启动,查看注册中心

7、通过ZUUL调用

访问provider

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

访问:consumer

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

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<String,Object> 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;
            }
        };
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值