새로 스프링 배치 프로그램을 만들었는데, 테스트 환경에서는 특별히 이슈가 없다가 운영 환경에서 오류가 발생했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
2018-05-21 16:00:43.044 INFO 5372 --- [main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-05-21 16:00:43.099 ERROR 5372 --- [main] o.apache.catalina.core.StandardService : Failed to start connector [Connector[HTTP/1.1-8080]] org.apache.catalina.LifecycleException: Failed to start component [Connector[HTTP/1.1-8080]] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) ~[tomcat-embed-core-8.5.29.jar!/:8.5.29] at org.apache.catalina.core.StandardService.addConnector(StandardService.java:225) ~[tomcat-embed-core-8.5.29.jar!/:8.5.29] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:256) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:198) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.startWebServer(ServletWebServerApplicationContext.java:300) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553) [spring-context-5.0.5.RELEASE.jar!/:5.0.5.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at kr.co.freeism.batch.FreeismBatchApplication.main(FreeismBatchApplication.java:9) [classes!/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [voyager-batch-0.0.1-SNAPSHOT.jar:na] at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [voyager-batch-0.0.1-SNAPSHOT.jar:na] at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [voyager-batch-0.0.1-SNAPSHOT.jar:na] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [voyager-batch-0.0.1-SNAPSHOT.jar:na] Caused by: org.apache.catalina.LifecycleException: Protocol handler start failed at org.apache.catalina.connector.Connector.startInternal(Connector.java:1020) ~[tomcat-embed-core-8.5.29.jar!/:8.5.29] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.5.29.jar!/:8.5.29] ... 21 common frames omitted Caused by: java.net.BindException: Address already in use at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_144] at sun.nio.ch.Net.bind(Net.java:433) ~[na:1.8.0_144] at sun.nio.ch.Net.bind(Net.java:425) ~[na:1.8.0_144] at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223) ~[na:1.8.0_144] at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) ~[na:1.8.0_144] at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:210) ~[tomcat-embed-core-8.5.29.jar!/:8.5.29] 2018-05-21 16:00:43.136 ERROR 5372 --- [main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured. Action: Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port. |
결국은 8080 포트가 충돌나서 오류가 발생한 것이었다.
배치를 여러 번 실행시키는 경우 톰캣이 제대로 shutdown시키지 못해서 발생하는 문제였다.
그런데 스프링 배치인데, 굳이 톰캣을 8080 포트로 실행해야 할 이유가 있을까?
찾아보니 스프링 배치에서는 기본적으로 톰캣을 8080 포트로 로딩하고, 배치 모니터링을 제공한다.
(사실 엄밀히 따지면 배치가 실행되는 동안만 톰캣이 유효하도록 되어 있어서, 내 경우에는 별로 의미가 없는 모니터링이었다)
그래서 찾아봤더니, 아래처럼 설정을 하면 톰캣을 실행시키지 않는다고 한다.
1 2 |
main: web-environment: false |
앗, 그런데 deprecate되었다고 warning이 발생한다.
해당 설정을 하는 곳을 찾아봤더니,
1 2 3 4 5 6 7 8 9 10 11 |
/** * Sets if this application is running within a web environment. If not specified will * attempt to deduce the environment based on the classpath. * @param webEnvironment if the application is running in a web environment * @deprecated since 2.0.0 in favor of * {@link #setWebApplicationType(WebApplicationType)} */ @Deprecated public void setWebEnvironment(boolean webEnvironment) { this.webApplicationType = webEnvironment ? WebApplicationType.SERVLET : WebApplicationType.NONE; } |
위 옵션으로 서블릿을 실행할 것인지 아닌지 처리하는 설정이고, 2.0 버전부터 deprecate되었다고 친절하게 적어놨다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/** * Sets the type of web application to be run. If not explicitly set the type of web * application will be deduced based on the classpath. * @param webApplicationType the web application type * @since 2.0.0 */ public void setWebApplicationType(WebApplicationType webApplicationType) { Assert.notNull(webApplicationType, "WebApplicationType must not be null"); this.webApplicationType = webApplicationType; } /** * An enumeration of possible types of web application. * * @author Andy Wilkinson * @author Brian Clozel * @since 2.0.0 */ public enum WebApplicationType { /** * The application should not run as a web application and should not start an * embedded web server. */ NONE, /** * The application should run as a servlet-based web application and should start an * embedded servlet web server. */ SERVLET, /** * The application should run as a reactive web application and should start an * embedded reactive web server. */ REACTIVE } |
SpringBoot 2.0 부터는 아래처럼 WebApplicationType을 통해서 설정이 가능하다고 한다.
결국 application.yml
에 아래처럼 설정하면 된다.
1 2 |
main: web-application-type: none |
훌륭
도움이 되셨다니 감사합니다 🙂