SpringCloud微服务(四)——Zuul

六、Zuul

1、简要概述

在这里插入图片描述
不使用Zuul的开发架构是:
在这里插入图片描述

2、Zuul作用

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

3、Zuul进行地址转换和负载均衡

在父工程下创建一个miscroservicecloudzuulgateway9527的maven工程
在pom文件中添加如下依赖:

	 <dependencies>
        <!--zuul路由网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>    
        <!--actuator监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--hystrix容错-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--日常标配-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>SpringCloud</groupId>
            <artifactId>miscroserviceapi</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
            <version>1.2.6.RELEASE</version>
        </dependency>
    </dependencies>

编写主启动类:

package springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;


@SpringBootApplication
@EnableZuulProxy
public class Zuul_9527_StartSpringCloudApp {

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

以kv形式配置路由规则,k就是路由id,path就是所匹配的路径,最终让此端口的这一路径会先通过网关然后才能访问微服务,

server:
  port: 9527
zuul:
  prefix: /example
#  ignored-services: miscroservicecloud-dept
  ignored-services: "*"
  routes:
    mydept.serviceId: miscroservicecloud-dept
    mydept.path: /mydept/**

我们可以发现,现在已经不用再访问本来的端口访问到数据了,而是经过了网关去转发请求地址,来到了9527。
但是有一个问题,如果以后的微服务地址发生了变化,或者启动了多台集群需要我们配置负载均衡,那么我们就要在zuul的依赖中引入Eureka客户端的依赖

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

然后进行相关的配置

server:
  port: 9527
spring:
  application:
    name: miscroservice-cloud-zuul-gateway
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka 
    instance:
      instance-id: gateway-9527.com
      prefer-ip-address: true

info:
  app.name: miscrocloud
  company.name: www.cloud.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$
zuul:
  prefix: /example
#  ignored-services: miscroservicecloud-dept
  ignored-services: "*"
  routes:
    mydept.serviceId: miscroservicecloud-dept
    mydept.path: /mydept/**

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

4、过滤器

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

<1>、ZuulFilter

ZuulFilter是过滤器的最高级的父类,其中有四个最重要的方法

public abstract class ZuulFilter implements IZuulFilter, Comparable<ZuulFilter> {

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

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

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

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

<3>、自定义过滤器
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 take = request.getParameter("access-token");
        //判断是否存在
        if (StringUtils.isBlank(take)) {
            //不存在,未登录,就拦截
            ctx.setSendZuulResponse(false);
            //返回403
            ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
        }
        return null;
    }
}

运行进行测试,输入原来的地址,出现403禁止访问的错误,是因为没有按照之前的自定义过滤器所编写的规则,同时提交一个请求参数,由于我们没有具体的业务实现,所以填写什么路由规则都可以

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

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

ribbon:
  ReadTimeout: 60000
  ConnectTimeout: 60000
  
hystrix:
  command:
    default:
      execution:
        isolution:
          thread:
            timeoutInMilliseconds: 2000
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一个基于Spring Boot的微服务框架,它提供了一系列组件和解决方案,用于构建和管理微服务架构。其中包括Spring Cloud Netflix、Spring Cloud Config等组件。\[2\]Spring Cloud Netflix是一个集成了Eureka、Hystrix、Ribbon、Feign和Zuul等组件的框架,用于实现服务注册发现、熔断器、负载均衡、服务调用和服务网关等功能。Eureka是服务注册中心,用于管理和发现微服务;Hystrix是熔断器,用于容错管理,提供强大的容错能力;Ribbon是云端负载均衡组件,支持多种负载均衡策略;Feign是一个声明式的REST客户端,用于简化服务调用;Zuul是一个服务网关,提供代理、过滤和路由等功能。\[3\] 至于消息队列,Spring Cloud并没有提供自己的消息队列组件,但可以与其他消息队列中间件集成,如RabbitMQ、Kafka等。通过集成消息队列,可以实现微服务之间的异步通信和解耦。消息队列可以作为一种可靠的消息传递机制,确保消息的可靠性和可扩展性。通过使用消息队列,可以实现微服务之间的解耦和水平扩展,提高系统的可靠性和性能。 #### 引用[.reference_title] - *1* [搭建一个完整的springcloud微服务](https://blog.csdn.net/weixin_45997756/article/details/123710369)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [SpringCloud微服务架构开发——01微服务架构与SpringCloud](https://blog.csdn.net/weixin_43624810/article/details/124461632)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值