Gateway实战(二)、负载均衡

发布于:2025-03-29 ⋅ 阅读:(28) ⋅ 点赞:(0)

负载均衡

简单了解

我们引入负载均衡,主要是为了 让网络流量能均匀的分发到多个服务器上,以此来提高系统性能、可靠性和可扩展性,围绕这三个点:

  • 提高性能
    避免单点服务器因负载过高出现响应缓慢甚至崩溃的问题,通过让多个服务器共同处理请求来分担工作负载,来提升整体系统的处理能力和响应速度。
  • 增强可靠性
    当部分服务器出现故障,负载均衡器可以把流量自动分配到其他正常工作的服务器上,来保证服务正常可用,提高系统可用性和稳定性。
  • 实现可扩展性
    随着业务迭代,能方便添加新的服务器到负载均衡集群,来应对业务迭代过程中增加的用户请求和数据量,是系统能灵活扩展。

上一篇文章中的路由案例,是在网关中直接写好要路由到的地址,实际开发中的服务更多是注册在注册中心中。而且都有做集群的多节点的部署。我们可以通过负载均衡的方式来处理,在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 一致,在此不再赘述。