시작에 앞서
해당 내용은 <가장 빠른 풀스택을 위한 Flask & FastAPI>, Dave Lee 지음. BJ Public 출판.
내용을 토대로 작성되었습니다. 보다 자세한 사항은 해당 교재를 참고하시기 바랍니다.
플라스크 성능 개선
웹 애플리케이션의 성능을 개선하는 것은 사용자에게 더 빠르고 쾌적한 서비스를 제공하고, 서버 자원을 효율적으로 사용하기 위해 필수적이다.
데이터베이스 쿼리 최적화
적절하게 최적화된 쿼리는 데이터 검색 시간을 단축시켜 사용자 경험을 개선하고, 시스템 리소스의 효율적인 사용을 가능하게 한다. 데이터베이스 쿼리 최적화는 단순히 빠른 성능을 넘어서서 데이터베이스 서버의 부하를 줄이고 전체적인 애플리케이션의 안정성을 높이는 데도 기여한다.
- 선택적 데이터 로드: ORM(Object-Relational Mapping)을 사용하는 환경에서는 .all() 메서드를 사용하여 불필요하게 많은 데이터를 로드하는 것보다 .first()나 .limit()를 사용하여 필요한 데이터만 요청하는 것이 메모리 사용과 처리 시간을 절약
- N+1 쿼리 문제 해결: join, select_related, prefetch_related 와 같은 ORM 기능들을 적절히 활용함으로써 관련된 객체를 한 번의 데이터베이스 트랜잭션으로 불러와 N+1 쿼리 문제를 예방할 수 있다.
- 적절한 인덱스 설정: 데이터베이스에서 자주 조회되는 컬럼에 인덱스를 적용하는 것은 검색 속도를 극적으로 향상 시킬 수 있다. 인덱스는 데이터베이스가 테이블의 특정 컬럼에 빠르게 접근할 수 있도록 도와준다.
- 결과 캐싱: 자주 호출되는 쿼리의 결과를 메모리 내 캐시에 저장함으로써 반복적인 데이터베이스 호출을 줄일 수 있다.
※ N+1 쿼리 문제: N+1 문제는 ORM 기술에서 특정 객체를 대상으로 수행한 쿼리가 해당 객체가 가지고 있는 연관관계 또한 조회하게 되면서 N번의 추가적인 쿼리가 발생하는 문제
정적 파일 최적화 및 캐싱의 진화된 전략
정적 파일의 효과적인 관리는 웹 애플리케이션의 속도와 성능을 크게 향상시킬 수 있는 핵심 요소이다.
- 코드 최소화: CSS 및 자바스크립트 파일의 압축(minification)은 주석, 공백, 개행 문자 등 불필요한 문자를 제거하여 파일 크기를 최소화한다. 이는 네트워크 지연을 감소시키고, 페이지 로드 시간을 단축함으로써 전반적인 사용자 경험을 향상시킨다.
- 지능적 캐싱: CDN 서비스나 캐싱 프록시 서버를 이용하여 정적 파일을 전 세계에 분산시키고, 사용자에게 가장 가까운 위치에서 파일을 제공한다. HTTP 헤더를 통해 캐시를 세심하게 관리한다. (캐시 만료 기간, 변경 빈도 등 고려)
- 파일 버전 관리: 파일 이름에 버전 번호나 해시를 추가하여 캐시 무효화 문제를 해결한다. 새로운 버전의 애플리케이션을 배포할 때 클라이언트가 자동으로 최신 파일을 다운로드하도록 강제할 수 있다.
- 서버 측 최적화: Nginx나 아파치와 같은 웹 서버는 정적 파일을 처리하기 위한 다양한 설정 옵션을 제공한다. 이는 트래픽을 줄이고 로딩 시간을 단축시켜 서버의 성능을 극대화한다. (expires 헤더, gzip 등)
※ CDN 서비스: CDN(Content Delivery Network)은 지리적으로 분산된 서버들을 연결한 네트워크로서 웹 컨텐츠의 복사본을 사용자에 가까운 곳에 두거나 동적 컨텐츠(예: 라이브 비디오 피드)의 전달을 활성화하여 웹 성능 및 속도를 향상할 수 있게 한다.
로깅을 활용한 효과적인 디버깅
로깅을 통해 애플리케이션의 행동을 이해하고 문제가 발생했을 때 빠르게 원인을 찾아낼 수 있다.
※ 로깅: 애플리케이션에서 발생하는 이벤트를 시간 순서대로 기록하는 과정.
- 문제 해결: 로깅은 예외 발생 시 스택 추적을 기록하여 문제를 해결하는 데 도움을 준다. 예외가 발생한 정확한 코드 라인을 파악할 수 있어 디버깅 시간을 크게 단축할 수 있다
- 성능 모니터링: 로그를 통해 시스템의 성능 관련 메트릭을 수집할 수 있다. (예. 성능 지표- 응답 시간, 메모리 사용량 등 를 기록하여 성능 저하의 원인 분석)
- 안정성 향상: 정기적인 로그 분석을 통해 잠재적인 문제를 사전에 발견하고 시스템의 안정성을 향상 시킬 수 있다.
- 감사 및 컴플라이언스: 로깅은 감사 목적으로 중요하며, 때로는 법적 요구 사항을 충족시키는 데 필요할 수 있다.
- 로깅 레벨 설정; DEBUG, INFO, WARNING, ERROR, CRITICAL 등 다양한 로깅 레벨을 사용하여 메시지의 중요도에 따라 다른 처리를 할 수 있다.
- 로테이션과 보존: 로그 파일의 크기가 너무 커지는 것을 방지하기 위해 로그 로테이션을 구현할 수 있다.
- 중앙집중화: 대규모 시스템에서는 로그를 한곳에서 모니터링하고 분석할 수 있는 중앙집중화된 로깅 시스템을 구축하는 것이 유용하다
- 외부 서비스 활용: ELK(Elasticsearch, Logstash, Kibana) 스택이나 Splunk 같은 로깅 서비스를 사용하면 로그 데이터를 쉽게 수집, 검색, 분석하고 시각화할 수 있다.
※ 로그 로테이션(로그 로테이트, log rotate): 로그 정보가 계속 쌓이면 파일 용량 문제로 시스템에 문제가 생길 수 있으므로 사전에 저장 기간 및 저장 방법 설정하여 원활한 서버 관리, 운영을 하기 위해 설정하는 리눅스 기능.
※ ELK 스택: 사용자에게 모든 시스템과 애플리케이션에서 로그를 집계하고 이를 분석하며 애플리케이션과 인프라 모니터링 시각화를 생성하고, 빠르게 문제를 해결하며 보안 분석할 수 있는 능력을 제공
※ Splunk: 대용량 로그 수집 및 분석 시스템으로, 기업이 컴퓨터와 네트워크 장비에서 생성된 로그를 수집하여 필요한 정보를 추출할 수 있게 한다.
[로깅 관련 글]
고도화된 코드 최적화 기법
- 성능 측정: 플라스크 애플리케이션의 각 기능과 요청 처리 시간을 면밀히 분석하여 성능 저하를 초래하는 코드를 정확히 식별한다. (프로파일링 과정을 통해 수행) 병목 혀상이나 불필요한 자원 사용을 드러내는 데 큰 도움이 된다.
- 작업 분산: 계산 집약적이거나 시간 소모적인 작업들을 메인 애플리케이션 스레드로부터 분리하여 백그라운드에서 실행한다. 메인 스레드가 요청 처리에 집중할 수 있도록 해 사용자에게 빠른 응답 시간을 제공한다. (Celery와 같은 비동기 작업 큐를 사용하여 수행)
- 동시성 증가: 멀티 프로세싱과 스레딩을 활용하여 플라스크 애플리케이션을 복수의 작업 단위로 나누어 동시에 실행한다. Gunicorn과 같은 WSGI HTTP 서버를 활용하면, 여러 프로세스 및 스레드에서 애플리케이션을 구동시켜 단일 서버에서도 많은 요청을 효과적으로 처리할 수 있다.
※ 스레드: 애플리케이션 스레드는 컴퓨터 프로그램에서 동작하는 실행 단위를 말한다. 각 스레드는 프로그램 내에서 독립적으로 실행될 수 있으며, 서로 다른 작업을 동시에 처리할 수 있다. 예를 들어, 웹 브라우저에서 여러 개의 탭을 열 때 각 탭은 별도의 스레드에서 동작하여 동시에 여러 웹페이지를 로드하거나 데이터를 다운로드할 수 있다.
스레드를 잘 활용하면 프로그램의 성능을 향상시킬 수 있지만, 스레드 간의 자원 공유와 동기화 문제에 주의해야 한다. 이러한 문제들은 프로그래밍 언어나 개발 환경의 도움을 받아 해결할 수 있다.
애플리케이션 개발자는 다중 스레드를 사용하여 사용자 경험을 개선하거나 작업 처리 속도를 높이는 등의 목적으로 활용할 수 있다.
'[파이썬 Projects] > <파이썬 웹개발>' 카테고리의 다른 글
[파이썬] 플라스크(Flask) - 플라스크 프로젝트 - 메모앱(2) (0) | 2024.07.25 |
---|---|
[파이썬] 플라스크(Flask) - 플라스크 프로젝트 - 메모앱(1) (0) | 2024.07.23 |
[파이썬] 플라스크(Flask) - 테스팅(testing) (2) | 2024.07.22 |
[파이썬] 플라스크(Flask) - 배포(Deployment) (2) | 2024.07.22 |
[파이썬] 플라스크(Flask) - 캐싱(caching) (0) | 2024.07.21 |