DJango 서버개발, 다양한 캐시 백엔드 설정하기 (Memcached, Redis 등)

작성자: 조광형

날짜: 2024년 11월 26일

1. 캐시의 필요성

웹 어플리케이션 개발에서 성능은 매우 중요한 요소입니다. 사용자 경험을 향상시키고, 서버 자원 소비를 줄이기 위해 caching은 필수적입니다.
캐시를 사용하면 데이터베이스나 소스 시스템에 대한 요청을 줄이고, 이전에 저장된 결과를 빠르게 반환할 수 있습니다.
이로 인해, 응답 시간이 줄어들고 서버 부하도 감소합니다.

Django는 다양한 캐시 백엔드를 지원하며, 매우 유연한 캐시 시스템을 제공합니다.
이 글에서는 Django에서 Memcached와 Redis와 같은 캐시 백엔드를 설정하는 방법에 대해 상세히 다루겠습니다.

2. Django의 캐시 프레임워크 개요

Django의 캐시 프레임워크는 다음과 같은 장점을 제공합니다:

  • 고성능: 메모리 기반 캐시 시스템을 사용하여 빠른 데이터 접근을 가능하게 합니다.
  • 유연성: 다양한 캐시 수단(Memory, Memcached, Redis 등)을 지원합니다.
  • 확장성: 큰 규모의 프로젝트에서도 유용하게 사용할 수 있습니다.

기본적으로 Django는 캐시를 설정하기 위해 두 가지 방법을 제공합니다:

  1. 전체 캐시 설정
  2. 뷰 레벨 캐시 설정

이러한 설정을 통해 사용자 요청의 일부 결과를 저장하고, 주기적으로 갱신하여 불필요한 데이터베이스 쿼리를 줄일 수 있습니다.

3. Memcached 설정하기

3.1 Memcached 설치

Memcached는 메모리 기반의 분산 캐시 시스템으로, 속도가 빠르고 사용이 간편합니다.
설치를 위해서는 운영체제에 따라 다음과 같은 명령어를 사용합니다.

sudo apt-get install memcached

3.2 Django에서 Memcached 설정

Django 프로젝트에 Memcached를 사용하려면, settings.py 파일에서 캐시 설정을 추가해야 합니다.
아래는 Memcached를 사용하는 설정 예제입니다:

 
# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
        

3.3 데이터 캐싱 예제

캐시를 사용하여 장고의 뷰에서 데이터를 캐시하는 방법은 다음과 같습니다.
간단한 예제에서 특정 사용자 정보를 캐시해 보겠습니다:


from django.core.cache import cache
from django.shortcuts import render
from .models import UserProfile

def user_profile(request, user_id):
    # 캐시에 데이터가 있는지 확인
    user_data = cache.get(f'user_profile_{user_id}')
    
    if not user_data:
        # 캐시에서 데이터를 찾지 못하면 DB에서 조회
        user_data = UserProfile.objects.get(id=user_id)
        # 캐시에 데이터 저장 (5분 동안 유지)
        cache.set(f'user_profile_{user_id}', user_data, timeout=300)
    
    return render(request, 'user_profile.html', {'user_data': user_data})
        

4. Redis 설정하기

4.1 Redis 설치

Redis는 키-값 저장소로 메모리 기반의 데이터베이스입니다. 설치는 다음 명령어로 수행할 수 있습니다.

sudo apt-get install redis-server

4.2 Django에서 Redis 설정

Django에서 Redis를 사용하기 위해 django-redis 패키지를 설치해야 합니다. 다음 명령어를 사용합니다:

pip install django-redis

그 후, settings.py 파일에 Redis 캐시 설정을 추가해야 합니다:


# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        }
    }
}
        

4.3 데이터 캐싱 예제

Redis를 사용하여 캐시된 데이터를 이용하는 방법은 Memcached와 유사합니다.
다음 예제에서는 특정 키워드의 검색 결과를 캐시하는 기능을 구현합니다:


