服务网关
网关是介于服务端和客户端之间的,所有请求进来都会经过网关这一层.安全、性能、监控这些都可由网关来做
就像我们进学校所有学生都必须经过校门,在门口刷卡识别,才能通过门禁的检查才能进学校
不同微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会出现一些问题
• 客户端会多次请求不同的微服务,增加了客户端的复杂性
• 存在跨域请求,在某些场景下处理相对复杂
• 认证复杂,每个服务都需要独立认证
• 难以重构
• 某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有困难
优点
• 安全,只有网关系统暴露在外面,所有微服务都在内部
只有校门暴露在外面,里面有些什么东西都在学校里面
• 容易监控,可以在网关收集数据并分析
• 减少了客户端直接和微服务交流的操作
• 容易同意鉴权
SpringCloud gateWay 使用WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactro模式通信框架Netty
Gateway 的 三大核心概念
• Route(路由)
路由就是构建网关的基本模块,它由ID,目标URL,一系列的断言和过滤器组成,如果断言为true则匹配该路由
• Predicate (断言)
匹配HTTP请求中的所有内容(例如请求头和请求参数),如果请求域断言匹配则进行路由
• Filter (过滤)
使用过滤器,可以在请求前或请求后进行修改
Gateway 配置路由
方式1 在yml里面写相关配置
创建一个Spring Cloud gateway 工程
添加 pom
<dependencies>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--引入自定义的api通用包,可以使用Payment支付Entity-->
<dependency>
<groupId>com.example.common</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
web Gateway不需要web依赖,会报错
写配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_routh #payment_route 路由的ID 没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/**
- id: payment_routh2
uri: http://localhost:8001
predicates:
- Path=/payment/lb/**
eureka:
client:
register-with-eureka: true #是否将自己注册到注册中心,集群必须设置为true配合ribbon
fetch-registry: true #是否从服务端抓取已有的注册信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka
在主类上开启 注入进注册中心 Eureka
启动注册中心 7001,payment服务8001,启动网关 进行测试
查看两个服务都注入进去了
访问说明
• 添加网关之前:http://localhost:8001/payment/get/1
• 添加网关之后:http://localhost:9527/payment/get/1
测试可以访问
方式2 编码的方式配置
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
return routeLocatorBuilder.routes()
.route("path_route_george", r -> r.path("/guonei").uri("http://news.baidu.com/guonei"))
.build();
}
}
测试访问成功
动态配置路由
默认的情况是Gateway会根据注册中心注册的服务列表,以注册中心上的微服务名为路径创建 动态路由进行转发,从而实现动态路由
一个eureka7001 + 两个服务提供者8001/8002
更改 yml 的配置
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route 路由的ID 没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址 (非动态路由)
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/**
- id: payment_routh2
#uri: http://localhost:8001
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/**
eureka:
client:
register-with-eureka: true #是否将自己注册到注册中心,集群必须设置为true配合ribbon
fetch-registry: true #是否从服务端抓取已有的注册信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka
访问 7001 注册中心 8002之前配置了启动就可以注册进去
测试 使用9527 访问,刷新查看可以看到 访问成功 8001 和 8002 轮询