Mar 29, 2014

AWS ELB health check for Django application

I used AWS Cloud services from my last project. To increase stability of this web application, I used Elastic Load Balancing of AWS. AWS ELB keep checking health status of web application by using TCP or HTTP ping. From this blog article, I will summarize how AWS ELB health check can be used with Django application running on Apache web server with HTTPS enabled.

1. Simple TCP ping
This is easy setting. You can ping 80 port of TCP to check if web server is running.

AWS ELB == PING TCP:80 ==> AWS EC2 web server

2. Simple HTTP ping
To check about HTTP server and it's web application running well, you can ping by using a specific URL.

AWS ELB == PING HTTP:80 /status ==> AWS EC2 web server

3. Ping with HTTPS
What's happened if you're using HTTPS instead of HTTP in your web application? No issue.

AWS ELB == PING HTTPS:80 /status ==> AWS EC2 web server with HTTPS setting

But, wait. we can configure AWS ELB to support HTTPS instead of web server. Such like the below:

Internet <== HTTPS ==> AWS ELB <== HTTP ==> AWS EC2 web server

In this case, we need to use HTTP PING to do health check. But, if we need to redirect HTTP to HTTPS then things are getting complicated. To redirect HTTP to HTTPS in the above case, we should configure in Apache setting in AWS EC2. But, if Apache server redirect all HTTP access to HTTPS then AWS ELB can't use HTTP protocol for health checking.

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} !^/status
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

You can use the Apache setting like the above. Apache rewrite engine will redirect HTTP to HTTPS if the URI is not started with /status. So, you can use HTTP:80 /status setting for AWS ELB health check.

4. Ping to Django application with DEBUG = False
Finally, if you are using Django framework for your web application, you also need to solve issue with ALLOWED_HOSTS setting. AWS ELB uses private IP address of EC2 server instance in HTTP_HOST header of HTTP, it's difficult to properly set ALLOWED_HOSTS setting of Django for AWS ELB health checking.

AWS ELB == PING HTTP:80 /statsu (HOST_NAME: 10.0.5.101) ==> AWS EC2 Django web

If AWS ELB's private IP address is not in ALLOWED_HOSTS setting of Django, Django will return 500 error code to AWS ELB. Not good. Simple way to resolve this issue is set '*' to ALLOWED_HOSTS. But, this is not good for security.

I solved this issue by writing new middleware as like the below:

from django.conf import settings
from django.middleware.common import CommonMiddleware

class ELBMiddleWare(CommonMiddleware):
    """
    Middleware for AWS ELB health check
    """
    def process_request(self, request):
        # You should change IP address range for your subnet setting
        if request.META['HTTP_HOST'].startswith("10.0.5."):
            if not request.META['HTTP_HOST'in settings.ALLOWED_HOSTS:
                settings.ALLOWED_HOSTS.append(request.META['HTTP_HOST'])
                return super(ELBMiddleWare, self).process_request(request)

ELBMiddleWare will add host IP address to ALLOWED_HOSTS if it's in the same address range of AWS VPC subnet which has AWS ELB. By using this one instead of CommonMiddleware, Django should return 200 OK to AWS ELB health check request.

That's all. Now you can use HTTP health check of AWS ELB to your HTTPS enabled Django application running on AWS EC2 Apache server.

Feb 23, 2014

AWS EB에 Django 사용 시 Cache 설정 방법

MWC 2014에 선보일 데모 프로그램을 AWS EB에 Django로 개발하였다. 주요 기능 완료 후 페이지 로딩 속도를 개선하기 위해 HTTP cache 설정을 하였다. 생각보다 고생을 해서 어떤 함정이 있었는지 이 블로그에 정리해두고자 한다.

1. AWS EB의 Apache mod_wsgi 설정
Static 파일에 대한 cache 설정은 Apache의 mod_wsgi 설정 파일의 수정이 필요하다. 하지만, mod_wsgi 설정 파일을 직접 수정해봐야 다음 번 application 버전을 AWS EB에 업로드 하면 다시 초기 설정 값으로 바뀌어 버린다. 이 문제를 해결하기 위해서는 AWS EB의 configuration hook 파일을 직접 수정해 주어야 한다. 자세한 방법은 stackoverflow의 다음 Q&A를 참고하시라.

2. S3 Cache 설정
만일, static 파일들을 AWS S3에 저장해두고 사용한다면 AWS S3의 각 object들의 cache 설정이 필요하다. 지정한 bucket의 모든 object에 대해 cache 설정을 하는 Python 예제 코드를 참고하기 바란다.

3. Django storage를 사용하는 경우
Django storage를 사용하여 AWS S3에 파일을 업로드한 경우 이 파일에 대한 URL 링크가 HTTPS이거나 혹은, auth string param이 추가되어 있으면 local cache가 불가능하다. 이 문제를 해결하기 위해서는 아래 두 설정 값을 settings.py 파일에 추가한다.

AWS_QUERYSTRING_AUTH = False
AWS_S3_SECURE_URLS = False

4. 최종 확인
Safari나 Chrome 브라우저의 developer tool을 사용해서 static file들의 local cache가 정상적으로 동작하는지 확인한다.

Feb 1, 2014

NHK Radio News 스크립트 블로그 사이트

일본 우익 정치인들은 짜증 나지만 워낙 재미있는 콘텐츠를 많이 가진 일본. 그래서, 몇 개월 전부터 본격적으로 일본어를 공부하기 시작했다.

모든 외국어 공부에서 가장 중요한 듣기 능력 향상을 위해 아침 출근 중에 NHK Radio News podcast를 내려받아 듣기 시작했는데 아직 내 실력이 모자라서 내용 파악이 전혀 되지 않는다.

어딘가 스크립트를 정리해 둔 사이트가 있지 않을까 열심히 검색해 보았지만 찾을 수가 없었다. 어떻게 할까 고민하다 떠오른 아이디어! 일본어 뉴스 정도면 음성인식으로 스크립트를 만들어 볼 수 있지 않을까?

그리하여, http://nhkradio.blogspot.kr 블로그에 일본어 음성인식을 이용해 매일 아침 NHK Radio News를 블로그에 올리는 프로그램을 만들어 보았다. 대략적인 프로그램의 동작 방법은 다음과 같다.
  1. NHK Podcast URL에서 XML 파일을 내려받는다.
  2. 새로 추가된 Podcast의 MP3 파일을 내려받는다.
  3. MP3 파일을 ffmpeg을 이용하여 WAV 파일로 변환한다. 앞 7.5초 정도의 오프닝 음악은 잘라낸다.
  4. 쿄토 대에서 개발한 Julius 음성 인식하여 text 파일로 만든다.
  5. 위 블로그에 음성 인식된 결과를 SMTP로 포스팅한다.
음성 인식을 사용하므로 당연히 100% 정확한 결과는 나오지 않지만, 학습에는 도움이 될 정도 수준의 결과는 보여준다. 전체 내용 파악은 가능하고 꽤 정확하게 문장이 만들어진다.

다음 버전에는 음성 인식된 문장 단어에 일본어 사전 링크를 연결 시켜 볼까 한다.  일본어 학습하시는 다른 분들에게도 도움이 되었으면 좋겠다.