-
Spring Cloud Zuul是什么?
Spring Cloud Zuul提供API网关服务。 -
为什么需要API网关服务?
如果我们把项目拆分,构建成微服务,那原来只用于单体服务的鉴权功能,在每个拆分出来的微服务里都需要使用,保证每个服务单元都有和之前单体一样的鉴权逻辑。这时要是我们业务发展迅速,在该微服务体系上又多增加了几个服务单元,那么这新增的几个服务单元势必又要加上鉴权功能,这单单从代码的角度来说已经冗余了,更别提每次新增服务都要做增加鉴权的操作,太麻烦了,更恶心的是,要是这个鉴权服务,你哪天要改个什么,那不是所有服务都要改,想想就可怕。还有我们之前做负载和路由要么是硬件负载F5或者软件负载Nginx,我们服务少的时候可以把路由都靠F5或Nginx配置,但是每次增加服务,我们就得在F5或Nginx上增加对应路由规则,对开发来说,这种重复的事能做一次就别做第二次。
所以这时Spring Cloud Zuul就起到了统一路由配置和权限校验的作用(当然它不止这两个功能,但是这里只做简单实现),用了zuul,所有请求进来先过zuul这关,由zuul来做路由和鉴权,之后再分发请求到具体的服务单元,要是不符合条件,直接打回去。有点像门卫大叔,他会告诉你进小区后你要去的地方往哪走和决定你能不能进小区哈。
Spring Cloud Zuul的简单实现
- 传统路由的方式
这里在上篇博客里增加了一个模块,api-gateway,结构如下:
启动文件,增加@EnableZuulProxy开启zuul的api网关服务功能:
package com.example.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
配置文件如下:
spring:
application:
name: api-gateway
server:
port: 8766
#路由规则
zuul:
routes:
#自定义的路由服务名,以下的path和url要一致
hello-feign:
path: /hello-feign/**
url: http://localhost:8765/
hello-eureka:
path: /hello-eureka/**
url: http://localhost:8762/
以上路由配置表示请求的url类似:
/hello-feign/feign/{name}的都要跳转到http://localhost:8765/feign/{name}
/hello-eureka/helloWorld/{name}都要跳转到http://localhost:8762/helloWorld/{name}
测试下效果:
-
访问http://localhost:8766/hello-feign/feign/AA
-
访问http://localhost:8766/hello-eureka/helloWorld/AA
可以看出zuul根据url匹配到了我们配置的路由规则然后做了相应的跳转
- 面向服务的路由
传统的路由需要我们了解到每个服务节点的IP地址和端口,每当增加或修改时,我们都需要花费精力去维护path和url的关系。这时采用面向服务的路由方式就会显得简单方便许多。
现在我们把zuul也作为一个服务提供者注册到注册中心eureka上,修改后的代码如下:
启动文件增加@EnableEurekaClient,开启eureka客户端功能:
package com.example.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
配置文件:
spring:
application:
name: api-gateway
server:
port: 8766
zuul:
routes:
hello-feign:
path: /hello-feign/**
serviceId: eureka-feign-client
hello-eureka:
path: /hello-eureka/**
serviceId: eureka-client
#注册到注册中心上
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
可以看到我们现在配置文件里用的是path和serviceId方式了
注册中心如下:
测试下效果:
-
访问http://localhost:8766/hello-feign/feign/AA
-
访问http://localhost:8766/hello-eureka/helloWorld/AA
可以看出效果其实是一样的。