현 서버는 로드밸런서로 구성되어 있으며 CI/CD 를 진행할때면 교차로 배포하고 슬랙으로 알림이 온다. 그리고 개인적으로 AWS에서 대상그룹으로 배포가 잘 되고 있는지 확인한다. 그런데 오늘 처음으로 장애가 발생했다. 배포 중 실패하여 대상그룹의 상태가 Request Error 가 발생한 것.
해서 서버의 로그를 보기 위해 접속했다. 보니 다음의 에러가 발생.
18-Nov-2020 17:48:53.002 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
18-Nov-2020 17:48:53.421 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
18-Nov-2020 17:48:53.436 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-8080]]
org.apache.catalina.LifecycleException: Protocol handler initialization failed
at org.apache.catalina.connector.Connector.initInternal(Connector.java:983)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:533)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1057)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.startup.Catalina.load(Catalina.java:584)
at org.apache.catalina.startup.Catalina.load(Catalina.java:607)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:304)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)
Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:230)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:213)
at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1124)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1137)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:575)
at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)
... 13 more
18-Nov-2020 17:48:53.437 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
18-Nov-2020 17:48:53.438 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[AJP/1.3-8009]]
org.apache.catalina.LifecycleException: Protocol handler initialization failed
at org.apache.catalina.connector.Connector.initInternal(Connector.java:983)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:533)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1057)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.startup.Catalina.load(Catalina.java:584)
at org.apache.catalina.startup.Catalina.load(Catalina.java:607)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:304)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)
Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:230)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:213)
at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1124)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1137)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:575)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)
... 13 more
알고보니 shutdown을 실행했음에도 톰캣이 정상종료되지 않아 프로세스를 유지하고 있었고, 해당 포트를 점령하고 있어서 벌어진 일이었다.
단일서버 배포할때야 별 문제가 되지 않겠지만 CI/CD를 구축한 만큼 덜컥 겁이 났다. 서비스가 단 1초라도 멈추면 안된다고 생각하기 때문에 어떻게 이것을 복구하며 다시 배포를 할 수 있을까 생각하다 다음처럼 수행했다.
1. 이전 서버의 문제점을 수정(여기서는 이전 서버가 종료되지 않은 문제.)
2. CodeDeploy로 들어가서 현재 배포중인 것을 정지.
3. 배포 재시도.
1번문제는 위에서 발견했기 때문에 자체적으로 해결했고(kill 했다)
2번은 AWS를 접속해야 했다.
CodeDeploy를 접속해보면 다음과 같은 목록이 뜨는데, 당시 캡쳐를 해두지 못했다. 그래도 일단 정지한 기록은 남아있다.
정지하는 방법은 왼쪽 라디오박스를 클릭해 선택 한 후, 위에 '동작 > 배포 중지'를 클릭하면 된다.
현재는 모두 정상이기 때문에 버튼이 활성화되지 않는다.
롤백을 할 거냐고 물어보는데 그렇다고 답했다.
중지를 한 이유는 이벤트를 보니 이미 배포 & 스크립트 실행 부분을 지났기 때문이다.
만약 배포중지를 하지 않을거라면 ApplicationStart 쪽에서 에러가 나서 대기중이어야 했다.
이로 말미암아 파악하건데 CodeDeploy는 주어진대로 수행만 할 뿐이지 특별한 에러감지를 할 수 없다. 로그를 보면 Traffic을 시도하다가 실패해서 배포가 실패한 것이지 진짜 원인인 Tomcat 구동 문제를 알려주진 않는다.
해서 처음부터 스크립트를 다시 수행하길 바랐기 때문에 배포중인걸 중단하고 재배포 했다.
시간이 지나 새로고침을 하면 상태가 '중지'로 변한다. 그럼 마지막에 시도했던 것을 선택(라디오박스 선택)하여 '배포 재시도' 버튼을 클릭한다.
클릭하고 나면 이전과 같이 자동으로 진행한다.
끝.
함께 보면 좋은 글:lemontia.tistory.com/948
'공부 > 프로그래밍' 카테고리의 다른 글
[webpack] Cannot read property 'tap' of undefined 에러 (0) | 2020.11.22 |
---|---|
[springboot] refresh_token 호출 시 에러날 때(Authorization Server) (0) | 2020.11.20 |
[springboot, slf4j] logging 파일분리 application.properties 에 설정하기(RollingFileAppender) (0) | 2020.11.16 |
[springboot, security] Authorization Server 실무에 써먹게 설정 (0) | 2020.11.15 |
[ajax, axios] Get호출 시 배열(list) 파라미터 전달하기 (1) | 2020.11.05 |
댓글