from django.core.cache import cache
from django.shortcuts import render
from .models import Product

def search_products(request):
    query = request.GET.get('q')
    cache_key = f'products_search_{query}'
    products = cache.get(cache_key)

    if not products:
        products = Product.objects.filter(name__icontains=query)
        cache.set(cache_key, products, timeout=600)
    
    return render(request, 'search_results.html', {'products': products})
        

5. 캐시 무효화 및 관리

캐시된 데이터는 시간이 지나면 유효성이 떨어지거나 변경될 수 있습니다.
이럴 때는 캐시를 무효화하거나 갱신해야 합니다. Django에서는 cache.delete() 메소드를 통해 특정 키의 캐시를 삭제할 수 있습니다.


# 특정 캐시 삭제
cache.delete(cache_key)
        

또한 모든 캐시를 한 번에 삭제하고 싶다면 cache.clear()를 사용할 수 있습니다.
이는 집합적으로 모든 캐시를 무효화하는 방법입니다.


# 모든 캐시 삭제
cache.clear()
        

6. 결론

Django의 캐시 프레임워크를 활용하면 애플리케이션 성능을 크게 향상시킬 수 있습니다.
이번 글에서는 Memcached와 Redis 두 가지 캐시 백엔드를 설정하고 사용하는 방법에 대해 알아보았습니다.
각각의 캐시는 특정 상황과 용도에 따라 장단점이 있으므로, 필요에 맞는 것을 선택하여 사용하길 권장합니다.

캐시 구성은 초기 설정만으로 끝나는 것이 아니라, 주기적인 모니터링과 조정이 필요합니다.
각 캐시의 성능을 분석하고, 사용자 요구에 맞춰 적절히 관리해 나가는 것이 중요한 만큼
이 글이 Django에서 캐시 시스템을 이해하고 구현하는 데 도움이 되었길 바랍니다.

© 조광형 – All Rights Reserved.

DJango 서버개발, Django Channels를 이용한 실시간 기능 구현하기


<h2>Chat Room</h2>
<div id=”chat-log”></div>
<input type=”text” id=”username” placeholder=”Enter your name” />
<input type=”text” id=”message” placeholder=”Message” />
<button id=”send”>Send</button>

