11.SpringCloud - Spring Cloud Netflix 之 Zuul网关;路由(十一)
11.SpringCloud - Spring Cloud Netflix 之 Zuul网关;路由(十一)
阅读本文前可先参考
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/> <!– lookup parent from repository –>-->
</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/ ;这个是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 |
来源:https://blog.csdn.net/MinggeQingchun/article/details/125326667