Spring Cloud Zuul作为API网关实现请求路由转发教程

  当我们的架构实现前后端分离以后,前端和后端之间交互就是通过API网关进行,API网关两个职责:

1.设计上的适配层,或称Facade模式,后端微服务可能过于细粒度,通过API网关进行内外适配,前后端转换,如果220v转换成110v一样。

2.运行阶段:将外部请求路由分发到内部各个微服务,负载平衡和路由策略是需要的。

  API网关,即边缘服务,为一组微服务提供统一的接口,以便客户无需了解微服务内部的所有细节。但是,在微服务架构中使用API​​网关模式有一些优缺点。

优点:

  • 为客户提供更简单的界面
  • 可用于防止将内部微服务结构暴露给客户端
  • 允许重构微服务而不强制客户端重构消耗逻辑
  • 可以集中安全,监控,速率限制等交叉问题

缺点:

  • 如果不采取适当措施使其具有高可用性,它可能会成为单点故障
  • 各种微服务API的知识可能会渗透到API网关中

  Spring Cloud提供类似于Nginx的代理 Zuul,可用于创建API网关。最新版本已经使用非堵塞的Spring Cloud Gateway替代了Zuul,当然我们还是能通过Zuul方便使用了解学习API网关。本文看看Zuul如何将前端请求转发到后端的微服务。

现在我们已经掌握了一个规律,建立一个Springcloud项目,一般主要首先是Maven的配置,然后就是元注解,第三就是application.properties,按照这个开发步骤:

第一步, pom.xml配置如下,也可以使用idea的新模块导航,选择Spring.io进行一步步设置,生成如下配置:

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

这里引入zuul库包是不奇怪的,那么为什么引入注册服务器呢?这个问题很好,本文我们将展示通过或不通过注册服务器两种应用场景:

1. 如果我们在application.properties配置

zuul.routes.producer.url=http://localhost:2111

这是将前端请求/producer/****都转发到端口2111上,这个功能就非常类似Nginx了,这种情况当然不需要服务注册服务器,因为没有有关服务信息,只是纯url信息。

2.如果我们在application.properties配置:

zuul.routes.peng.path=/producer/**
zuul.routes.peng.serviceId=PengProducerService

application.properties中Zuul路由的配置遵循以下模式:zuul.routes.+服务名称.+path或serviceId。这里我们随便取了服务名称peng,主要是为了辨识这个服务器名称在运行时是否起作用,当然实际中最好与服务名称一致,zuul.routes.peng.path=/producer/**就是将前端请求/producer/****都转发到zuul.routes.peng.serviceId=中定义的PengProducerService,这个服务在哪里呢?就需要服务注册器了,那么我们需要在pom.xml中配置eureka。

好了,除了以上两种情况的不同配置,我们在application.properties中还要配置:

spring.application.name=zuulrouter
server.port=8080
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

这是常例配置,如果不需要eurake就去除,端口是开在8080,这里直接面对前端的端口,正式环境可以是80端口,这类似Nginx作用。

第三步看看元注解:


@SpringBootApplication
@EnableZuulProxy
public class ZuulrouterApplication {

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

@EnableZuulProxy是需要的。

好了我们完成开发配置,下面可以运行测试,我们也分两种情况:

1. 先启动模块producer,测试第一种情况纯粹url转发:

http://localhost:8080/producer/articles

这个请求将被Zuul路由转发到2111端口的producer,访问其中/articles。

2.再启动eureka注册服务器,再启动producer,测试第二种情况:

http://localhost:8080/producer/articles

这是根据服务Id进行转发的。

为了测试两种情况对应注册服务器是否启动,可以对application.properties里面配置错配,比如使用服务Id转发,如果不启动注册服务器,则无法访问成功。

本文源码案例:百度网盘

附:API网关能够实现Nginx +Lua复杂的路由分发逻辑,包括动静网页分离,权限检查等,下面是application.yml格式的配置案例,学完以上教程以后应该能看懂:

logging:
level:
org.springframework.security: DEBUG
org.springframework.cloud: DEBUG
org.springframework.web: WARN

server:
port: 8080

spring:
aop:
proxy-target-class: true

zuul:
routes:
startpage:
path: /**
url: http://localhost:8081
resource:
path: /resource/**
url: http://localhost:9001/resource
user:
path: /user/**
url: http://localhost:9999/uaa/user

security:
oauth2:
client:
accessTokenUri: http://localhost:9999/uaa/oauth/token
userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
clientId: ui1
clientSecret: ui1-secret
resource:
userInfoUri: http://localhost:9999/uaa/user
preferTokenInfo: false
sessions: ALWAYS

 

Springcloud专题