简介
在实际的工作中,服务的相互调用都是依赖于服务中心提供的入口来使用,服务中心往往注册了很多服务,如果每个服务都需要单独配置的话,非常麻烦。Spring Cloud Gateway 提供了一种默认转发的能力,只要将 Spring Cloud Gateway 注册到服务中心,Spring Cloud Gateway 默认就会代理服务中心的所有服务
代码实现
新建一个Module,命名为microservice-gateway,还涉及到两个服务,注册中心microservice-eureka,服务提供者microservice-feign
pom引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
因为网关也需要注册到注册中心,所以需要引入eureka的依赖
yml文件
server:
port: 8090
eureka:
client:
service-url:
#单机版
defaultZone: http://127.0.0.1:8761/eureka/
#集群模式
# defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
#是否与服务发现组件结合,通过serviceId转发到具体的实例。默认为false,设为true开始根据serviceId创建路由功能
enabled: true
#是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了)
配置解读
- spring.cloud.gateway.discovery.locator.enabled:是否与服务注册于发现组件进行结合,通过 serviceId 转发到具体的服务实例。默认为 false,设为 true 便开启通过服务中心的自动根据 serviceId 创建路由的功能。
- spring.cloud.gateway.discovery.locator.lowerCaseServiceId:是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了)。
服务提供者
@RestController
public class GatewayController {
@GetMapping("/hello")
public String hello(String name){
return "hello! " + name;
}
}
启动3个项目,用postman访问 http://localhost:8090/feign-service/hello?name=Java,返回信息
说明网关转发成功。
自定义请求路径
上面的例子中,我们请求的url为 /feign-service/hello?name=Java ,必须带上feign-service,才可以转发成功,但在实际开发中,有时服务名字过长,不易使用,想自定义一个简称来达到相同的效果,来改配置:
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
#是否与服务发现组件结合,通过serviceId转发到具体的实例。默认为false,设为true开始根据serviceId创建路由功能
enabled: false
#是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了)
lower-case-service-id: true
routes:
#自定义 全局唯一路由ID
- id: feign-service
#uri以lb://开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称
uri: lb://FEIGN-SERVICE
#谓词
predicates:
#匹配路由 http://ip:port/feign/** 的请求
- Path=/feign/**
#过滤器
filters:
#剥离请求路径 例如 http://ip:port/feign/FEIGN-SERVICE/hello ==> http://ip:port/FEIGN-SERVICE/hello
- StripPrefix=1
在上面的配置中,配置了一个Path 的 predicte,将以 /feign/** 开头的请求都会转发到uri为 lb://FEIGN-SERVICE的地址上,lb://FEIGN-SERVICE即feign-service服务的负载均衡地址,并用StripPrefix的filter 在转发之前将/feign去掉。同时将spring.cloud.gateway.discovery.locator.enabled改为false,如果不改的话,之前的localhost:8090/feign-service/hello?name=Java这样的请求地址也能正常访问,相当于为每个服务创建了2个router。