SpringCloud----Zull的使用

2.1.2 zuul作用
  • 路由转发(代理)

  • 过滤器(认证、授权、日志等)

2.2 搭建zuul服务器

  • 创建项目导入依赖

    • spring boot web

    • eureka-server

    • Routing—zuul

  • 在启动类添加@EnableZuulProxy注解

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

配置yml

server:
  port: 8080
spring:
  application:
    name: zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"

启动zuul服务,查看代理信息

2.3 网关配置

2.3.1 服务的自定义映射配置

如果在zuul中没有配置服务的path映射,则默认使用服务的service-id作为当前服务的访问路径

方式1:

zuul:
  routes:
    order-ui: /order/**
    goods-ui: /goods/**

方式2:

zuul:
  routes:
    aaa:
      path: /o/**
      serviceId: order-ui
    bbb:
      path: /g/**
      serviceId: goods-ui

2.3.2 忽略某个/某些服务

zuul:
  ignored-services: order-provider,goods-provider
2.3.3 配置其他服务
  • 有些时候,某些服务可能是其他语言编写的,没有在eureka上进行注册,所以无法通过注册中心进行动态拉取,我们可以单独配置

  • zuul:
      routes:
        ccc:
          path: /music/**
          url: http://47.96.11.185:9999
2.3.4 配置其他服务的集群
  • 配置第三方服务(没有在eureka中进行注册的服务)的集群

  • zuul:
      routes:
        ccc:
          path: /music/**
          serviceId: music-service
          
    music-service:
      ribbon:
        eureka:
          enable: false
        listOfServer: http://47.96.11.185:9999,http://47.95.124.125:8082,http://121.196.17.126:9999

    2.3.4 访问路径的前缀配置

2.4 网关服务降级

  • 创建网关服务降级处理类(此类的作用就是为用户请求提供响应)

  • /**
     * 1.创建服务降级处理类,实现FallbackProvider
     * 2.实现getRoute和fallbackResponse方法
     */
    @Component
    public class GoodsUIFallback implements FallbackProvider {
    
        @Override
        public String getRoute() {
            //如果想要此类处理所有服务请求失败,return "*" 或者 return null
            //如果返回的是一个具体的服务名称,则表示只处理当前服务请求失败 降级
            return "goods-ui";
        }
    
        @Override
        public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
            ClientHttpResponse response = new ClientHttpResponse() {
                public HttpStatus getStatusCode() throws IOException {
                    return HttpStatus.OK;
                }
                public int getRawStatusCode() throws IOException {
                    return HttpStatus.OK.value();
                }
                public String getStatusText() throws IOException {
                    return HttpStatus.OK.getReasonPhrase();
                }
    
                public void close() {
                }
    
                public InputStream getBody() throws IOException {
                    //设置响应体
                    Map<String,Object> map = new HashMap<>();
                    map.put("code",0);
                    map.put("msg","无法请求商品数据,请检查网络");
                    ObjectMapper objectMapper = new ObjectMapper();
                    String msg = objectMapper.writeValueAsString(map);
                    return new ByteArrayInputStream(msg.getBytes("UTF-8"));
                }
    
                public HttpHeaders getHeaders() {
                    //设置响应头
                    HttpHeaders httpHeaders = new HttpHeaders();
                    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                    return httpHeaders;
                }
            };
    
            return response;
        }
    }

2.5 网关过滤器

  • 过滤器类型

    • pre 前置过滤器,在路由之前执行

    • routing 在路由过程中执行

    • post 后置过滤器,在路由之后执行

    • error 在用户请求网关过程中发生错误执行

    • 网关过滤器案例
    • @Component
      public class LoginFilter extends ZuulFilter {
      
          private Logger logger = LoggerFactory.getLogger(LoginFilter.class);
          /**
           * 设置网关过滤器类型:
           * 1.pre 路由之前
           * 2.routing 路由之时
           * 3.post 路由之后
           * 4.error
           */
          public String filterType() {
              return "pre";
          }
      
          public int filterOrder() {
              //设置同类型过滤器的执行顺序
              return 0;
          }
      
          public boolean shouldFilter() {
              //设置过滤器是否生效
              return true;
          }
      
          //doFilter
          public Object run() throws ZuulException {
              try {
                  RequestContext context = RequestContext.getCurrentContext();
                  HttpServletRequest request = context.getRequest();
      
                  logger.info("----->>>>>>>>>>>>>>>>");
                  //String url = request.getRequestURL().toString();
                  //if(url 是受限资源路径){
                  if (!"options".equalsIgnoreCase(request.getMethod())) {
                      //String token = request.getHeader("token");  //要求token从header中传递
                      String token = request.getParameter("token"); //token用参数传递
                      if (token == null) {
                          //拦截用户请求
                          context.setSendZuulResponse(false); //设置response不用于zuul响应
                          context.setResponseStatusCode(401);
                          context.getResponse().getWriter().write("Token is empty..");
                      } else {
                          //JWT校验token的正确性
                          if (!token.equals("123123")) {
                              context.setSendZuulResponse(false);
                              context.setResponseStatusCode(401);
                              context.getResponse().getWriter().write("Token is error..");
                          }
                      }
                  }
                  //}
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return null;
          }
      }
原文地址:https://www.cnblogs.com/jikeyi/p/13339767.html