4/2 전까지

지난주 주말에 EB 적용하고 AWS SNS, Lambda 학습해서 Slack으로 알람 연동을 하려 했으나, 몸이 너무 안좋아서 그냥 잠만잤다..
월요일은 아이엠웹으로 만들어진 회사 홈페이지 js코드 작업을 도와주고 Google Crushlytics와 회사 Slack 연동작업을 했다.

스크린샷 2019-04-03 오전 3.42.45.png

회사 초기에 안드로이드 앱 깨지는 현상때문에 애를 많이 먹었고, 실제 배포된 상황에서 약 10여건정도 깨지는 현상을 play console에서 확인했었다.
실시간으로 체크하는게 힘들고, 또 세부사항을 알 수 없어서 직감과 노가다로 버그를 잡았었는데, Crushlytics를 이용해서 이전보다 훨씬 효율적으로 버그들을 잡을 수 있을 것 같다.

월요일 작업은 금방 끝나서 따로 블로깅하진 않았다.

Elastic Beanstalk 적용

적용기

EB 코드 배포는 두가지 방법이 있다.

  1. 프로젝트 디렉토리를 zip으로 묶어 aws console을 통한 배포
  2. AWS EB CLI와 .elasticbeanstalk 옵션 파일을 이용한 배포

콘솔에 매번 들어가서 zip파일을 올리는 수고를 덜기 위해 CLI를 통해 서버코드를 배포하고자 했다.
역시나 CLI로 작업을 하면 매번 불안불안하고 추가적인 셋팅하는데 오랜시간 잡아먹어왔는데, 이번도 역시 마찬가지로 단순 코드배포하는데 하루종일 걸렸다.

배포를 하며 어려웠던 점이

  • babel-node를 활용한 배포 불가능 및 성능이슈
  • EB 옵션 파일과 명령어 정보가 부족하여 초기 프로젝트 배포는 CLI로 하고 세부환경 설정을 콘솔에서 했던 점
  • https 도메인 설정
  • Nginx 프록시

이 네가지 였다.

https 도메인은 ACM와 Route 53을 이용해 해결했으나, 첫번째 이슈를 해결하지 못한채 넘어갔다.

이전까지 서버코드에 ES7 import export 구문과 babel root-import를 사용했기 때문에 babel 컴파일 작업이 필요했다.
때문에, 컴파일 작업을 거친 파일을 실행하지 않고 package.json 스크립트에 babel-node를 활용하는 방식으로 여태까지 사용해왔다.
그러나, 이 방식으로 EB에 배포를 하려고 하면 인스턴스에 babel cli 설치작업이 필요할 뿐만 아니라 성능상으로도 좋지 않다고 한다.
(참조: https://stackoverflow.com/a/32929589/10743079)

때문에 배포전에 미리 컴파일을 한 파일들을 올려 실행하려고 했으나, EB 인스턴스 업데이트시 @babel/polyfill를 계속 읽어오지 못해 성능이슈와 함께 해결하고자 코드를 다시 고쳐서 배포했다.

이번주 금요일에 별일 없으면 서버코드를 다시 수정하는 작업을 거칠껀데, 이때 해결방안을 다시 한번 찾아봐야겠다.

스트레스 테스트

대표님께서 목요일 부터 우리 앱을 홍보할 것이라고 말씀하셨다.
때문에, 우리 서버가 얼마나 버틸 수 있는지 어느정도 감을 잡아보면서 동시에 오토 스케일링 테스트를 위해 스트레스 테스트를 할 필요성을 느꼈다.

스트레스 테스트 도구들은 많으나, 할 줄 아는게 자바스크립트 뿐인 나를 위해 자바스크립트 친화적인 도구를 찾다가 artillery 라는 도구를 활용하여 테스트를 했다.

artillery의 특징으로

  1. 시나리오 작성이 가능하다.
  2. 외부 모니터링 시스템과 연동이 가능하다 (ex. datadog, lnflux)
  3. 자바스크립트 로직 추가가 가능하다.
  4. 그래프를 활용한 테스트 결과 보고서 제공

등 여러 특징이 있다.

테스트에 앞서 우리가 앱에서 유저가 사용하는 시나리오를 짜고, 예상 사용자 및 사용시간을 예상하여 테스트 코드를 작성했다.

매일 2분짜리 영상을 15회 반복해서 학습해야 하기 때문에 약 30분정도 사용자가 어플을 사용할 것이며, 하루 평균 사용자 15명에 이후 신규로 유입되는 고객들이 20 ~ 30여명이 될 것이라고 판단하여

30분간 매초 50개의 request로 측정해보기로 했다.

test.json

{
  "config": {
    "target": "<url>",
    "phases": [
      {
        "duration": 60, 
        "arrivalRate": 5
      },
      {
        "duration": 180, 
        "arrivalRate": 5,
        "rampTo": 10
      },
      {
        "duration": 600, 
        "arrivalRate": 15
      },
      {
        "duration": 1800, 
        "arrivalRate": 50
      }

    ],
    "payload": {
      "path": "./data.csv",
      "fields": ["email", "pw","videoid"]
    },
    "defaults": {
      "headers": {
        "token": "<value>"
      }
    },
    "publish-metrics": { 
      "type": "datadog",
      "apiKey": "<apikey>",
      "prefix": "artillery.",
      "tags": {
        "test": "aws-eb"
      }, 
      "event": {
        "tags":
          {"test": "aws-eb"}
        }
      }
  },
  "scenarios": [
    {
      "name": "action:user-login",
      "flow": [
        {
          "post": {
            "url": "<login-path>",
            "json": {
              "email": "{{email}}",
              "pw": "{{pw}}"
            }
          }
        },
        {
          "get": {
            "url": "<path>"
          }
        }
      ]
    },
    {
      "name": "action:play-main-contents",
      "flow": [
        {
          "get": {
            "url": "<path>"
          }
        }
      ]
    },
    {
      "name":"action:search-contents",
      "flow": [
        {
          "get": {
            "url": "<path>"
          }
        },
        {
          "get": {
            "url": "<path>"
          }
        }
      ]
    }
  ]
}

사실 30분동안 매초 50개의 요청을 보내게되면 요청수가 꽤 많을것 같아 오토스케일링에 의해 인스턴스가 추가되지 않을까 라고 예상했지만, CPU크레딧은 거의 사용하지 않고 잘 버텨냈다.

스크린샷 2019-04-03 오전 4.41.14.png

스크린샷 2019-04-03 오전 4.42.50.png

이후에 계속 사용량을 주시하겠지만, 오토 스케일링도 달아놨기 때문에 한달여간은 서버가 터질일은 없을 것 같다.