반응형

스프링 프로젝트에서 Netty 프레임워크를 사용하여 'ServerBootstrap'을 구동하고 사용하였는데, 톰캣을 종료하면 자연스럽게 죽을줄 알았던 Netty 서버가 좀비처럼 계속 살아있는 현상이 발생했다.

 

덕분에 톰캣을 재기동하게 되면 같은 포트로 바인딩하면서 BindException이 발생하는 등 여러가지 문제가 생겼고, 대처법으로 netstat을 통해 port의 pid를 찾아와 kill을 시킬까 했지만, 애초에 종료를 안하는 원초적인 문제를 해결하는것이 맞다고 판단하여 아래와 같이 '@PreDestroy' 어노테이션을 추가하여, 스프링을 종료하게되면 ServerBootstrp을 종료 할 수 있도록 구성하였다.

 

Netty Server 안전하게 종료하기

Controller.java

private NettyServer server;

@PostConstruct
private void start() {
	new Thread(new Runnable() {
		
		@Override
		public void run() {
			try {
				server = new NettyServer(SERVER_PORT, service);
				server.run();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}).start();
}

/**
 * 바인딩된 NettyServer를 종료한다.
 * @throws InterruptedException
 */
@PreDestroy
private void destory() throws InterruptedException {
	logger.info("================ Spring @PreDestroy ================");
	server.serverDestroy();
}

 

NettyServer.java

private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private ChannelFuture future;

public void serverDestroy() throws InterruptedException {
	logger.info("================ Netty BootStrapServer Destroy() ================");
	bossGroup.shutdownGracefully().sync();
	workerGroup.shutdownGracefully().sync();
	future.channel().closeFuture().sync();
}

구동하면서 동작시킨 이벤트 그룹들을 shutdown시켜서 종료되도록 처리하였다.

 

 

반응형