SpringCloud微服务学习(四)——Zuul

六、Zuul网关

1.简介

在这里插入图片描述

没有Zuul之前的开发架构
在这里插入图片描述

2.Zuul的作用

在这里插入图片描述

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

3.使用Zuul进行地址转换和负载均衡

在总工程师内创建一个新的Module
在这里插入图片描述
然后添加依赖

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

编写启动类和Zuul的启动注解

package itcast;

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.EnableZuulServer;

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

编写端口号

server:
  port: 10010

以kv形式配置路由规则,k就是路由id,path就是所匹配的路径,url匹配对应端口,最终让此端口的这一路径会先通过网关然后才能访问微服务,而1就是我们的路由id,叫什么都可以

server:
  port: 10010
zuul:
  routes:
    1:
      path: /user-Service/**
      url: http://127.0.0.1:9091

然后启动我们的Zuul,拜访对应的端口,由于我们user-Service的Module控制层设置的请求地址为user,所以直接来访问user即可
如图;
在这里插入图片描述
我们可以发现,现在已经不用再访问本来的9091端口访问到数据了,而是经过了网关去转发请求地址,来到了10010。
但是有一个问题,如果将来微服务的地址发生了变化,或者启动了多台集群需要我们配置负载均衡,那么我们就要在zuul
的依赖中引入Eureka客户端的依赖

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

然后进行Zuul配置

server:
  port: 10010
zuul:
  routes:
    1:
      path: /user-Service/**
      serviceID: user-Service
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka

这样就可以直接获取到eureka的INSTANCE列表服务了 ,然后需要把url改换成我们的ServiceID,而我们的ServiceID就是user-Service。

重新启动
在这里插入图片描述
然后再介绍一种简化配置zuul的配置方法
在这里插入图片描述
按照此规则配置也就是这样

server:
  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
zuul:
  routes:
    user-Service: /user-Service/**
  ignored-services:
    - consumer-Service
spring:
  application:
    name: Zuul

然后重新运行
在这里插入图片描述
总结:
当一个request请求过来之后,先进行端口和serviceID的匹配,匹配到之后将原服务转发到zuul网关的服务 ,但是服务本身没有地址,所以就要拉取Eureka的INSTANCE列表,获取具体的路径地址,然后通过负载均衡算法,这就是面向服务的路由,内部同时实现了负载均衡和地址转发。

4.过滤器

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

<1>ZuulFilter

ZuulFilter是过滤器的顶级父类,里面有四个最重要的方法

public abstract ZuulFilter implements IZuulFilter{

    abstract public String filterType();//过滤器类型

    abstract public int filterOrder();//过滤器顺序
    
    boolean shouldFilter();// 来自IZuulFilter,要不要过滤

    Object run() throws ZuulException;// IZuulFilter,过滤逻辑
}
  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
  • run:过滤器的具体业务逻辑。
  • filterType:返回字符串,代表过滤器的类型。包含以下4种:
    • pre:请求在被路由之前执行
    • routing:在路由请求时调用
    • post:在routing和errror过滤器之后调用
    • error:处理请求时发生错误调用
  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

<2>生命周期

在这里插入图片描述

  • 正常流程:
    • 请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。
  • 异常流程:
    • 整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。
    • 如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。
    • 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了。

<3>自定义过滤器

自定义一个过滤器,模拟一个登录的校验,如果请求中有access-token参数,则认为请求有效,放行

package itcast.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class LoginFilter extends ZuulFilter {

    @Override
    public String filterType() {//定义过滤器种类
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {//定义过滤器优先级
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {//定义是否过滤
        return true;
    }

    @Override
    public Object run() throws ZuulException {//写过滤逻辑,登录拦截
        //获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //获取request
        HttpServletRequest request = ctx.getRequest();
        //获取请求参数
        String token = request.getParameter("access-token");
        //判断是否存在
        if (StringUtils.isBlank(token)) {
            //不存在,未登录,就拦截
            ctx.setSendZuulResponse(false);
            //返回403
            ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
        }
        return null;
    }
}

简单的进行了一下Session的模拟,现在可以来重新测试一下
在这里插入图片描述
填入原来的地址,发生了403禁止访问的错误,就是因为我们没有按照之前的自定义过滤器所编写的,同时提交一个请求参数,由于我们没有具体的业务实现,所以填写什么路由规则都可以
在这里插入图片描述

访问成功。

<4>Zuul的负载均衡和熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:

hystrix:
  command:
    default:
      execution:
        isolution:
          thread:
            timeoutInMilliseconds: 2000
ribbon:
  ReadTimeout: 60000
  ConnectTimeout: 60000
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值