<script>
$(document).ready(function(){
const roomName = “{{ room_name }}”;
const chatSocket = new WebSocket(
‘ws://’ + window.location.host + ‘/ws/chat/’ + roomName + ‘/’
);

chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
$(‘#chat-log’).append(data.username + “: ” + data.message + “<br>”);
};

$(‘#send’).click(function(){
const messageInputDom = $(‘#message’);
const message = messageInputDom.val();
const username = $(‘#username’).val();
chatSocket.send(JSON.stringify({
‘message’: message,
‘username’: username
}));
messageInputDom.val(”);
});
});
</script>

DJango 서버개발, 사용자 정의 에러 페이지 만들기 (404, 500 에러 처리)

Django는 파이썬으로 작성된 오픈소스 웹 프레임워크로, 빠르게 프로토타입을 만들고 배포하할 수 있게 도와주는 훌륭한 도구입니다. 웹 애플리케이션을 개발하면서, 사용자 경험을 높이기 위한 여러 가지 요소를 고려해야 하며, 그 중 하나가 바로 에러 페이지입니다. 기본적으로 Django는 여러 가지 HTTP 에러에 대해 기본 제공 에러 페이지를 갖추고 있지만, 이를 사용자 정의 페이지로 변경하여 보다 나은 사용자 경험을 제공할 수 있습니다. 이 글에서는 404 에러와 500 에러에 대한 사용자 정의 페이지를 만드는 방법에 대해 자세히 설명하겠습니다.

1. Django 프로젝트 설정하기

먼저, Django 프로젝트를 설정해야 합니다. 프로젝트를 처음부터 시작할 경우, 다음 명령어로 새 프로젝트를 생성합니다:

django-admin startproject myproject

생성된 프로젝트 폴더로 이동한 후:

cd myproject

이제 Django 서버를 실행해 보겠습니다. 아래의 명령어를 사용하여 서버를 시작합니다:

python manage.py runserver

이제 http://127.0.0.1:8000에서 기본 Django 페이지를 확인할 수 있습니다.

2. 에러 처리 페이지 만들기

Django에서 404 에러(페이지를 찾을 수 없음)와 500 에러(서버 오류) 페이지를 사용자 정의하려면, 특정 HTML 템플릿 파일을 만들어야 합니다. 먼저, 앱 내의 템플릿 디렉토리를 생성합니다. 예를 들어, myapp이라는 앱을 사용한다고 가정합시다. 다음과 같은 구조를 만듭니다:

myproject/
├── myapp/
│   ├── templates/
│   │   ├── 404.html
│   │   └── 500.html
├── manage.py
└── myproject/

2.1 404 에러 페이지 만들기

404.html 파일을 생성하고 아래와 같이 작성해보세요:

<!-- myapp/templates/404.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>페이지를 찾을 수 없습니다</title>
    <style>
        body { text-align: center; padding: 150px; }
        h1 { font-size: 50px; }
        body { font: 20px Helvetica, sans-serif; color: #333; }
        article { display: block; text-align: left; width: 650px; margin: 0 auto; }
    </style>
</head>
<body>
    <article>
        <h1>죄송합니다, 페이지를 찾을 수 없습니다.</h1>
        <p>요청하신 페이지는 존재하지 않거나 삭제되었습니다.</p>
        <a href="/ ">홈으로 돌아가기</a>
    </article>
</body>
</html>

2.2 500 에러 페이지 만들기

마찬가지로, 500.html 파일을 생성하고 다음과 같이 작성해보세요:

<!-- myapp/templates/500.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>서버 오류</title>
    <style>
        body { text-align: center; padding: 150px; }
        h1 { font-size: 50px; }
        body { font: 20px Helvetica, sans-serif; color: #333; }
        article { display: block; text-align: left; width: 650px; margin: 0 auto; }
    </style>
</head>
<body>
    <article>
        <h1>죄송합니다, 서버 오류가 발생했습니다.</h1>
        <p>지금 잠시 후 다시 시도해 주시기 바랍니다.</p>
        <a href="/ ">홈으로 돌아가기</a>
    </article>
</body>
</html>

3. Django에서 사용자 정의 에러 페이지 등록하기

이제 만든 HTML 파일을 Django에 등록하여 사용할 수 있도록 설정해야 합니다. Django 프로젝트의 settings.py 파일을 열고, 하단에 다음 코드를 추가하여 템플릿 디렉토리를 설정합니다:

# myproject/settings.py
import os

TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'myapp/templates')],
        ...
    },
]

그 다음, 사용자 정의 에러 페이지를 활성화하려면, 다음과 같이 설정합니다:

# myproject/settings.py

DEBUG = False  # 디버깅 모드 끄기
ALLOWED_HOSTS = ['localhost']  # 허용된 호스트

이제 우리는 커스텀 에러 페이지를 활용할 준비가 되었습니다. Django의 모듈을 만들어 404 에러와 500 에러를 실제로 발생시켜 테스트해보겠습니다.

4. 에러 테스트하기

4.1 404 에러 테스트하기

브라우저에서 http://127.0.0.1:8000/thispagedoesnotexist와 같은 잘못된 URL에 접근하면, 우리가 만든 404.html 사용자 정의 에러 페이지가 나타나야 합니다.

4.2 500 에러 테스트하기

500 에러는 실제 상황에서 발생하기 어렵기 때문에, 의도적으로 500 에러를 발생시키기 위해 views.py 파일에 다음과 같은 코드를 추가합니다:

# myapp/views.py

from django.http import HttpResponse
from django.shortcuts import render

def trigger_error(request):
    # 이 함수는 500 에러를 발생시킵니다.
    return 1 / 0  # ZeroDivisionError를 발생시킴

