【Spring】优雅上下线

一、服务下线方案

(一)粗鲁下线

粗鲁下线应该绝对禁止

kill -n <pid> # n为信号变量
例:
kill -9 <pid> # 强制停止
kill -15 <pid> # 如果程序正在IO,可能不会立刻做出反映

在停止的那一霎那,应用中正在处理的业务逻辑会被中断,导致产生业务异常情形。

# 查看linux常见的信号变量
$ kill -l

参考:Linux kill -9 和 kill -15 的区别
在这里插入图片描述

普通服务优雅下线

(1)web容器优雅停止

在 Spring Boot 2.3 中增加了新特性优雅停止。下面都支持优雅停止
(1)Spring Boot 内置的四钟嵌入式 Web 服务器(Jetty、Reactor Netty、Tomcat 和 Undertow)
(2)反应式框架
(3)基于 Servlet 的 Web 应用程序

大概逻辑就是先停止外部的所有新请求,然后再处理关闭前收到的请求
在这里插入图片描述

application.yml 中添加一些配置来启用优雅停止

# 开启优雅停止 Web 容器,默认为 IMMEDIATE:立即停止
server:
  shutdown: graceful

# 最大等待时间
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

(2)SpringApplication.exit(context);

(3)acturator 的 shutdown 端点

自定义EndPoint - gitee.com

原理:执行 doClose() 方法,关闭并销毁 applicationContext

(4)自定义 ApplicationListener

Nacos 服务下线

(1) 创建脚本

k8s 容器生命周期中的prestop阶段配置一个执行脚本:

          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - '-c'
                  - 'curl -X POST  ''http://localhost:8080/actuator/stopService'';\'   # 
                  - sleep 30;

(2) 暴露出关闭接口

/** 使用了nacos注册中心的服务关闭端点配置 */
@ConditionalOnClass(NacosAutoServiceRegistration.class)
@RestController
@RequestMapping("actuator")
@RequiredArgsConstructor
@Slf4j
public class NacosStopEndpoint {
    private final NacosAutoServiceRegistration nacosAutoServiceRegistration;
    private final ApplicationContext context;

    /** 注销服务后关闭应用前等待的时间(毫秒) */
    @Value("${stopService.waitTime:10000}")
    private int waitTime;

    /**
     * 关闭服务 <br>
     * 只接收localhost发起的请求
     *
     * @param request
     * @return
     */
    @PostMapping("stopService")
    public ResponseEntity<Boolean> stopNacosService(HttpServletRequest request) {
        //只接受本机请求 
        if (!request.getServerName().equalsIgnoreCase("localhost")){
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(false);
        }
		//开启异步线程:先从Nacos注销,等待1000毫秒后,关闭容器
        new Thread(
                        () -> {
                            log.info("Ready to stop service");
                            nacosAutoServiceRegistration.stop(); // 一、从Nacos注销
                            log.info("Nacos instance has been de-registered");
                            log.info("Waiting {} milliseconds...", waitTime);
                            try {
                                Thread.sleep(waitTime); // 二、等待1000毫秒后
                            } catch (InterruptedException e) {
                                log.info("interrupted!", e);
                            }
                            log.info("Closing application...");
                            SpringApplication.exit(context); // 三、关闭容器
                            ((ConfigurableApplicationContext) context).close();
                        })
                .start();

        return ResponseEntity.ok(true);
    }
}

二、服务注销 原理

(一)Eureka 注销服务

Eureka Server 存在三个变量:(registry、readWriteCacheMap、readOnlyCacheMap) 保存服务注册信息

ReadWriteMap 读写缓存
ReadOnlyMap 只读缓存

在这里插入图片描述

定时任务
(1)定时任务每 30s 将 readWriteCacheMap 同步至 readOnlyCacheMap
(2)每 60s 清理超过 90s 未续约的节点
(3)Eureka Client 每 30s 从 readOnlyCacheMap 更新服务注册信息

在这里插入图片描述

(二)Nacos 注销服务-待续

nacos收到注销请求,如何注销服务?

三、参考

五星 - Spring Cloud使用了注册中心(nacos)的服务优雅下线方案
四星 - 优雅停机之主动从Nacos下线实例
五星 - SpringCloud 服务优雅上下线

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
对于Spring Cloud来说,平滑上下线是指在系统升级或者故障恢复过程中,保持服务的正常运行且对用户无感知。 首先,为了实现平滑上下线,我们需要使用负载均衡器来分发用户请求到多个实例上。在Spring Cloud中,可以使用Ribbon或者OpenFeign作为负载均衡器。通过将多个实例注册到注册中心并与负载均衡器进行关联,负载均衡器能够根据设定的策略将请求分发到不同的实例上,从而实现平衡负载和故障转移。 其次,为了实现平滑上下线,我们可以使用服务注册与发现组件如Eureka、Consul或者Zookeeper 来追踪服务实例的状态。当一个服务实例需要下线时,它可以主动向注册中心发送注销请求,并逐渐停止接收新的请求,同时继续处理已有请求直至全部处理完,最后才完全下线。这样能够避免因为突然下线而引起的服务不可用问题。 再次,为了实现平滑上下线,可以使用配置中心如Spring Cloud Config来集中管理服务的配置信息。这样,当我们需要修改配置或者应用新的配置时,可以通过配置中心来实现动态更新,而不需要重新启动服务。这样就能够避免服务的停机时间,保持服务的持续可用性。 最后,为了实现平滑上下线,我们可以使用熔断器如Hystrix来处理服务之间的依赖关系。当某个服务实例发生故障或者下线时,熔断器可以快速地切换到备用实例上,从而保证用户的请求能够得到及时响应。 总之,通过合理地使用负载均衡器、服务注册与发现组件、配置中心和熔断器,我们能够实现Spring Cloud的平滑上下线。这样既可以提高系统的可靠性和稳定性,又能够最大程度地减少对用户的影响,提供良好的用户体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机智的路易

用爱发电是走不远的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值