22.05.30 항해99 6기 지원주차 1일차 TIL

유현준·2022년 6월 6일
0

진행한 일

  • 이력서 1차 작성 완료
  • 알림/문자전송 스케줄러 AWS lambda 적용 진행

트러블 슈팅

1) 알림 스케줄러를 AWS EC2가 아닌 AWS Lambda로 구현하기

  • AWS lambda에 AWS Cloud watch event 트리거를 설정해서 매 1분마다 특정 로직을 실행하는 것은 구현했다.
  • 하지만, 문제는 DB 연결에 있었다. 여러 이유로 인해 다음과 같은 에러가 떴다.
(1)
ERROR   Unhandled Promise Rejection    {
    "errorType": "Runtime.UnhandledPromiseRejection",
    "errorMessage": "Error: SequelizeConnectionError: Got timeout reading communication packets",
    "reason": {
        "errorType": "Error",
        "errorMessage": "SequelizeConnectionError: Got timeout reading communication packets",
        "stack": [
            "Error: SequelizeConnectionError: Got timeout reading communication packets",
            "    at /var/task/alarm.service.js:208:23",
            "    at processTicksAndRejections (node:internal/process/task_queues:96:5)",
            "    at async Object.createStartAlarm (/var/task/alarm.service.js:116:9)"
        ]
    },
    "promise": {},
    "stack": [
        "Runtime.UnhandledPromiseRejection: Error: SequelizeConnectionError: Got timeout reading communication packets",
        "    at process.<anonymous> (file:///var/runtime/index.mjs:775:15)",
        "    at process.emit (node:events:520:28)",
        "    at emit (node:internal/process/promises:133:20)",
        "    at processPromiseRejections (node:internal/process/promises:260:27)",
        "    at processTicksAndRejections (node:internal/process/task_queues:97:32)"
    ]
}

혹은
(2)
connect ETIMEDOUT ERROR
가 발생했다.

결국 DB와 연결이 제대로 되지 못하거나, 통신이 제대로 되지 않는 이슈가 계속 발생했던 것이다.
이는 다음과 같은 방법으로 해결해보려고 노력했다.

1) lambda의 VPC를 connect 에러가 뜨는 RDS의 VPC와 동일하게 세팅한다.
2) lambda의 메모리를 128mb에서 1024mb로 높인다.

다행히도 위 두가지를 람다에 도입햇더니, DB로 인한 연결 오류 발생률이 줄어들었다. 그럼에도 불구하고, 10번에 1번, 20번에 1번꼴로 DB 연결 에러가 여전히 발생하기는 했다.

또한, DB에서 (1)과 같은 에러는 코드에 변경사항이 있어서, 함수 코드를 변경했을 때에는 반드시 일어났다. 신기하게도 (1) 에러는 코드에 변경사항이 있을 시, 기존의 함수에서 변경사항을 업데이트 하는 것이 아니라, 함수 자체를 삭제 시킨 뒤 변경사항을 새로운 함수에 업로드하면 종종 발생하지 않았다. 즉, 코드에 변경사항이 있을 때마다 함수를 다시 생성해주면 (1) 에러는 간혹 발생하지 않았던 것이다.

위 에러들은 계속 삽질하면서 꼭 해결하고 싶었지만, 이력서 작성과 취업 준비를 병행하고 있는 상황이었기 때문에, 완벽하게 핸들링하지는 못했다. 주변에게 좀 더 수소문을 해보고, 더 구글링을 하면서 빠른 시일 내에 해결해보고자 한다.

