Spring Boot 최신 판 우아 한 정지 방법 을 자세히 알 아 보 세 요.
먼저 간단 한 코드 를 주세요.다음 과 같 습 니 다.
@RestController
public class DemoController {
 @GetMapping("/demo")
 public String demo() throws InterruptedException {
 //           
 Thread.sleep(20 * 1000L);
 return "hello";
 }
} 
 오픈 소스 항목:
분산 식 모니터링(Gitee GVP 의 가장 가치 있 는 오픈 소스 프로젝트):https://gitee.com/sanjiankethree/cubic
카메라 영상 흐름 채집:https://gitee.com/sanjiankethree/cubic-video
우아 한 정지
현재 Spring Boot 는 2.3.4.RELEASE 까지 발 전 했 고 2.3 버 전이 도래 함 에 따라 우아 한 정지 체제 도 더욱 완선 되 었 다.
현재 버 전의 Spring Boot 우아 한 정지 지원 Jetty,Reactor Netty,Tomcat,Undertow 및 반응 식 및 Servlet 기반 웹 프로그램 은 우아 한 정지 기능 을 지원 합 니 다.
우아 한 정지 의 목적:
우아 한 정지 가 없 으 면 서버 가 직접 닫 습 니 다(kill-9).그러면 현재 용기 에서 실행 중인 업무 가 직접 실패 하고 특정한 특수 한 장면 에서 더러 운 데 이 터 를 만 들 수 있 습 니 다.
우아 한 정지 설정 이 추 가 된 후:
서버 가 종료(kill-2)를 실행 할 때 용기 내부 업무 스 레 드 가 실 행 될 시간 을 조금 남 깁 니 다.이 때 용기 도 새로운 요청 이 들 어 갈 수 없습니다.새로운 요청 의 처리 방식 은 웹 서버 와 관련 이 있 으 며,Reactor Netty,Tomcat 은 접속 요청 을 중단 합 니 다.Undertow 의 처리 방식 은 503 으로 되 돌아 갑 니 다.
새 버 전 설정
YAML 설정
새 버 전 설정 은 매우 간단 합 니 다.server.shutdown=graceful 이면 됩 니 다.(주의,우아 한 정지 설정 은 Tomcat 9.0.33(포함)이상 버 전에 맞 춰 야 합 니 다.)
server:
 port: 6080
 shutdown: graceful #      
spring:
 lifecycle:
 timeout-per-shutdown-phase: 20s #         30s다음은 정지 할 때 우아 한 정지 로그 와 추가 하지 않 는 차 이 를 살 펴 보 겠 습 니 다.
//        
Disconnected from the target VM, address: '127.0.0.1:49754', transport: 'socket'
Process finished with exit code 130 (interrupted by signal 2: SIGINT) 
 닫 기 방식
1.kill-9 동작 을 사용 하지 말고 kill-2 를 사용 하여 용 기 를 닫 습 니 다.이렇게 해야만 자바 내부 Shutdown Hook 작업 을 촉발 할 수 있 습 니 다.kill-9 는 Shutdown Hook 을 촉발 하지 않 습 니 다.
2.터미널 모니터링 POST 요청/actuator/shutdown 을 사용 하여 우아 하 게 전원 을 끌 수 있 습 니 다.
ShutdownHook 추가
위의 로 그 를 통 해 우 리 는 Druid 가 자신의 Shutdown Hook 을 실행 한 것 을 발 견 했 습 니 다.그러면 우 리 는 Shutdown Hook 을 추가 합 니 다.몇 가지 간단 한 방법 이 있 습 니 다.
1.DisposableBean 인 터 페 이 스 를 실현 하고 destroy 방법 실현
@Slf4j
@Service
public class DefaultDataStore implements DisposableBean {
 private final ExecutorService executorService = new ThreadPoolExecutor(OSUtil.getAvailableProcessors(), OSUtil.getAvailableProcessors() + 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(200), new DefaultThreadFactory("UploadVideo"));
 @Override
 public void destroy() throws Exception {
 log.info("           DisposableBean");
 executorService.shutdown();
 }
}
@Slf4j
@Service
public class DefaultDataStore {
 private final ExecutorService executorService = new ThreadPoolExecutor(OSUtil.getAvailableProcessors(), OSUtil.getAvailableProcessors() + 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(200), new DefaultThreadFactory("UploadVideo"));
 @PreDestroy
 public void shutdown() {
 log.info("         @PreDestroy");
 executorService.shutdown();
 }
}폐쇄 원리
1、kill pid 를 사용 하여 닫 습 니 다.원본 코드 는 간단 합 니 다.GracefulShutdown 을 보 실 수 있 습 니 다.
	private void doShutdown(GracefulShutdownCallback callback) {
		List<Connector> connectors = getConnectors();
		connectors.forEach(this::close);
		try {
			for (Container host : this.tomcat.getEngine().findChildren()) {
				for (Container context : host.findChildren()) {
					while (isActive(context)) {
						if (this.aborted) {
							logger.info("Graceful shutdown aborted with one or more requests still active");
							callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE);
							return;
						}
						Thread.sleep(50);
					}
				}
			}
		}
		catch (InterruptedException ex) {
			Thread.currentThread().interrupt();
		}
		logger.info("Graceful shutdown complete");
		callback.shutdownComplete(GracefulShutdownResult.IDLE);
	}actuator 는 모두 SPI 의 확장 방식 을 사 용 했 기 때문에 AutoConfiguration 을 살 펴 보면 관건 은 Shutdown Endpoint 입 니 다.