위 코드를 추가한 뒤, urls.py에 이 뷰를 호출할 URL을 등록합니다:

# myapp/urls.py

from django.urls import path
from .views import trigger_error

urlpatterns = [
    path('trigger-error/', trigger_error, name='trigger-error'),  # 500 에러를 발생시키는 URL
]

이제 http://127.0.0.1:8000/trigger-error/로 접속하면, 500.html 사용자 정의 에러 페이지가 표시되어야 합니다.

5. 결론

이렇게 Django에서 사용자 정의 에러 페이지(404, 500 에러)를 만드는 방법을 살펴보았습니다. 사용자 정의 페이지를 통해 웹사이트의 일관된 디자인을 유지하고 사용자 경험을 높일 수 있습니다. 에러 페이지를 세심하게 설계하면, 방문자들이 사이트에 대한 긍정적인 인상을 받을 수 있습니다. Django의 유연성과 강력함을 활용하여 원하는 대로 웹 애플리케이션을 개발해보세요!

마지막으로, Django는 매우 많은 기능을 제공하므로, 더 많은 기능을 활용하고 싶다면 공식 문서도 참고하십시오. 다음 링크를 통해 Django의 공식 문서를 확인하실 수 있습니다: Django 공식 홈페이지.

DJango 서버개발, 테스트 커버리지 측정 및 CI CD 도구와 통합하기

이번 포스팅에서는 Django를 사용한 서버 개발 과정에서의 테스트 커버리지 측정 및 CI/CD 도구와 통합하는 방법을 상세히 설명하겠습니다. 이 과정을 통해 우리는 보다 신뢰할 수 있는 애플리케이션을 개발할 수 있으며, 코드 품질을 유지하고 배포 과정을 자동화할 수 있습니다.

1. Django 서버 개발

Django는 파이썬으로 작성된 웹 프레임워크로, 애플리케이션의 전반적인 개발 과정을 간소화하고, 빠른 개발을 가능하게 합니다. Django의 주요 특징으로는 MVC 패턴을 따른 웹 애플리케이션 구조, ORM(Object-Relational Mapping)의 제공, 다양한 내장 기능 등이 있습니다.

1.1 Django 설치

우선, Django를 설치하기 위해서는 Python이 필요합니다. Python 및 Django를 설치하는 방법은 다음과 같습니다:

pip install django

1.2 Django 프로젝트 생성

Django 프로젝트를 생성하기 위해서는 다음의 명령어를 실행합니다:

django-admin startproject myproject

이렇게 만들어진 myproject 폴더 안에는 여러 설정 파일이 생성됩니다. 이제 서버를 실행해 보겠습니다:

cd myproject
python manage.py runserver

기본적으로 개발 서버는 http://127.0.0.1:8000에서 실행됩니다. 웹 브라우저에서 이 주소를 입력하면 Django의 환영 페이지를 볼 수 있습니다.

2. Django 애플리케이션 생성

이제 본격적으로 Django 애플리케이션을 생성해 보겠습니다. Django는 하나의 프로젝트 안에 여러 개의 애플리케이션을 포함할 수 있습니다.

python manage.py startapp myapp

이제 myapp 폴더가 생성되었습니다. 이 폴더에는 여러 파일이 포함되어 있으며, models.py, views.py, urls.py 등의 중요한 파일들이 있습니다.

3. 테스트 커버리지 이해하기

테스트 커버리지는 코드의 측정 기준을 제공하는 도구입니다. 코드를 어떤 정도로 테스트했는지 평가하는 데 사용되며, 이는 단위 테스트가 얼마나 많은 부분의 코드를 커버하고 있는지를 나타냅니다. Django에서 테스트 커버리지를 측정하는데 사용할 수 있는 도구 중 하나는 coverage.py입니다.

3.1 테스트 및 커버리지 설치

테스트와 커버리지 측정을 위해 필요한 패키지를 설치합니다:

pip install coverage

3.2 테스트 작성하기

