K8S下SpringCloud应用无损下线

废话不多说直接上代码,一种2个步骤

步骤一: 添加以下代码到SpringCloud应用中

 



import cn.hutool.extra.spring.SpringUtil;
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.ConfigurableApplicationContext;
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;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 使用了nacos注册中心的服务关闭端点配置
 */
@ConditionalOnClass(NacosAutoServiceRegistration.class)
@RestController
@RequestMapping("actuator")
@RequiredArgsConstructor
@Slf4j
public class NacosStopEndpoint {
    private final NacosAutoServiceRegistration nacosAutoServiceRegistration;
    /**
     * 注销服务后关闭应用前等待的时间(毫秒)
     */
    private int waitTime = 30000;


    /**
     * 关闭服务 
* 只接收localhost发起的请求 * * @param request * @return */ @PostMapping("stopService") public ResponseEntity stopNacosService( HttpServletRequest request) throws UnknownHostException { if (!request.getRemoteHost().equalsIgnoreCase("127.0.0.1")) { log.warn("非法访问 尝试关闭应用 远程地址[{}]", request.getRemoteHost()); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(false);//非本机访问直接return 防止外部攻击 } new Thread(() -> { log.info("Nacos instance has been de-registered"); nacosAutoServiceRegistration.stop(); log.info("Waiting {} milliseconds...", waitTime); try { Thread.sleep(waitTime); } catch (InterruptedException e) { log.info(Thread.currentThread().getName() + " interrupted!", e); } log.info("Spring close……"); ((ConfigurableApplicationContext) SpringUtil.getApplicationContext()).close(); log.info("Spring closed……"); System.exit(0); }, "Application Closed Thread").start(); return ResponseEntity.ok(true); } }

步骤二:

配置K8S的工作负载的preStop函数 , 如下
 

["curl","-X","POST","http://127.0.0.1:8080/actuator/stopService","&&","sleep","30"]

大功告成!从此以后应用下线再也不会丢流量了!

你可能感兴趣的:(kubernetes,spring,cloud,容器)