前言
服务端提供 RestFul API ,客户端如果想要使用某个服务直接调用服务的API 即可。但是在微服务环境中会有很多的具体服务,而客户端在调用众多的服务时直接和具体的服务打交道这样虽然可以实现,但是处理方式并不是很好。而服务网关就是用来专门解决这一个问题的。
有了网关后可以将各个服务的API 都接入到网关中,客户端直接调用网关即可。一个业务可能需要多个服务进行参与才能完成,这时可以通过服务网关将多个服务进行聚合。在有就是引入网关后可以将安全验证、用户权限验证、服务流量控制统一在网关层做处理,无需每个服务在独自做这些操作。
目前开源的服务网关有:Kong、Zuul/Zuul2、OpenResty、Tyk。我们今天要介绍的就是SpringCloud 集成 Netflix 的开源网关Zuul 使用的简单介绍。
阅读本文需要你熟悉SpringBoot项目的基本使用即可,还有一点需要注意的是在操作过程中尽量和我本地环境一致,因为环境不一致可能会带来一些问题。我本地环境如下:
SpringBoot Version: 2.1.0.RELEASE
SpringCloud Version: Greenwich.RELEASE
Apache Maven Version:3.6.0
Java Version:1.8.0_144
IDEA:Spring Tools Suite (STS)
Zuul 的简单介绍
Zuul 核心是通过一系列的过滤器来完成整个网关的操作,具体过滤器有如下4中:
PRE :前置过滤器,在调用具体服务前执行,常见的操作如:身份验证,安全校验
ROUTING:路由过滤器,它的作用是将访问网关的请求路由到具体的服务。
POST:后置过滤器,在调用服务后执行。常见的操作如:统计访问请求、请求日志
ERROR:错误过滤器,当调用服务发生错误是执行。
Zuul 服务请求声明周期流程如下图:
SpringCloud Zuul 环境搭建
SpringCloud Zuul 环境最小配置列表如下:
一台 Eureka 服务注册中心(Eureka Server 端)
一台用户服务
一台 Zuul 网关服务
其中用户服务端和Zuul 网关服务 同时也是 Eureka Client 端。
第一步:创建一个新的SpringBoot 项目来搭建Eureka 服务注册中心,关于如果搭建Eureka 服务注册中心请参考:带你入门SpringCloud服务发现Eurka搭建和使用 或者直接使用 spring-cloud-get-started 仓库中模块名为:spring-cloud-zuul-eureka-service 项目即可,项目地址参考文章末尾处介绍。
第二步:创建一个新的SpringBoot 项目来搭建 Zuul 网关服务,首先需要在Zuul 网关服务引入SpringCloud、Eureka 、Zuul 的 starter 依赖,具体代码入下:
xml version="1.0" encoding="UTF-8"?>
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.0.RELEASE
cn.zhuoqianmingyue
spring-cloud-zuul-service
0.0.1-SNAPSHOT
spring-cloud-zuul-service
Demo project for Spring Boot
1.8
Greenwich.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-zuul
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
zuulService
org.springframework.boot
spring-boot-maven-plugin
maven-compiler-plugin
1.8
1.8
true
第三步:在Zuul 网关服务启动类上声明 @EnableZuulProxy 注解
@SpringBootApplication
@EnableZuulProxy
public class SpringCloudZuulServiceApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudZuulServiceApplication.class, args);
}
}
第四步:在Zuul 网关服务的application.properties 中添加入下配置:
spring.application.name=api-gateway
server.port=8060
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka/
spring.application.name: Zuul 网关服务的名称
server.port:Zuul 网关服务端口
eureka.client.service-url.defaultZone:Eureka Server 服务端地址
第五步:搭建用户服务,用户服务这里就不做过多的阐述了。
用户服务 pom.xml 具体配置如下:
xml version="1.0" encoding="UTF-8"?>
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.0.RELEASE
cn.zhuoqianmingyue
spring-cloud-zuul-user-service
0.0.1-SNAPSHOT
spring-cloud-zuul-user-service
Demo project for Spring Boot
1.8
Greenwich.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-config-client
org.springframework.cloud
spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-bus-amqp
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
zuulUserService
org.springframework.boot
spring-boot-maven-plugin
maven-compiler-plugin
1.8
1.8
true
用户服务增删改查API服务接口类具体代码如下:
@RestController()
@RequestMapping("/user")
public class UserController {
Logger log = LoggerFactory.getLogger(UserController.class);
/**
* 根据用户id 查询用户
* @return
*/
@GetMapping("/{id}")
public ResponseEntity<User> get(@PathVariable(name = "id") Long id){
User user = new User("lijunkui",18);
log.info("查询用户成功:"+"id:{}",id);
return ResponseEntity.ok(user);
}
/**
* 查询所有的用户
* @return
*/
@GetMapping("/")
public ResponseEntity<List<User>> getAll(){
List<User> userList = new ArrayList<User>(){{
add(new User("lijunkui1",18));
add(new User("lijunkui2",18));
add(new User("lijunkui3",18));
}};
return ResponseEntity.ok(userList);
}
/**
* 添加用户
*/
@PostMapping("/")
public ResponseEntity<User> add(@RequestBody User user){
log.info("添加用户成功:"+"name:{},age:{}",user.getName(),user.getAge());
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
/**
* 更新用户
* @param user
* @return
*/
@PutMapping("/")
public ResponseEntity<Void> updatePut(@RequestBody User user){
log.info("修改用户成功:"+"name:{},age:{}",user.getName(),user.getAge());
return ResponseEntity.ok().build();
}
/**
* 局部更新
* @return
*/
@PatchMapping("/{name}")
public ResponseEntity<Void> updatePatch(@PathVariable("name") String name){
log.info("修改用户成功:"+"name:{}",name);
return ResponseEntity.ok().build();
}
/**
* 删除用户
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable("id") Long id){
log.info("删除用户成功:"+"id:{}",id);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
}
因为用户服务同时是 Eureka Client 所以在启动类上声明 @EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudZuulUserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudZuulUserServiceApplication.class, args);
}
}
用户服务端 application.properties 中配置内容如下:
spring.application.name=user
server.servlet.context-path=/userService
server.port=8763
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka/
到这里最简 Zuul 环境搭建完毕!
关于Zuul 高可用用直接搭建多个 Zuul 服务注册到 Eureka Server 端即可。如果你想让Zuul 服务实现动态路由,搭建Zuul 服务 SpringCloud Config 环境即可。具体操作请参考
带你入门SpringCloud统一配置SpringCloudConfig
带你入门SpringCloud之通过SpringCloud Bus自动更新配置
测试
首先启动 Eureka 服务注册中心,然后在启动用户服务和 Zuul 网关服务。
访问Eureka 服务注册中心 http://127.0.0.1:8761,具体效果如下图所示:
访问用户服务链接地址:http://localhost:8763/userService/user/,具体效果如下图:
访问Zuul 网关服务链接地址:http://localhost:8060/user/userService/user/,具体效果如下图:
通过Zuul 访问具体服务规则 Zuul 服务 IP+Zuul服务端口号+访问服务应用名称+访问服务 API
在 application.properties 通过 spring.application.name 配置访问服务应用名称,还有一点要注意的是服务名称只能使用小写。
小结
Zuul 环境搭建大致步骤如下:
引入 Eureka 和 Zuul 的 starter 依赖
启动类上声明 @EnableZuulProxy 注解
配置文件中配置 Eureka Server 地址
当然还需要搭建 Eureka 注册中心和用户服务,本文主要介绍 Zuul 环境搭建和简单使用,后面会陆续讲解 Zuul 其他具体使用配置。
代码示例
如果你按照上述方式搭建并未成功,可以参考我在GitHub 项目 spring-cloud-get-started 仓库中模块名为:
spring-cloud-zuul-eureka-service
spring-cloud-zuul-service
spring-cloud-zuul-user-service
进行对比查看是否配置有误。
GitHub项目地址:https://github.com/zhuoqianmingyue/spring-cloud-get-started
参考文献
https://github.com/Netflix/zuul/wiki
https://medium.com/netflix-techblog/announcing-zuul-edge-service-in-the-cloud-ab3af5be08ee