반응형
문제상황
- 테스트해볼 환경이 있어 POC 중에 AWS EC2 프론트엔드 프로젝트 빌드 시 EC2가 멈춰버리는 현상이 지속 발생했다.
- AWS EC2 프리티어를 사용하면 t2.micro의 사양의 RAM이 1GB이기 때문에 빌드 규모가 조금만 커져도 멈춰버린다.
해결 방법 1
- 로컬에서 빌드후 빌드 소스코드를 깃허브에 올린 후 받는다. 또는 FTP로 빌드파일을 전송..
해결 방법 2
- 구글링을 통해 메모리 스왑으로 해결할수 있는 방법을 찾았다. 이 방법으로 해결은 했으나 명령어만 사용하였고 자세한 내용은 알지 못해서 추가로 찾아보았다.
- EC2에서 메모리 스왑은 리소스가 부족할 때, 물리적인 RAM이 부족하면 디스크를 메모리처럼 사용할 수 있는 방식이다.
- AWS 우분투 프리티어 기준으로 설명하겠다.
- 이 방법은 임시방편일 뿐, 맘 편하게 프리티어 말고 사양을 올리는 것을 추천한다.
1. 현재 swap 공간 확인
- 현재 스왑 메모리가 설정되어 있는지 확인 (아무런 출력이 없으면 스왑 메모리가 설정되어있지 않은 것)
$ sudo swapon --show
2. 전체 메모리 상태 확인
$ free -h
3. 아래 명령어를 순차적으로 입력한다.
$ sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048
$ sudo mkswap /mnt/swapfile
$ sudo swapon /mnt/swapfile
이 명령어들을 차례대로 보자면 (스왑파일 생성, 스왑 파일 초기화, 스왑파일 활성화 순이다)
- sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048
- dd : 파일 복사 및 변환을 수행하는 명령어
- if=/dev/zero : 입력 파일(input file)로 /dev/zero를 사용하겠다. /dev/zero는 무한히 0으로 채워진 가상장치로 여기서 생성된 파일은 0으로 채워진다.
- of=/mnt/swapfile : 출력파일(output file)로 /mnt/swapfile을 생성한다.
- bs=1M : 블록 크기를 1M로 설정함, 데이터가 1MB씩 읽고 쓰여질 것이라는 의미이다.
- count=2048 : 총 2048개의 블록을 생성한다는 의미이다. 1MB의 블록이 2048개 이므로 2GB의 스왑파일이 생성된다.
- 요약하자면 2GB 크기의 파일(/mnt/swapfile)을 0으로 채워 생성한다.
- sudo mkswap /mnt/swapfile
- mkswap: 지정된 파일 또는 파티션을 스왑 공간으로 초기화하는 명령어이다.
- /mnt/swapfile: 스왑 공간으로 사용할 파일이다. 위에서 생성한 출력파일
- 요약하자면, /mnt/swapfile을 스왑 메모리로 초기화한다. 즉, 이 파일이 스왑 영역으로 사용될 수 있도록 준비한다.
- sudo swapon /mnt/swapfile
- swapon: 스왑 파일이나 스왑 파티션을 활성화하는 명령어이다.
- /mnt/swapfile: 활성화할 스왑 파일이다.
여기서 드는 궁금증은 if=/dev/zero, of=/mnt/swapfile 처럼 입/출력 파일을 왜 만드는 것일까?
궁금해서 찾아보았는데, 위에서 말했듯이 스왑 파일은 시스템 메모리(RAM)가 부족할 때 디스크의 일부를 가상 메모리 처럼 사용하여 시스템이 정상적으로 동작할 수 있도록 해주는 것이다. 메모리가 부족할때 안전망 역할을 해준다.
따라서 if=/dev/zero, of=/mnt/swapfile 이와 같은 스왑파일을 만드는 이유는 0으로 가득 찬 스왑파일을 생성하여, 물리적인 메모리(RAM)가 부족할 경우 운영체제가 이 파일(디스크의 일부)를 메모리처럼 사용한다는 것으로 이해하였다.
이렇게 입력하면 해결은 되지만 빌드 타임이 굉장히 느리고, 위에서 말했듯 프리티어환경에서 어쩔 수 없이 빌드하기 위함이었다. 그래서 임시방편으로 사용하는 것이 좋다.
4. swap 메모리 해제 방법
- 위에서 설정한 swap 메모리를 해제하는 방법이다.
$ sudo swapoff -v /mnt/swapfile
$ sudo rm /mnt/swapfile
- sudo swapoff -v /mnt/swapfile
- swapoff: 현재 활성화된 스왑 영역을 비활성화하는 명령어이다. 이 명령어를 사용하면 더 이상 해당 스왑파일을 사용하지 않는다.
- -v: verbose 모드로 실행하여, 스왑이 비활성화되는 과정을 출력한다. 스왑이 제대로 비활성화되었는지 확인하기 위함
- /mnt/swapfile: 비활성화할 스왑 파일, /mnt/swapfile이 스왑 파일로 사용되었으므로, 이 파일을 비활성화합니다.
- sudo rm /mnt/swapfile
- rm: 파일을 삭제하는 명령어.
- /mnt/swapfile: 삭제할 파일의 경로, 여기서는 스왑으로 사용되었던 /mnt/swapfile을 삭제
해결 방법 3
- package.json 의 build 스크립트에 GENERATE_SOURCEMAP=false를 추가해 준다.
"scripts": {
"build": "GENERATE_SOURCEMAP=false react-scripts build"
}
- GENERATE_SOURCEMAP=false는 소스맵(Source Map) 생성을 비활성화하는 옵션이다.
- 주로 React나 Create-react-app과 같은 자바스크립트 기반 애플리케이션 빌드 환경에서 사용된다.
소스맵 (SourceMap)?
소스맵은 번들, 빌드된 코드와 원본코드(개발 중에 작성한 코드)의 매핑 정보를 제공하는 파일이다. 개발자가 디버깅할 때, 번들된 코드 대신 원본 코드를 보고 디버깅할 수 있게 해 준다.
GENERATE_SOURCEMAP=false의 역할
- 기본적으로 소스맵은 생성됨 (default는 true)
- create-react-app 같은 도구는 프로덕션 빌드를 할 때도 기본적으로 소스맵을 생성한다. 이는 디버깅에 유용하지만, 실제 프로덕션 환경에서는 소스맵을 제공하는 것은 보안상 위험이 될 수 있다
- 이 소스맵을 통해 소스 코드의 원본이 노출될 가능성이 있기 때문이다.
- false로 설정: GENERATE_SOURCEMAP=false로 설정하면 번들된 파일에 대한 원본 코드가 노출되지 않게 하고, 배포되는 파일의 크기도 줄일 수 있다.
여기서 의문점은 현재는 빌드 때문에 이 방법을 찾았는데 소스맵을 false로 설정하는 게 무조건 좋을까?
이는 개발 환경과 배포 전략에 따라 나뉘는 것 같다. 개발환경에선 유용하지만, 프로덕션 환경에서 디버깅이 필요한 경우에는 원본 코드를 기준으로 오류를 빠르게 찾아 해결할 수는 있지만, 보안적인 측면에 따라 서버에는 업로드하지 않는 방식으로 할 수도 있을 것 같다.
또한 별도의 모니터링 및 디버깅 및 오류 추적 설정이 되어있다면, 빌드 타임도 줄이고 불필요한 자원낭비를 없앨 수 있을 것이다.
결론
- POC용도나 사이드프로젝트 용도로 EC2 프리티어를 어쩔 수 없이 사용할 때는 위 방법을 추천해 준다.
- 나는 2번으로 해결하였지만 그래도 빌드 시간은 매우 길다(5분~10분)
- 웬만하면 사양을 올려서 쓰는 것을 추천한다.
참고 자료
반응형
'개발 > 오류기록' 카테고리의 다른 글
Jenkins Pipeline 중 Docker Command not found (2) | 2024.10.02 |
---|---|
React-activate 사용 중 'decorators-legacy' 오류 (0) | 2022.12.08 |
[Next.js] CORS 오류 해결방법, Next proxy 설정 (0) | 2022.11.30 |
[오류 기록] tomcat startup.sh 바로 꺼짐 문제 (0) | 2022.10.02 |
댓글