目錄
1、GateWay網關概述
1.1、什麼是GateWay?
1.2、為什麼要使用微服務網關?
1.3、Zuul與GateWay網關的差別?
2、快速入門
2.1、建立項目
2.2、配置yml檔案
2.3、controller層
2.4、啟動類
2.5、啟動整體項目
2.6、配置全局過濾器
1、GateWay網關概述
1.1、什麼是GateWay?
SpringCloud Gateway是Spring Cloud 的一個全新項目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的API路由管理方式。
SpringCloud Gateway 作為Spring Cloud 生态系統中的網關,目标是替代Zuul,在Spring Cloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上 最新高性能版本進行內建,仍然還是使用的Zuul 1.x非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway是基于WebFlux架構實作的,而WebFlux架構底層則使用了高性能的Reactor模式通信架構Netty。
Spring Cloud Gateway的目标提供統一的路由方式且基于Filter鍊的方式提供了網關基本的功能,例如:安全,監控/名額,和限流。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0Y2N0YjMwUDNyIzMmJjYhRWMhRjYyE2M4UWYmRWOhJ2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1.2、為什麼要使用微服務網關?
不管是之前學習的的Zuul網關,還是今天所學阿裡推出的GateWay網關,學習它們的原因是為了什麼呢?
微服務網關是整個微服務api接口的入口,可以實作過濾Api接口。
作用:就是可以實作使用者的驗證登陸、解決跨域、日志攔截、權限控制、限流熔斷、負載均衡、黑名單和白名單機制等。 微服務中的架構模式采用前後分離,前端調用接口位址都能夠被抓包分析到。
1.3、Zuul與GateWay網關的差別?
之前已經學習過Zuul網關了,為什麼還要學習GateWay網關呢?
Zuul網關屬于NetFix公司開源架構,屬于第一代微服務網關
GateWay屬于SpringCloud自己研發的網關架構,屬于第二代微服務網關
相比來說GateWay 比Zuul網關的性能要好很多。
主要差別: Zuul網關底層基于Servlet實作,阻塞式api,不支援長連接配接,依賴SpringBoot-Web. SpringCloudGateWay基于Spring5建構,能夠實作響應式非阻塞式api,支援長連接配接,能夠更好的支援Spring體系産品,依賴SpringBoot-WebFux。
2、快速入門
2.1、建立項目
建立一個項目,名字随意
建立使用者項目,用來查詢使用者
建立eureka子產品
2.2、配置yml檔案
gateway網關子產品yml檔案
server:
port: 9857
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
##允許通過注冊中心擷取位址調用
enabled: true
#路由政策
routes:
#根據我們的服務名稱查找位址實作調用
- id: user-api
uri: lb://user-service
#比對規則
predicates:
- Path=/user/**
#這裡使用了eureka服務注冊中心,如果想用其他的随意
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka
使用者子產品的yml檔案
server:
port: 8081
spring:
application:
name: user-service
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_crud?useSSL=false&useUnicode=true&characterEncoding=utf-8
username: root
password:
mybatis:
type-aliases-package: cn.itssl.pojo
mapper-locations: classpath:mappers/*.xml
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka
instance:
# 更傾向使用ip位址,而不是host名
prefer-ip-address: true
# 續約間隔,預設30秒
lease-renewal-interval-in-seconds: 5
# 服務失效時間,預設90秒 服務失效時間是要比續約間隔時間大的
lease-expiration-duration-in-seconds: 10
eureka子產品yml檔案
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka
fetch-registry: false
register-with-eureka: false
server:
enable-self-preservation: false # 關閉自我保護機制 失效服務會被删除
eviction-interval-timer-in-ms: 10000 # 剔除失效服務的時間間隔
2.3、controller層
在user-service子產品,建立controller層,并實作相關業務
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${server.port}")
private String port;
@Autowired
private UserService userService;
@RequestMapping("/{id}")
public User queryById(@PathVariable String id) {
System.out.println("端口号為:"+port+"的user-service服務被調用了");
//查詢使用者業務,自行完成
return userService.getUserById(id);
}
}
2.4、啟動類
gateway-service子產品啟動類
@EnableEurekaClient
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
}
eureka子產品啟動類
@SpringBootApplication
@EnableEurekaServer //開啟服務端Eureka
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
使用者子產品啟動類
@SpringBootApplication
@MapperScan("cn.itssl.mapper")
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
2.5、啟動整體項目
備注:userService2是user-service的一個複制子產品,功能一模一樣,隻是yml檔案中spring.name不同而已。形成了一個user叢集
連續請求接口localhost:9857/user/2
可以看到請求成功,原本隻能通過localhost:8081/user/2,現在在外面又加上一層屏障,把真實的業務請求位址隐藏了,防止了不法分子對真實業務位址進行攻擊。
可以看到user叢集兩個都被通路了,達到了網關的負載均衡的功能。
2.6、配置全局過濾器
在gateway子產品中建立一個filter包,建立MyLogGateWayFilter類,實作兩個接口,分别是GlobalFiler全局過濾器,以及Ordered類。
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("進入了過濾器攔截");
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.info("非法請求,進行攔截....");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
log.info("符合請求要求,放行!");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
重新啟動項目,必須在後面帶有uname參數才能擷取到資料,不帶uname參數直接拒絕請求。