spring cloud Alibaba- Gateway实战二:负载均衡
负载均衡
简单了解
我们引入负载均衡,主要是为了 让网络流量能均匀的分发到多个服务器上,以此来提高系统性能、可靠性和可扩展性,围绕这三个点:
- 提高性能
避免单点服务器因负载过高出现响应缓慢甚至崩溃的问题,通过让多个服务器共同处理请求来分担工作负载,来提升整体系统的处理能力和响应速度。 - 增强可靠性
当部分服务器出现故障,负载均衡器可以把流量自动分配到其他正常工作的服务器上,来保证服务正常可用,提高系统可用性和稳定性。 - 实现可扩展性
随着业务迭代,能方便添加新的服务器到负载均衡集群,来应对业务迭代过程中增加的用户请求和数据量,是系统能灵活扩展。
上一篇文章中的路由案例,是在网关中直接写好要路由到的地址,实际开发中的服务更多是注册在注册中心中。而且都有做集群的多节点的部署。我们可以通过负载均衡的方式来处理,在Gateway中有两种负载均衡的方式,分别为自动负载均衡和手动负载均衡。
一)、实操案例-自动负载均衡
step1 、新建两个maven项目,端口分别为9001,9002做为两个服务提供者。
1、9001应用的yaml文件内容配置:
server:
port: 9001
spring:
application:
name: nacos-provider
cloud:
discovery:
server-addr: 172.18.102.252:80
management:
endpoint:
web:
exposure:
include: '*'
对应web接口 /hello
/**
* @Auther: gina
* @Date: 2025-03-10
* @Description:
*/
@RestController
@Slf4j
public class UserController {
@GetMapping("/hello")
public String hello(HttpServletRequest request) {
log.info("........Nacos Provider run..");
return "9001-----hello Nancy...";
}
}
在主启动类增加服务发现注解,服务启动后会注册到nacos注册中心;
@EnableDiscoveryClient
@SpringBootApplication
public class NacosProvider9001Application {
public static void main(String[] args) {
SpringApplication.run(NacosProvider9001Application.class, args);
}
}
2、9002应用的yaml文件内容配置:
server:
port: 9002
spring:
application:
name: nacos-provider
cloud:
discovery:
server-addr: 172.18.102.252:80
management:
endpoint:
web:
exposure:
include: '*'
对应web接口 /hello
/**
* @Auther: gina
* @Date: 2025-03-10
* @Description:
*/
@RestController
@Slf4j
public class UserController {
@GetMapping("/hello")
public String hello(HttpServletRequest request) {
log.info("........Nacos Provider run..");
return "9002-----hello Nancy...";
}
}
在主启动类增加服务发现注解,服务启动后会注册到nacos注册中心;
@EnableDiscoveryClient
@SpringBootApplication
public class NacosProvider9002Application {
public static void main(String[] args) {
SpringApplication.run(NacosProvider9001Application.class, args);
}
}
step2、新建一个gateway-service端口9966
对应yaml文件内容
server:
port: 9966
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: 172.18.102.252:80
gateway:
discovery:
locator:
enabled: true
在调用方,也就是网关侧引入负载均衡相关的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
在主启动类增加服务发现注解,服务启动后会注册到nacos注册中心;
@EnableDiscoveryClient
@SpringBootApplication
public class Gateway9966Application {
public static void main(String[] args) {
SpringApplication.run(Gateway9966Application.class, args);
}
}
step3、启动服务提供这9001,9002以及网关服务9966
1、三者启动后,可以在注册中心查看到对应服务已经注册:
其中服务提供者nacos-provider
有2台,点击详情可以查看到:
通过网关gateway服务访问提供者接口,在前端访问相同接口,根据接口响应可以看出,访问的请求会路由到9001和9002两个服务。
- 请求链接
http://localhost:9966/nacos-provider/hello - 测试结果
自动路由默认轮训的方式,分两次访问,发现分别对应不同服务:
按照以上操作步骤,不难看出,自动负载均衡有个不好的点:请求服务时,需要暴漏注册中心的服务名称。接下来我们可以通过手动负载均衡规避这个缺点。
二)、实操案例-手动负载均衡
1、手动负载均衡方式一
上面的自动负载均衡案例,存在暴漏当前服务名称的问题,可以通过手动配置负载均衡,有效规避暴漏服务名称的问题。
step1、gateway9966应用的yaml文件内容:
server:
port: 9966
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: 172.18.102.252:80
gateway:
discovery:
locator:
enabled: false # 开启注册中心路由功能
routes:
- id: nacos-provider
uri: lb://nacos-provider #路由到注册中心,服务为nacos-provider的服务
predicates:
- Path=/nancy/** # 路径匹配,则进行路由
management:
endpoint:
web:
exposure:
include: '*'
配置路由,访问服务时,增加断言指定的路径,会映射到对应uri的服务,从找找到对应接口。
step2、两个服务提供者的yaml文件内容都要调整
servlet.context 都要配置 /nancy/
,9001服务提供者,yaml文件内容:
server:
port: 9001
servlet:
context-path: /nancy/
spring:
application:
name: nacos-provider
cloud:
discovery:
server-addr: 172.18.102.252:80
management:
endpoint:
web:
exposure:
include: '*'
9002服务提供者,yaml文件内容:
server:
port: 9002
servlet:
context-path: /nancy/
spring:
application:
name: nacos-provider
cloud:
discovery:
server-addr: 172.18.102.252:80
management:
endpoint:
web:
exposure:
include: '*'
step3、测试验证
1、启动gateway网关服务,以及两个提供者。可以看到已经注册到nacos注册中心。
2、进行测试访问
- 链接
http://localhost:9966/nancy/hello - 效果
连续访问两次,返回结果分别如下图:
但是这种方式还是差点意思,如果按照这样操作,每次需要做负载均衡,都要到对应的服务提供者添加servlet上下文路径,这就很麻烦了。可以借助过滤器,把请求路径的第一部分省略掉,这样就不用到服务提供者去添加servlet上下文路径了,这样说起来可能比较繁琐,我直接上实操吧。
2、手动负载均衡方式二
基于手动负载均衡方式一的操作案例,服务提供者9001和9002的yaml文件调整,去掉内容:
servlet:
context-path: /nancy/
9001,9002服务的yaml具体内容一样,端口调整下即可,参看:
server:
port: 9002
spring:
application:
name: nacos-provider
cloud:
discovery:
server-addr: 172.18.102.252:80
management:
endpoint:
web:
exposure:
include: '*'
对gateway网关服务的yaml文件的调整,则在predicates断言的同级下增加
filters:
- StripPrefix=1
增加的这部分内容表示截取掉断言路径的第一部分,具体:
server:
port: 9999
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: 172.18.102.252:80
gateway:
discovery:
locator:
enabled: false # 开启注册中心路由功能
routes:
- id: nacos-provider
uri: lb://nacos-provider
predicates:
- Path=/nancy/**
filters:
- StripPrefix=1
management:
endpoint:
web:
exposure:
include: '*'
验证环节,同手动负载均衡step3 一致,在此不再赘述。