【SpringCloud】SpringCloud(五)之Zuul网关

目录


前言

        闲言少叙,直入主题

一、Zuul是什么?

        Zuul是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,Zuul的核心是一系列的过滤器,可以完成如下的功能:

  • 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求
  • 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图
  • 动态路由:动态的将请求路由到不桶的后端集群
  • 压力测试:主键增加指向集群的流量,以了解性能
  • 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
  • 静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群

二、快速入门

1.引入后的架构

 

       在引入Zuul网关之后,不管是来自客户端的请求,还是服务内部调用,一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现鉴权、动态路由等操作。

2.快速入门

下文中的user-service和user_consumer参考此篇博客搭建:https://blog.csdn.net/weixin_43267344/article/details/109956408

项目结构:

2.1 新建工程zuul-demo

添加Zuul依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w2.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>cn.james.demo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.james.demo</groupId>
    <artifactId>zuul-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

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

2.2 编写启动类

@SpringBootApplication
@EnableZuulProxy // 开启Zuul的网关功能
public class ZuulApplication {

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

2.3 编写配置

server:
  port: 10010 #服务端口
spring: 
  application:  
    name: api-gateway #指定服务名
zuul:
  routes:
    user-service: # 这里是路由id,随意写
      path: /user-service/** # 这里是映射路径
      url: http://127.0.0.1:8081 # 映射路径对应的实际url地址

        以上配置,我将将符合path规则的一切请求,都代理到url参数指定的地址,即,将/user-service/**开头的请求,代理到http://localhost:8081.,

        也就是说如果我们访问了:http://localhost:10010/user-service/user/{id},就会去端口号为8081的user-service的服务中发起请求,然后返回结果

3. 面向服务的路由

      刚刚的配置中,对应的服务地址是确定的,不能改变的,如果同一个服务有多个实例的话,这样就有点不太合理,我们应该通过服务的名称,去Eureka注册中心去查找服务对应的实例列表,然后进行动态路由才可以.

3.1 添加Eureka客户端依赖

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

3.1 开启Eureka客户端发现功能

@EnableZuulProxy   //开启zuul的网关功能
@SpringBootApplication
@EnableDiscoveryClient
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

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

eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka

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

zuul:
  routes:
    user-service: # 这里是路由id,随意写
      path: /user-service/** # 这里是映射路径
      serviceId: user-service # 指定服务名称

配置内容:

启动重新访问地址测试即可:

 

4 路由的配置规则

4.1简化的路由配置

       在刚刚的路由配置中,配置的规则如下:

  • path:指定路由器的映射路径,
  • serviceId:指定服务名

        在多数的情况下,路由名称往往和服务名会写成一样的,因此Zuul就可以简化成以下的写法:

zuul:
  routes:
    user-service: /user-service/** # 这里是映射路径

4.2 默认的路由规则

       在使用Zuul的过程中,上面的配置已经大大简化了配置项,但是当服务较多的时候,配置也是比较繁琐的,因此Zuul就指定了more你的路由规则:

  • 默认情况下,一切服务的映射路径就是服务名本身
    • 例如服务名为:user-service,则默认的映射路径就是:/user-service/**

     即映射路径无需配置也是可以的.

     如果想要禁用某个路由规则,则可以使用以下的写法("-"和服务名之间有空格):一般我们为了不让用户看到注册中的微服务,会禁用Eureka的服务

zuul:
  ignored-services:
    - ureka-server

也就是说如果禁用Eureka路由Zuul的application.yml的配置文件可以写如下:

server:
  port: 10010
spring:
  application:
    name: api-gateway
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
zuul:
  routes:
    user-service:
      path: /user-service/**
      serviceId: user-service

zuul:
  ignored-services:
    - eureka-server

4.3 路由前缀 

       为了让路径名没有太明确的含义,一般在路径名的前面加上一个前缀,这样在发起请求的时候,访问路径就需要一这个前缀开头,通过带有前缀的这个路径名,然后代理到相对应的路径名.如下:

zuul:
  prefix: /api # 添加路由前缀
  routes:
    user-service: /user-service/** # 这里是映射路径

       我们通过zuul.prefix=/api来指定了路由的前缀,这样在发起请求时,路径就要以/api开头。路径/api/user-service/user/1将会被代理到/user-service/user/1

5 Zuul过滤器

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

5.1 ZuulFilter

        ZuulFilter是过滤器的顶级父类,其中有如下四个重要的方法:

public abstract ZuulFilter implements IZuulFilter{

    abstract public String filterType();  // 类型 前置 路由中 路由后  error类型

    abstract public int filterOrder();   // 过滤器的执行顺序 这个返回值越小就越先执行
    
    boolean shouldFilter();// 来自IZuulFilter   是否要进入到run方法中

    Object run() throws ZuulException;// IZuulFilter  核心方法
}
  • filterType:返回字符串,代表过滤器的类型。包含以下4种:

    pre:请求在被路由之前执行

    route:在路由请求时调用

    post:在routing和errror过滤器之后调用

    error:处理请求时发生错误调用

  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。

  • run:过滤器的具体业务逻辑。

5.2 过滤器的生命周期

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

5.3 使用场景

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

5.4 自定义过滤器

@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);
            // 设置返回状态码
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;  // 什么都不做 直接进入到微服务中
    }
}

6 负载均衡和熔断

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

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000    //总的熔断时间,根据实际来配置即可
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 2000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 1

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值