한편, 위 에러들 때문에 정확한 의사결정은 아니겠지만, 실전 프로젝트 진행 당시에 AWS Lambda가 아니라 AWS EC2에 알림 스케줄러를 구축한 것이 옳은 결정이었다는 근거를 몇 가지 찾을 수 있었다.

  • 첫째는 과금이다. Lambda는 로직을 실행한 ms 단위로 과금이 발생한다. 물론 무료인 ms 구간이 생각보다 넓기는 하지만 작은 규모의 서비스라도 "운영"하면 과금이 쉽게 발생할 수 있는 과금표라고 생각이 들었다.

  • 둘째는 DB 연결의 어려움이다. AWS 공식 홈페이지에서 또한 이에 대해 명시하고 있다.(https://aws.amazon.com/ko/premiumsupport/knowledge-center/lambda-rds-connection-timeouts/)
    Lambda를 통해 DB를 엑세스 하는 과정에 TIMEOUT 에러가 종종 발생할 수 있다고 말이다. 실제로 AWS EC2, 로컬 등 다른 환경에서는 원활하게 작동하는 DB 관련 소스코드가 Lambda에서만 유독 연결 에러가 빈번하게 발생했다. 심지어는 한동안 잘 연결되어 로직이 실행되다가도, 갑자기 불규칙적으로 연결 에러가 발생하기도 했다.

  • 셋째는 트리거에 따른 로직 실행의 불규칙성이다. 이 이유는 내가 트리거를 잘 활용하지 못했기 때문에 오해한 것일수도 있다고 생각하지만, 필자는 분명 1분에 한번씩 로직을 실행시키는 트리거를 실행했음에도 불구하고, 로그를 확인해보니, 1분 안에서 로직을 2~3번 실행한 것을 확인할 수 있었다. 필자는 02:00:00, 02:01:00, 02:02:00과 같이 규칙적으로 로직이 실행될 것을 희망했지만, 로직은 생각과 달리, 02:00:02, 02:00:12, 02:01:03, 02:02:15와 같이 불규칙한 단위로 실행되었다. 다음은 그 예시 로그와 db 데이터 사진이다.

2022-06-07T02:03:38.408+09:00	2022-06-06T17:03:38.390Z ce09651b-742e-4519-9362-1cdd99d102d8 INFO Executing (default): SELECT `Groups`.`userId`, `Groups`.`title`, `Groups`.`groupId`, `Appliers`.`applyId` AS `Appliers.applyId`, `Appliers`.`groupId` AS `Appliers.groupId`, `Appliers`.`userId` AS `Appliers.userId` FROM `Groups` AS `Groups` LEFT OUTER JOIN `Appliers` AS `Appliers` ON `Groups`.`groupId` = `Appliers`.`groupId` WHERE (`Groups`.`date` = '2022-06-07' AND `Groups`.`standbyTime` = '02:33:00');

2022-06-07T02:03:38.409+09:00	2022-06-06T17:03:38.408Z ce09651b-742e-4519-9362-1cdd99d102d8 INFO Executing (default): SELECT `Groups`.`userId`, `Groups`.`title`, `Groups`.`groupId`, `Appliers`.`applyId` AS `Appliers.applyId`, `Appliers`.`groupId` AS `Appliers.groupId`, `Appliers`.`userId` AS `Appliers.userId` FROM `Groups` AS `Groups` LEFT OUTER JOIN `Appliers` AS `Appliers` ON `Groups`.`groupId` = `Appliers`.`groupId` WHERE (`Groups`.`date` = '2022-06-07' AND `Groups`.`standbyTime` = '01:03:00');

2022-06-07T02:03:38.410+09:00	END RequestId: ce09651b-742e-4519-9362-1cdd99d102d8

2022-06-07T02:03:38.410+09:00	REPORT RequestId: ce09651b-742e-4519-9362-1cdd99d102d8 Duration: 28.47 ms Billed Duration: 29 ms Memory Size: 128 MB Max Memory Used: 53 MB

2022-06-07T02:03:40.256+09:00	START RequestId: 4b9fda86-128b-4354-b1f7-c6188e5ad54e Version: $LATEST

2022-06-07T02:03:40.257+09:00	2022-06-06T17:03:40.257Z ce09651b-742e-4519-9362-1cdd99d102d8 INFO startAlarm 1.876

2022-06-07T02:03:40.257+09:00	2022-06-06T17:03:40.257Z ce09651b-742e-4519-9362-1cdd99d102d8 INFO 보낼 시작 알람이 없습니다

2022-06-07T02:03:40.258+09:00	2022-06-06T17:03:40.258Z ce09651b-742e-4519-9362-1cdd99d102d8 INFO endAlarm 1.877

2022-06-07T02:03:40.258+09:00	2022-06-06T17:03:40.258Z ce09651b-742e-4519-9362-1cdd99d102d8 INFO 보낼 종료 알람이 없습니다

2022-06-07T02:03:40.268+09:00	2022-06-06T17:03:40.268Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO Moment<2022-06-07T02:03:40+09:00>

2022-06-07T02:03:40.271+09:00	2022-06-06T17:03:40.271Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO Executing (default): SELECT `Groups`.`userId`, `Groups`.`title`, `Groups`.`groupId`, `Appliers`.`applyId` AS `Appliers.applyId`, `Appliers`.`groupId` AS `Appliers.groupId`, `Appliers`.`userId` AS `Appliers.userId` FROM `Groups` AS `Groups` LEFT OUTER JOIN `Appliers` AS `Appliers` ON `Groups`.`groupId` = `Appliers`.`groupId` WHERE (`Groups`.`date` = '2022-06-07' AND `Groups`.`standbyTime` = '02:33:00');

2022-06-07T02:03:40.288+09:00	2022-06-06T17:03:40.271Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO Executing (default): SELECT `Groups`.`userId`, `Groups`.`title`, `Groups`.`groupId`, `Appliers`.`applyId` AS `Appliers.applyId`, `Appliers`.`groupId` AS `Appliers.groupId`, `Appliers`.`userId` AS `Appliers.userId` FROM `Groups` AS `Groups` LEFT OUTER JOIN `Appliers` AS `Appliers` ON `Groups`.`groupId` = `Appliers`.`groupId` WHERE (`Groups`.`date` = '2022-06-07' AND `Groups`.`standbyTime` = '01:03:00');

2022-06-07T02:03:40.289+09:00	END RequestId: 4b9fda86-128b-4354-b1f7-c6188e5ad54e

2022-06-07T02:03:40.289+09:00	REPORT RequestId: 4b9fda86-128b-4354-b1f7-c6188e5ad54e Duration: 29.88 ms Billed Duration: 30 ms Memory Size: 128 MB Max Memory Used: 53 MB

2022-06-07T02:03:41.020+09:00	START RequestId: fd63ed52-201a-4567-829f-6ebc6118dbaf Version: $LATEST

2022-06-07T02:03:41.020+09:00	2022-06-06T17:03:41.020Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO startAlarm 0.752

2022-06-07T02:03:41.020+09:00	2022-06-06T17:03:41.020Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO 보낼 시작 알람이 없습니다

2022-06-07T02:03:41.021+09:00	2022-06-06T17:03:41.021Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO endAlarm 0.752

2022-06-07T02:03:41.021+09:00	2022-06-06T17:03:41.021Z 4b9fda86-128b-4354-b1f7-c6188e5ad54e INFO 보낼 종료 알람이 없습니다

반면, AWS EC2에 구축한 알림 스케줄러의 경우, 로직 실행이 매우 규칙적으로 진행되고 있으며, DB 연결 또한 현재까지 아무런 문제 없이 유지 되고 있다. 이에, 실전프로젝트 당시에 AWS EC2에 알림 스케줄러를 구축한 것이 정말 다행이었다는 생각이 들었다.

그럼에도 불구하고, 최근 서버리스한 개발이 중요하게 간주되고 있는만큼, 람다를 더 알아가고 싶고, 더 잘 활용하고 싶은 마음이 크다. 빠른 시일 내에 이 문제도 좀 더 연구해보도록 하고 싶다. 관건은 RDS 연결트리거 규칙 안정화이다.

내일 할일

  • 이력서 수정 및 자소서 작성하기
  • CD 구현
profile
차가운에스프레소의 개발블로그입니다. (22.03. ~ 22.12.)

0개의 댓글

관련 채용 정보