SpringCloud 10:服务网关Zuul

项目搭建参考https://blog.csdn.net/qq_40977118/article/details/104738485

1. 服务网关

  • Zuul是分布式springcloud项目的流量入口,理论上所有进入到微服务系统的请求都要经过zuul来过滤和路由。

2. pom引入依赖

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.spring.fisher</groupId>
    <artifactId>micro-zuul</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>micro-zuul</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--eureka客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--zuul-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <!--配置中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
            <version>LATEST</version>
        </dependency>
        <!--健康检测-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

3. 创建启动类

在这里插入图片描述

package com.spring.fisher;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;


@SpringBootApplication
//开启zuul路由功能
@EnableZuulProxy
public class MicroZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(MicroZuulApplication.class, args);
    }

    @Bean
    //动态刷新配置中心的配置信息
    @RefreshScope
    //获取zuul开头的配置信息
    @ConfigurationProperties("zuul")
    @Primary
    public ZuulProperties zuulProperties() {
        return new ZuulProperties();
    }
}

4. 配置文件

  • 把web开头的请求,通过服务名称分配给micro-web的服务

在这里插入图片描述

  • zuul内部包含ribbon和hystrix的功能,可以设置超时时间
spring.application.name=micro-zuul
server.port=7070

eureka.client.serviceUrl.defaultZone=http://root:root@localhost:8763/eureka/
# 使用路径方式匹配路由规则。
# 参数key结构: zuul.routes.customName.path=xxx
# 用于配置路径匹配规则。
# 其中customName自定义。通常使用要调用的服务名称,方便后期管理
# 可使用的通配符有: * ** ?
# ? 单个字符
# * 任意多个字符,不包含多级路径
# ** 任意多个字符,包含多级路径
zuul.routes.micro-web.path=/web/**

# 参数key结构: zuul.routes.customName.url=xxx
# url用于配置符合path的请求路径路由到的服务地址。
#zuul.routes.micro-order.url=http://localhost:8080/

# key结构 : zuul.routes.customName.serviceId=xxx
# serviceId用于配置符合path的请求路径路由到的服务名称。
zuul.routes.micro-web.serviceId=micro-web

# ignored service id pattern
# 配置不被zuul管理的服务列表。多个服务名称使用逗号','分隔。
# 配置的服务将不被zuul代理。
#zuul.ignored-services=eureka-application-service

# 此方式相当于给所有新发现的服务默认排除zuul网关访问方式,只有配置了路由网关的服务才可以通过zuul网关访问
# 通配方式配置排除列表。
zuul.ignored-services=*

# 通配方式配置排除网关代理路径。所有符合ignored-patterns的请求路径都不被zuul网关代理。
zuul.ignored-patterns=/**/local/**

# prefix URL pattern 前缀路由匹配
# 配置请求路径前缀,所有基于此前缀的请求都由zuul网关提供代理。
#zuul.prefix=/api

management.endpoints.web.exposure.include=*

# http://localhost:6060/actuator/hystrix.stream
#针对某个服务传输指定的headers信息 ,默认是过滤掉 Cookie,Set-Cookie,Authorization 这三个信息的
#这里置空就是不要过滤掉这三个
zuul.routes.micro-web.sensitive-headers=

#指定全局的headers传输,对所有路由的微服务
#zuul.sensitive-headers=Cookie,Set-Cookie,Authorization

#添加host头信息,标识最初的服务端请求地址
zuul.add-host-header=true

#默认添加  X-Forwarded-*头域
zuul.add-proxy-headers=true

zuul.routes.zuul-server.path=/local/**
zuul.routes.zuul-server.url=forward:/local

zuul.routes.blog.path=/blog/**
zuul.routes.blog.url=http://localhost:8003/

#全局关闭重试
zuul.retryable=false
#关闭该服务的重试
zuul.routes.micro-web.retryable=false

ribbon.ConnectTimeout=5000
ribbon.ReadTimeout=10000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=100000
#如果没有从配置中心获取配置,可以设置为false
#否则会提示Could not locate PropertySource: I/O error on GET request for "http://localhost:8888/micro-zuul/default": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
#但是不影响程序正常运行
spring.cloud.config.enabled=false

5. 依次启动所有服务

在这里插入图片描述
在这里插入图片描述

6. 获取路由规则

  • http://localhost:7070/actuator/routes

在这里插入图片描述

7. 打开hystrix监控

  • http://localhost:9990/hystrix
  • http://localhost:7070/actuator/hystrix.stream

在这里插入图片描述
在这里插入图片描述

8. 发起请求

  • http://localhost:7070/web/queryUser

在这里插入图片描述

  • 连续请求结果,,最终会调用到micro-web服务的接口

在这里插入图片描述

在这里插入图片描述

9. 使用配置中心

在这里插入图片描述

# 使用路径方式匹配路由规则。
# 参数key结构: zuul.routes.customName.path=xxx
# 用于配置路径匹配规则。
# 其中customName自定义。通常使用要调用的服务名称,方便后期管理
# 可使用的通配符有: * ** ?
# ? 单个字符
# * 任意多个字符,不包含多级路径
# ** 任意多个字符,包含多级路径
zuul.routes.micro-web.path=/web/**

# 参数key结构: zuul.routes.customName.url=xxx
# url用于配置符合path的请求路径路由到的服务地址。
#zuul.routes.micro-order.url=http://localhost:8080/

# key结构 : zuul.routes.customName.serviceId=xxx
# serviceId用于配置符合path的请求路径路由到的服务名称。
zuul.routes.micro-web.serviceId=micro-web

#zuul.routes.micro-web1.path=/web/path/**
#zuul.routes.micro-web1.serviceId=micro-web-no
# ignored service id pattern
# 配置不被zuul管理的服务列表。多个服务名称使用逗号','分隔。
# 配置的服务将不被zuul代理。
#zuul.ignored-services=eureka-application-service

# 此方式相当于给所有新发现的服务默认排除zuul网关访问方式,只有配置了路由网关的服务才可以通过zuul网关访问
# 通配方式配置排除列表。
zuul.ignored-services=*

# 通配方式配置排除网关代理路径。所有符合ignored-patterns的请求路径都不被zuul网关代理。
zuul.ignored-patterns=/**/local/**

# prefix URL pattern 前缀路由匹配
# 配置请求路径前缀,所有基于此前缀的请求都由zuul网关提供代理。
#zuul.prefix=/api

management.endpoints.web.exposure.include=*

# http://localhost:6060/actuator/hystrix.stream
#针对某个服务传输指定的headers信息 ,默认是过滤掉 Cookie,Set-Cookie,Authorization 这三个信息的
#这里置空就是不要过滤掉这三个
zuul.routes.micro-web.sensitive-headers=

#指定全局的headers传输,对所有路由的微服务
#zuul.sensitive-headers=Cookie,Set-Cookie,Authorization

#添加host头信息,标识最初的服务端请求地址
zuul.add-host-header=true

#默认添加  X-Forwarded-*头域
zuul.add-proxy-headers=true

zuul.routes.zuul-server.path=/local/**
zuul.routes.zuul-server.url=forward:/local

zuul.routes.blog.path=/blog/**
zuul.routes.blog.url=http://localhost:8003/

#全局关闭重试
zuul.retryable=false
#关闭该服务的重试
zuul.routes.micro-web.retryable=false

ribbon.ConnectTimeout=5000
ribbon.ReadTimeout=10000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=100000

在这里插入图片描述

spring.application.name=api-gateway
server.port=7070

eureka.client.serviceUrl.defaultZone=http://root:root@localhost:8763/eureka/

spring.cloud.config.profile=dev
spring.cloud.config.label=master
#这种配置是configserver还单机情况,直接连接这个单机服务就行
#spring.cloud.config.uri=http://localhost:8085/
#configserver高可用配置
#开启configserver服务发现功能
spring.cloud.config.discovery.enabled=true
#服务发现的服务名称
spring.cloud.config.discovery.service-id=config-server

#如果连接不上获取配置有问题,快速响应失败
spring.cloud.config.fail-fast=true
#默认重试的间隔时间,默认1000ms
spring.cloud.config.retry.multiplier=1000
#下一间隔时间的乘数,默认是1.1
#spring.cloud.config.retry.initial-interval=1.1
#最大间隔时间,最大2000ms
spring.cloud.config.retry.max-interval=2000
#最大重试次数,默认6次
spring.cloud.config.retry.max-attempts=6

ribbon.ConnectTimeout=3000
ribbon.ReadTimeout=3000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

#spring.rabbitmq.host=192.168.67.139
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=admin
#spring.rabbitmq.password=admin

management.endpoints.web.exposure.include=*

10. 重启服务

在这里插入图片描述

  • 再次请求

在这里插入图片描述

11. 过滤器

Zuul大部分功能都是通过过滤器来实现的,Zuul定义了4种标准的过滤器类型,这些过滤器类型对应于请求的典型生命周期。

  • pre: 这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择请求的微服务,记录调试信息等。
  • routing: 这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。
  • post: 这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的http header、收集统计信息和指标、将响应从微服务发送给客户端等。
  • error: 在其他阶段发送错误时执行该过滤器。

在这里插入图片描述

1、PreFilter

package com.spring.fisher.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
public class PreFilter extends ZuulFilter {
    @Override
    public String filterType() {
    	//设置过滤器类型
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //排序,数字越小,越优先执行
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().sendZuulResponse();
    }

    @Override
    public Object run() throws ZuulException {
        //获取上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //获取Request
        HttpServletRequest request = ctx.getRequest();
        //获取请求参数accessToken
        String accessToken = request.getParameter("accessToken");
        //使用String工具类
        if (StringUtils.isBlank(accessToken)) {
            log.warn("accessToken is empty");
            //设置为false不进行路由
            ctx.setSendZuulResponse(false);  //进行拦截
            ctx.setResponseStatusCode(401);
            try {
                ctx.getResponse().getWriter().write("accessToken is empty");
            } catch (Exception e) {
            }
            return null;
        }
        log.info("zuul pre filter-->" + request.getRequestURL() + "-->" + request.getMethod());
        log.info("access is ok");
        return null;
    }
}

  • http://localhost:7070/web/queryUser?accessToken=ok

在这里插入图片描述
在这里插入图片描述

  • http://localhost:7070/web/queryUser

在这里插入图片描述
在这里插入图片描述

  • 通过RequestContext.getCurrentContext().sendZuulResponse()获取sendZuulResponse的值,true则路由成功,false则不路由

在这里插入图片描述

  • 通过ctx.setSendZuulResponse(false)方法,设置sendZuulResponse的值,可以靠这个值做权限校验

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值