Springcloud1---->Zuul网关

简介

在这里插入图片描述

加入zuul后的架构

在这里插入图片描述
不管是来自于客户端(PC或移动端)的请求,还是服务内部调用。一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现 鉴权、动态路由等等操作。Zuul就是我们服务的统一入口。

快速入门

创建zuul服务

添加Zuul依赖

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

编写zuul启动类

通过 @EnableZuulProxy 注解开启Zuul的功能:

@SpringBootApplication
@EnableZuulProxy //开启zuul
public class ZuulServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulServiceApplication.class);
    }
}

编写zuul配置文件

server:
  port: 10000
spring:
  application:
    name: zuul-service

编写路由规则

zuul:
  routes:
    user-service:  #没用
      path: /user-service/**  # 服务实例ID
      url: http://127.0.0.1:8080 # 服务代理的具体地址
    order-service: #没用
      path: /order-service/**  # 服务实例ID
      url: http://127.0.0.1:9090 # 服务代理的具体地址

面向服务的路由

在刚才的路由规则中,我们把路径对应的服务地址写死了!如果同一服务有多个实例的话,这样做显然就不合理了。
我们应该根据服务的名称,去Eureka注册中心查找 服务对应的所有实例列表,然后进行动态路由才对!

添加Eureka客户端依赖

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

开启Eureka客户端发现功能

在zuul服务启动类加注解@EnableDiscoveryClient //开启euerka客户端发现功能

@SpringBootApplication
@EnableDiscoveryClient //开启euerka客户端发现功能
@EnableZuulProxy //开启zuul
public class ZuulServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulServiceApplication.class);
    }
}

添加Eureka配置,获取服务信息

#    Eureka配置-- 目前先注册自己保证不报错
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka

修改映射配置,通过服务名称获取

因为已经有了Eureka客户端,我们可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问,而且Zuul已经集成了Ribbon的负载均衡功能。

zuul:
  routes:
    order-service:
      path: /1/**
      #url: order-service  #无负载
      serviceId: order-service #有负载

简化的路由配置

我们关于user-service的配置可以简化为一条:

zuul:
  routes:
    order-service: /1/**
    user-service: /2/**

省去了对服务名称的配置。

过滤器

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

使用场景

场景非常多:

  • 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了
  • 异常处理:一般会在error类型和post类型过滤器中结合来处理。
  • 服务调用时长统计:pre和post结合使用。

自定义过滤器

接下来我们来自定义一个过滤器,模拟一个登录的校验。基本逻辑:如果请求中有access-token参数,则认为请求有效,放行。
创建一个LoginFilter:

@Component
@Log4j2
public class LoginFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

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

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

    @SneakyThrows
    @Override
    public Object run() throws ZuulException {

        log.warn("========================================");
        //1)获取Zuul提供的请求上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();
        //2)从上下文中获取request对象
        HttpServletRequest request = ctx.getRequest();
        HttpServletResponse response = ctx.getResponse();
        response.setContentType("application/json;charset=utf-8");
        // 3) 从请求中获取token
        //获取token
        String token = request.getHeader("token");
        log.info("token:{}",token);

        String requestURI = request.getRequestURI();
        if(requestURI.equals("/1/login")){
            return null;
        }

        //判断token是否正常
        if(StringUtils.isEmpty(token)){

            Result result = new Result(401,"token丢失");
            String json = new ObjectMapper().writeValueAsString(result);
            // 没有token,登录校验失败,拦截
            ctx.setSendZuulResponse(false);
            // 返回401状态码(未授权)。也可以考虑重定向到登录页。
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            ctx.setResponseBody(json);
            //拦截
            //return false;
        }

        //处理token是否有效
        boolean b = JwtUtil.checkToken(token);
        if(!b){
            Result result = new Result(401,"token失效");
            String json = new ObjectMapper().writeValueAsString(result);
            // 没有token,登录校验失败,拦截
            ctx.setSendZuulResponse(false);
            // 返回401状态码(未授权)。也可以考虑重定向到登录页。
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            ctx.setResponseBody(json);
            //拦截
            //return false;
        }

        return null;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值