1. Spring Cloud 架构中为什么需要API gateway
避免暴露内部的微服务
很多时候, 有些微服务是不应该被外部(UI) 直接调用的,我们需要API gateway来拦截这些请求
方便进行用户认证
如果没有网关, 我们可能要对每个service 加入用户验证的代码
负载均衡
这个Eureka也可以实现
请求限流 (保护后面所有的微服务)
限制 请求数量, 避免系统崩溃
2. Zuul or Spring Cloud Gateway
Spring cloud 中实现网关的工具有两个 zuul , Gateway
zuul:
基于Servlet实现, 属于阻塞式编程.
Gateway:
基于Spring 5中提供的WebFlux, 属于响应式编程的实现, 更好的性能,更强的吞吐量。
3. 创建spring cloud gateway 项目
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Eureka Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
只需要引入4个依赖
spring cloud start gateway 这个是核心依赖
Eureka client 和 starter config 依赖是为了Eurke注册 和 集成config server.
注意不要引入spring-boot-starter-web 否则一大堆问题
启动类
没什么特别, 只需springboot 注解
package com.home.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoCloudApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(DemoCloudApiGatewayApplication.class, args);
}
}
本地配置文件
因为uat 和 prod 要注册不同的Eureka 来得到remote的配置文件, 所以本地需要两个bootstrap 配置文件
bootstrap-uat.yml
spring:
cloud:
config:
name: demo-cloud-api-gateway # means the config file service name
# uri: http://10.0.1.223:8888 # config-server ip
label: master # git branch
profile: common
discovery: # to use the config server in Eureka
enabled: true
service-id: demo-cloud-config-server
eureka:
client:
service-url:
defaultZone: http://10.0.1.223:8761/eureka #url of eureka service
instance:
prefer-ip-address: true
bootstrap-prod.yml
spring:
cloud:
config:
name: demo-cloud-api-gateway # means the config file service name
# uri: http://10.0.1.223:8888 # config-server ip
label: master # git branch
profile: common
discovery: # to use the config server in Eureka
enabled: true
service-id: demo-cloud-config-server
eureka:
client:
service-url:
defaultZone: http://43.138.xxx.xxx:3366/eureka #url of eureka service
instance:
prefer-ip-address: true
注意在本地两个配置文件中, spring.cloud.config.profile 都是common, 所以我们在common只需要1个配置文件用于配置 路由表
config server 远程配置文件
在这里我们配置了启动端口和 application name, 这些属性都是env无关的
server:
port: 8890
spring:
application:
name: demo-cloud-api-gateway # cannot use _
cloud:
gateway:
routes:
- id: demo-cloud-user-service
# uri: http://xxx.xx.xxx.x:xxxx Not suggestion to use
uri: lb://demo-cloud-user-service # lb means load balance
predicates: # url mapping
- Path=/user/**
- id: demo-cloud-user-service
uri: lb://demo-cloud-order-service # lb means load balance
predicates: # url mapping
- Path=/order/**
关键是路由表, id必须保证配置唯一, uri 表示 被重定向的地址, 由于我们继承Eureka, 所以写上注册id就可以, lb means 负载均衡。
predicates 表示你要为那些url地址重定向, 这些不难理解。
启动测试
启动后, 首先检查rureka 中心
见到api-gateway已注册
然后postman 测试其中1个端口, passed