springcloud-springcloudnetflix之zuul网关;路由(代码片段)

MinggeQingchun MinggeQingchun     2022-10-21     715

关键词:

阅读本文前可先参考

SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客

一、API网关

引自百度百科

API网关,软件术语,两个相互独立的局域网之间通过路由器进行通信,中间的路由被称之为网关

任何一个应用系统如果需要被其他系统调用,就需要暴露 API,这些 API 代表着一个一个的功能点。

如果两个系统中间通信,在系统之间加上一个中介者协助 API 的调用,这个中介者就是 API 网关

API 网关是一个搭建在客户端和微服务之间的服务,我们可以在 API 网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等。

API 网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例。

对于服务数量众多、复杂度较高、规模比较大的系统来说,使用 API 网关具有以下好处:

  • 客户端通过 API 网关与微服务交互时,客户端只需要知道 API 网关地址即可,而不需要维护大量的服务地址,简化了客户端的开发。
  • 客户端直接与 API 网关通信,能够减少客户端与各个服务的交互次数。
  • 客户端与后端的服务耦合度降低。
  • 节省流量,提高性能,提升用户体验。
  • API 网关还提供了安全、流控、过滤、缓存、计费以及监控等 API 管理功能。

常见的 API 网关实现方案主要有以下 5 种:

  • Spring Cloud Gateway
  • Spring Cloud Netflix Zuul
  • Kong
  • Nginx+Lua
  • Traefik

二、Zuul

Spring Cloud Zuul是 Netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。提供路由、监控、弹性、安全等方面的服务框架。Zuul 能够与 Eureka、Ribbon、Hystrix 等组件配合使用。

Zuul 包含了对请求的路由过滤两个最主要的功能,外加代理功能:

1、路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础

2、过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础

三、Zuul网关的作用

1、认证和安全:识别每个需要认证的资源,拒绝不符合要求的请求。

2、性能监测:在服务边界追踪并统计数据,提供精确的生产视图。

3、动态路由:根据需要将请求动态路由到后端集群。

4、压力测试:逐渐增加对集群的流量以了解其性能。

5、负载卸载:预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。

6、静态资源处理:直接在边界返回某些响应

1、路由功能

1、新建一个springboot Module(springcloud-7-service-eureka-zuul),设置父项目

