Spring Cloud Gateway + 注册服务 ( Consul ) 实现负载均衡
前言
在微服务( SpringBoot )的使用过程中,一直在用 Zuul 作为网关服务程序,但很久很久以前,就传出 Spring Cloud Zuul 已经停止维护,并且使用 Spring Cloud Gateway 代替;但一直没有在实际项目中替换使用 Gateway 的想法(懒)。
最近,由于疫情的影响公司似乎是要凉凉,所以工作的事情比较少。就打算对服务中的网关程序下手,并看看是不是可以解决之前在 Zuul 的历史遗留问题。(最后还是没有解决...)
想一想
接触 Spring 微服务以来,两年时间里一直使用 SpringBoot + Zuul + Consul 的组合;通过注册服务( Consul )来集合和管理各个微服务程序,网关( Zuul )通过配置的关键字跳转到不同的微服务程序。
这一次,只替换网关部分的程序,用 Spring Cloud Gateway 替换 Zuul 。
Gateway 的配置与 Zuul 类似,替换难度不大;这里主要说说项目的 Gateway 项目的搭建,并与测试项目联调。
工具和版本说明
- 集成开发工具:IDEA 2020.2.3
- 编译管理工具:Maven 3.6.3
- Spring Cloud 版本:2020.0.0-M5
- Spring Boot 版本:2.4.0
动手做
使用 Spring Initializr 在 IDEA 中创建两个 Module,一个是 Gateway 程序,一个是用户测试的微服务程序。
Maven 引入
Gateway 项目中包含的库:
spring-cloud-starter-gateway
测试项目中包含的库:
spring-boot-starter-web
两个项目中都需要包含的库:
spring-cloud-starter-consul-discovery
spring-boot-starter-actuator
spring-boot-devtools
spring-boot-configuration-processor
yaml 配置
Gateway 程序的 yaml 配置文件,使用最简配置
spring:
application:
name: gateway #定义应用名称
cloud:
consul:
host: 127.0.0.1 # Consul 服务的地址
discovery:
ip-address: ${spring.cloud.client.ip-address}
prefer-ip-address: true # 使用 IP 地址作为调用地址,而不使用主机名
healthCheckInterval: 1s # 健康检查间隔
gateway:
routes:
- id: test # 应用ID(名称)
uri: lb://test # URI,lb表示从发现服务进行服务的路由
predicates:
- Path=/test/** # 路径调整条件
filters:
- StripPrefix=1 # 截取路径的层级数 /t1/** 填 1, /t1/t2/** 填 2,以此类推
测试程序的 yaml 配置文件,因为要启动多个实例以达到负载均衡的效果,所以创建三个配置信息,其中主要的配置是一样的,是有服务端口变化。
第一个配置文件也是主要的配置信息。
server:
port: 8081
spring:
application:
name: test
cloud:
consul:
host: 127.0.0.1
discovery:
ip-address: ${spring.cloud.client.ip-address}
prefer-ip-address: true
healthCheckInterval: 1s
其他两个只是定义服务端口。
文件 application-test1.yaml
server:
port: 8082
文件 application-test2.yaml
server:
port: 8083
测试用 Controller 类
在测试程序项目中添加 TestController ,测试用 Controller 类。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("hi")
public class TestController {
@Value(value = "${server.port}")
private Integer port;
@GetMapping("get")
@ResponseBody
public String get() {
// 每个被访问的 Controller 输出各自服务的端口号加以区分
return "Test is OK. Server port : " + port;
}
}
启动 Gateway 服务
启动 Test 程序
复制 Test 程序启动配置
下图中选择Copy Configuration...
;
复制后修改名称和启动参数,以达到启动器调用不同的配置文件,启动不同的服务端口。
启动后各个服务程序的状态
IDEA 中 Services 界面:
Consul Web UI 界面:
启动浏览器看看效果
启动浏览器,访问地址http://127.0.0.1:8080/test/hi/get
并不断刷新,可以看到页面的内容会在 3 个测试服务中依次显示
Test is OK. Server port : 8081
Test is OK. Server port : 8082
Test is OK. Server port : 8083
遗留问题
当测试程序中的其中一个节点停止后,网关( Gateway 和 Zuul )并不会立即停止对给服务程序的访问,短暂的还是会有跳转到已经关闭的服务程序中去。
参考
Spring Cloud Gateway替代zuul作为API网关(一)
SpringCloud组件的停更和替换说明
Spring boot之@Value注解的使用总结
Spring Cloud Consul 注册服务failing,但是可以访问
SpringCloud实战十三:Gateway之 Spring Cloud Gateway 动态路由
SpringCloud gateway (史上最全)
SpringCloud Gateway 修改请求路径的过滤器(StripPrefix Filter和PrefixPath Filter)
- 0
- 0
-
分享