@Configuration(
 proxyBeanMethods = false
)
@ConditionalOnAvailableEndpoint(
 endpoint = ShutdownEndpoint.class
)
public class ShutdownEndpointAutoConfiguration {
 public ShutdownEndpointAutoConfiguration() {
 }
 @Bean(
 destroyMethod = ""
 )
 @ConditionalOnMissingBean
 public ShutdownEndpoint shutdownEndpoint() {
 return new ShutdownEndpoint();
 }
}
@Endpoint(
 id = "shutdown",
 enableByDefault = false
)
public class ShutdownEndpoint implements ApplicationContextAware {
 
 @WriteOperation
 public Map<String, String> shutdown() {
 if (this.context == null) {
  return NO_CONTEXT_MESSAGE;
 } else {
  boolean var6 = false;
  Map var1;
  try {
  var6 = true;
  var1 = SHUTDOWN_MESSAGE;
  var6 = false;
  } finally {
  if (var6) {
   Thread thread = new Thread(this::performShutdown);
   thread.setContextClassLoader(this.getClass().getClassLoader());
   thread.start();
  }
  }
  Thread thread = new Thread(this::performShutdown);
  thread.setContextClassLoader(this.getClass().getClassLoader());
  thread.start();
  return var1;
 }
 }
 
 private void performShutdown() {
 try {
  Thread.sleep(500L);
 } catch (InterruptedException var2) {
  Thread.currentThread().interrupt();
 }
 this.context.close(); //      
 }
}
/**
	 * Close this application context, destroying all beans in its bean factory.
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
	 * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
	 * @see #doClose()
	 * @see #registerShutdownHook()
	 */
	@Override
	public void close() {
		synchronized (this.startupShutdownMonitor) {
			doClose(); //  :  bean    jvm shutdown hook
			// If we registered a JVM shutdown hook, we don't need it anymore now:
			// We've already explicitly closed the context.
			if (this.shutdownHook != null) {
				try {
					Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
				}
				catch (IllegalStateException ex) {
					// ignore - VM is already shutting down
				}
			}
		}
	}여기까지
  버 전의 Spring Boot 우아 정지 에 대해 서 는 말 이 끝났다.왜  라 고 했 어 요?닫 을 때 서버 내부 스 레 드 의 실행 이 완료 되 었 을 뿐 호출 자의 상 태 는 관심 이 없다 는 것 을 알 수 있 기 때문이다.Dubbo 든 Cloud 의 분포 식 서비스 프레임 워 크 든 서비스 가 중단 되 기 전에 공급 자 를 등록 센터 에서 반 등록 한 다음 에 서비스 제공 자 를 정지 시 켜 야 업무 시스템 이 각종 503,timeout 등 현상 이 발생 하지 않도록 확보 할 수 있다.
다행히 현재 Spring Boot 는 Kubernetes 와 결합 하여 이 점 을 해결 해 주 었 습 니 다.즉,Spring Boot 2.3 버 전의 새로운 기능 인 Liveness(생존 상태)와 Readiness(준비 상태)입 니 다.
간단하게 이 두 상 태 를 제시 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.