引言
SpringBoot可以用上一篇文章中的插件(优雅停机插件地址)实现停机,但是在微服务情况下贸然使用,还是会导致请求丢失并不是我们需要的平滑、优雅更新发布
可能出现问题
发布的过程中,请求还是在接收,但是后台服务已经在重启,导致请求丢失,从而出现生产问题
解决思路
在需要关闭的项目服务中,对外暴露一个接口,相当于先给服务从注册中心下线,然后再关闭程序
解决方案
1.引入相关微服务的jar包pom
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>版本号</version>
</dependency>
注意事项:
这里的 版本号 需要替换为您需要使用的 Nacos Spring Cloud Starter 的实际版本。您可以访问 Maven Central Repository 或查阅 Alibaba Cloud 官方文档来获取最新的稳定版本。举例来说,如果您打算使用 Nacos Spring Cloud Starter 的 2.2.3.RELEASE 版本,那么对应的依赖声明如下:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
确保将上述依赖添加到您的项目的 pom.xml 文件中 <dependencies> 标签下,然后执行 mvn clean install 或相关构建命令,Maven 将自动下载并引入所需的 Nacos Spring Cloud Starter 库,包括 NacosAutoServiceRegistration 类。记得定期检查并更新到官方发布的最新版本,以便获取 bug 修复、性能改进和新特性支持。
2.新建一个类,比如:NacosServiceDownLinePointcut,用于暴露对外使当前服务在注册中心下线
import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@ConditionalOnClass(NacosAutoServiceRegistration.class)
@RestController
@RequestMapping("/actuator")
@RequiredArgsConstructor
@Slf4j
public class NacosServiceDownLinePointcut {
private final NacosAutoServiceRegistration nacosAutoServiceRegistration;
private final ApplicationContext context;
/**
* 关闭服务 <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注销,
new Thread(
() -> {
log.info("Ready to stop service");
// 一、从Nacos注销
nacosAutoServiceRegistration.stop();
log.info("Nacos instance has been de-registered");
}).start();
return ResponseEntity.ok(true);
}
}
3.运维端配置
可以告诉运维人员,在使用Springboot优雅停机之前,先调这里暴露的接口。例如:
http://test:8080/actuator/stopService 先进行服务下线,让服务先不接收新的请求
结尾
个人经验,不喜勿喷,有错误可以指出来更正,或者大家在评论区讨论