이제 간단한 테스트 케이스를 작성해 보겠습니다. myapp/tests.py 파일을 열고 다음 코드를 추가합니다:

from django.test import TestCase
from .models import MyModel

class MyModelTest(TestCase):
    def setUp(self):
        MyModel.objects.create(name="test", value=10)

    def test_model_str(self):
        my_model = MyModel.objects.get(name="test")
        self.assertEqual(str(my_model), "test")

3.3 커버리지 측정하기

테스트를 실행하고 커버리지를 측정해 보겠습니다. 다음 명령어를 사용합니다:

coverage run manage.py test myapp
coverage report

이 명령어를 통해 실행된 테스트 케이스와 커버리지 비율을 확인할 수 있습니다. 추가적으로, HTML 형식으로 커버리지 리포트를 생성할 수도 있습니다:

coverage html

이 명령어를 실행하면 htmlcov/index.html 파일이 생성되며, 이를 웹 브라우저에서 열면 시각적으로 커버리지 결과를 확인할 수 있습니다.

4. CI/CD 도구와 통합하기

CI/CD(지속적 통합 및 지속적 배포)는 소프트웨어 개발과 배포 프로세스를 자동화하여 효율성을 높이는 기법입니다. Jenkins, GitHub Actions, GitLab CI 등을 사용하여 Django 애플리케이션에 CI/CD를 통합할 수 있습니다. 여기서는 GitHub Actions를 예로 들겠습니다.

4.1 GitHub Actions 설정하기

먼저, 애플리케이션의 루트 디렉토리에 있는 .github/workflows 폴더 안에 새로운 YAML 파일을 생성합니다. 예를 들어, ci.yml라는 파일을 생성합니다.

name: Django CI

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      db:
        image: postgres:latest
        env:
          POSTGRES_DB: mydb
          POSTGRES_USER: user
          POSTGRES_PASSWORD: password
        ports:
          - 5432:5432
        health-check:
          test: ["CMD-SHELL", "pg_isready -U user"]
          interval: 5s
          timeout: 5s
          retries: 5

    steps:
      - name: 체크아웃 코드
        uses: actions/checkout@v2

      - name: Python에 대한 의존성 설치
        uses: actions/setup-python@v2
        with:
          python-version: '3.8'

      - name: 의존성 설치
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: 테스트 실시
        run: |
          coverage run manage.py test myapp
          coverage report

위의 설정은 다음과 같은 작업들을 수행합니다:

  • master 브랜치에 푸시하거나 풀 리퀘스트가 생성될 때 작업이 실행됩니다.
  • PostgreSQL 데이터베이스 서비스를 설정합니다.
  • 코드를 체크아웃하고, Python 환경을 설정합니다.
  • 필요한 의존성을 설치하고, 테스팅을 수행합니다.

4.2 CI/CD 실행 확인하기

GitHub에 변경사항을 푸시한 후, Actions 탭으로 이동하면 CI/CD 파이프라인이 실행되는 것을 확인할 수 있습니다. 성공적으로 완료되면 테스트 결과와 커버리지 리포트를 확인할 수 있습니다.

5. 결론

Django 애플리케이션의 서버 개발, 테스트 커버리지 측정 및 CI/CD 도구와의 통합 과정은 애플리케이션의 품질을 유지하고 안정적인 배포를 돕습니다. 이러한 프로세스를 통해 우리는 다수의 사용자에게 신뢰할 수 있는 서비스를 제공할 수 있습니다. 더욱이, 자동화된 테스트 및 배포 과정은 개발자가 보다 효율적으로 작업할 수 있도록 도와줍니다.

이 포스팅을 통해 Django 서버 개발의 기초와 테스트, CI/CD 통합의 중요성을 이해하는 데 도움이 되었기를 바랍니다. DevOps 문화의 일환으로 코드 품질 관리와 배포 자동화는 지금의 개발 환경에서 필수적인 요소가 되고 있습니다. 앞으로의 프로젝트에 이를 적용하여 더 좋은 결과를 만들어 나가길 바랍니다!