2、添加 spring-cloud-starter-netflix-zuul等 依赖(由于Zuul最终会注册进eureka,所以我们此处也依赖了eureka

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

        <!-- spring-cloud-starter-netflix-zuul -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
<!--继承统一的父项目-->
    <parent>
        <groupId>com.company</groupId>
        <artifactId>springcloud-demo</artifactId>
        <version>1.0.0</version>
        <!--        <relativePath/> &lt;!&ndash; lookup parent from repository &ndash;&gt;-->
    </parent>

    <groupId>com.company</groupId>
    <artifactId>springcloud-7-service-eureka-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>springcloud-7-service-eureka-zuul</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--spring web 起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- springboot 开发自动热部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

3、application.prperties配置文件中配置访问端口81

server.port=81

#eureka注册中心首页的Application这一栏
spring.application.name=springcloud-7-service-eureka-zuul

#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,不是取机器名
eureka.instance.prefer-ip-address=false

#注册服务实例ID,,服务ID必须唯一
eureka.instance.instance-id=springcloud-7-service-eureka-zuul
#注册中心的链接地址  http://localhost:8761/eureka
eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka


#设置Zuul超时时间
zuul.host.connect-timeout-millis=6000
zuul.host.socket-timeout-millis=6000

4、在 Spring Boot 的启动类中,添加 @EnableZuulProxy 注解,开启zuul的网关支持

@EnableZuulProxy //开启zuul的网关支持
@SpringBootApplication
public class EurekaZuul7Application 
    public static void main(String[] args) 
        SpringApplication.run(EurekaZuul7Application.class, args);
    

5、创建服务消费者 springcloud-6-service-eureka-hystrix-consumer,服务提供者springcloud-6-service-eureka-hystrix-provider

@RestController
public class GoodsController 
    //产品服务的接口地址(直连)
//    private final String GOODS_SERVICE_URL = "http://localhost:9001/service/goodList";

    //产品服务的接口地址 (注册中心服务名)
    private final String GOODS_SERVICE_EUREKA_HYSTRIX_URL = "http://springcloud-6-service-eureka-hystrix-provider/eureka/hystrix/service/goodList";

    @Autowired
    private HystrixProviderGoodsRemoteClient hystrixProviderGoodsRemoteClient;


    @GetMapping(value = "/springcloud/eureka/hystrix/goodList1")
    public @ResponseBody Object getGoodList1()
        return hystrixProviderGoodsRemoteClient.goods();
    

6、启动springboot启动类,即可通过zuul然后加上对应的微服务名字访问微服务

微服务名调用

http://localhost:81/springcloud-6-service-eureka-hystrix-consumer/springcloud/eureka/hystrix/goodList1

http://localhost:81/  ;这个是Zuul 本身的

springcloud-6-service-eureka-hystrix-consumer ;这个是要调用的项目名称

/springcloud/eureka/hystrix/goodList1 ;这个是被调用的contrller上的接口路径

在实际开发当中我们肯定不会通过微服务名去调用,比如我要调用消费者可能只要一个 /springcloud/eureka/hystrix/goodList1 就好了,而不是

/springcloud-6-service-eureka-hystrix-consumer/springcloud/eureka/hystrix/goodList1

1、在application.properties配置文件中加入以下配置:

#配置路由规则
#/ **代表是所有(多个)层级   如:/springcloud/eureka/hystrix/goodHystrixList
#/ * 是代表一层; 如: /hystrix/goodHystrixList 就不会被路由
zuul.routes.portal.service-id=springcloud-6-service-eureka-hystrix-consumer
zuul.routes.portal.path=/web/**

#/ **代表是所有(多个)层级   如:/springcloud/eureka/hystrix/goodHystrixList
#/ * 是代表一层; 如: /hystrix/goodHystrixList 就不会被路由 

http://localhost:81/web/springcloud/eureka/hystrix/goodList1

此时我们能通过自定义的规则进行访问,但是我们现在依然能用之前的微服务名调用,这是不合理的,第一是有多重地址了, 第二一般微服务名这种最好不要暴露在外,所以我们一般会禁用微服务名方式调用。 

在application.properties配置文件中加入以下配置:

#通过自定义的规则进行访问,但是依然能用之前的微服务名调用,这是不合理的,第一是有多重地址了, 第二一般微服务名这种最好不要暴露在外,所以我们一般会禁用微服务名方式调用
# 禁用微服务名方式调用
zuul.ignored-services=springcloud-6-service-eureka-hystrix-consumer

一个一个通过微服务名来配置难免有点复杂,所以一般这样配置来禁用所有 

#通过自定义的规则进行访问,但是依然能用之前的微服务名调用,这是不合理的,第一是有多重地址了, 第二一般微服务名这种最好不要暴露在外,所以我们一般会禁用微服务名方式调用
# 一个一个通过微服务名来配置难免有点复杂,所以一般这样配置来禁用所有
# 禁用微服务名方式调用
zuul.ignored-services=*
#zuul.ignored-services=springcloud-6-service-eureka-hystrix-consumer

接口调用需要一定的规范,如调用微服务的API URL前缀需要加上/api

#接口调用需要一定的规范,如调用微服务的API URL前缀需要加上/api
#http://localhost:81/api/web/springcloud/eureka/hystrix/goodList1
zuul.prefix=/api  

完整application.properties配置文件

server.port=81

#eureka注册中心首页的Application这一栏
spring.application.name=springcloud-7-service-eureka-zuul

#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,不是取机器名
eureka.instance.prefer-ip-address=false

#注册服务实例ID,,服务ID必须唯一
eureka.instance.instance-id=springcloud-7-service-eureka-zuul
#注册中心的链接地址  http://localhost:8761/eureka
eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka


#设置Zuul超时时间
zuul.host.connect-timeout-millis=6000
zuul.host.socket-timeout-millis=6000

#配置路由规则
#/ **代表是所有(多个)层级   如:/springcloud/eureka/hystrix/goodHystrixList
#/ * 是代表一层; 如: /hystrix/goodHystrixList 就不会被路由
zuul.routes.portal.service-id=springcloud-6-service-eureka-hystrix-consumer
zuul.routes.portal.path=/web/**
#接口调用需要一定的规范,如调用微服务的API URL前缀需要加上/api
#http://localhost:81/api/web/springcloud/eureka/hystrix/goodList1
zuul.prefix=/api  


#通过自定义的规则进行访问,但是依然能用之前的微服务名调用,这是不合理的,第一是有多重地址了, 第二一般微服务名这种最好不要暴露在外,所以我们一般会禁用微服务名方式调用
# 一个一个通过微服务名来配置难免有点复杂,所以一般这样配置来禁用所有
# 禁用微服务名方式调用
zuul.ignored-services=*
#zuul.ignored-services=springcloud-6-service-eureka-hystrix-consumer

过滤了微服务名调用

前缀 /api

2、通配符规则

通配符

含义

举例

说明

匹配任意单个字符

/springcloud-service-openfeign/?

匹配

/springcloud-service-openfeign/a,

/springcloud-service-openfeign/b,

/springcloud-service-openfeign/c 等

*

匹配任意数量的字符

/springcloud-service-openfeign/*

匹配

/springcloud-service-openfeign/aaa,

/springcloud-service-openfeign/bbb,

/springcloud-service-openfeign/ccc 等,

无法匹配

/springcloud-service-openfeign/a/b/c

**

匹配任意数量的字符

/springcloud-service-openfeign/**

匹配

/springcloud-service-openfeign/aaa,

/springcloud-service-openfeign/bbb,

/springcloud-service-openfeign/ccc 等,

也可以匹配

/springcloud-service-openfeign/a/b/c