前言
最近在搭建基于k8s和springcloud的分布式开发集群。需要用到springcloud gateway来做网关。在配置网关服务的时候,遇到了点小坑,记录下。
我们的需求是,将集群里的服务统一通过gateway对外暴露端口,并在gateway里做相应的处理,如打印日志,设置请求头,接口验签,限流降级等。
业务服务在内网通过ingress暴露url,提供集群外访问,地址如:http://${user-ingress-url}/user-service/api/v1/xxxx
。
对外网通过gateway暴露接口,地址如:https//${gateway-url}/gw/user-service/api/v1/xxxx
。
接下来需要做的事情是,通过配置gateway的配置文件application.yaml,通过服务注册发现组件和k8s的service来分别实现请求转发的负载均衡能力。
使用服务注册发现组件,如nacos或者eureka
不管是用nacos还是eureka做服务注册发现,在gateway侧的配置都是一样的,下面以nacos举例。假设有个服务user-service注册在了nacos上:
那么,对应gateway的application.yaml配置如下:
spring:
cloud:
gateway:
# 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
discovery:
locator:
enabled: true
# 配置路由规则
routes:
# 采用自定义路由 ID(有固定用法,不同的 id 有不同的功能,详见:https://cloud.spring.io/spring-cloud-gateway/2.0.x/single/spring-cloud-gateway.html#gateway-route-filters)
- id: user-service
# 采用 LoadBalanceClient 方式请求,以 lb:// 开头,后面的是注册在 Nacos 上的服务名
uri: lb://user-service
predicates:
- Path=/user-service/**
filters:
# StripPrefix是url过滤器,1表示请求转发给后端业务服务时,去掉上面Path里从左往右的第1个路径,即user-service
- StripPrefix=1
使用k8s自带的service
由于业务服务是基于k8s托管的,所以天然支持负载均衡,可以在gateway中调用业务服务对应的service地址即可。配置如下:
spring:
cloud:
gateway:
# 配置路由规则
routes:
# 采用自定义路由 ID(有固定用法,不同的 id 有不同的功能,详见:https://cloud.spring.io/spring-cloud-gateway/2.0.x/single/spring-cloud-gateway.html#gateway-route-filters)
- id: user-service
# 采用k8s的service,user-service即为业务服务通过service暴露的url,端口是80
uri: http://user-service
predicates:
- Path=/user-service/**
filters:
# StripPrefix是url过滤器,1表示请求转发给后端业务服务时,去掉上面Path里从左往右的第1个路径,即user-service
- StripPrefix=1
注意: 使用k8s自带service提供负载均衡时,业务服务的service端口最好保持在80,保证gateway能顺利将请求转发到业务服务上,这里貌似不支持service:port
的形式(需要进一步研究源码看下)