Nginx와 Gunicorn의 연결을 소켓에서 HTTP로 변경했습니다.

보이는



Django + MySQL에서 개발 한 애플리케이션의 프로덕션 환경을 Ansible을 사용하여 Amazon EC2에 구성했습니다.
마지막 게시물에서는 Nginx와 Gunicorn을 UNIX 도메인 소켓으로 연결했지만 HTTP 연결로 변경했습니다.

UNIX 도메인 소켓 연결



이것이 변경 전의 구성입니다.



왜 소켓으로 연결했는가



원래 소켓의 장점은 통신이 빠르다는 것입니다. 아래 링크에서 학습했습니다.
유닉스 도메인 소켓 - Go를 알 수 있는 시스템 프로그래밍 - 제9회
조사해야 잠을 잘 수 없다! 조사하면 불필요하게 잠을 잘 수없는 소켓 이야기

그러나 소켓 연결을 선택한 가장 큰 이유는 단순히 Gunicorn 공식 문서와 Udemy 코스 내용을 따랐기 때문이었습니다.

(1) Gunicorn 공식 문서



참조: Deploying Gunicorn (Systemd): htp // // cs. 구니코 rn. 오 rg / 엔 / ㅁ st /에서 pぉ y. html # sys md



(2) Udemy 코스



이 코스를 구입하고 학습했습니다.
「【철저하게 해설!】 Django의 기초를 마스터해, 3개의 앱을 만들자!」

HTTP 연결



그러나 그 후 소켓을 삭제하고 아래 그림의 구성으로 변경했습니다.
(왼쪽 위의/run/gunicorn 디렉토리는 PID 파일의 저장용이므로, 접속 방식과는 무관합니다)



왜 HTTP 연결로 변경했는지



(1) 구성 변경의 자유도


  • Nginx와 Gunicorn을 다른 인스턴스에 배치 할 수 있습니다 (소켓은 동일한 인스턴스 내 연결 전용)
  • Nginx와 Gunicorn 간의 관계를 일대 다로 만들 수 있습니다
  • Nginx를 ELB (Elastic Load Balancing) 등으로 교체 할 수 있습니다

  • (2) 문제 해결의 용이성



    그림과 같이 클라이언트에서 직접 Gunicorn에 연결할 수 있으므로 문제 발생 시 원인 개소를 쉽게 구분할 수 있습니다. 또한 gunicorn.socket에 의존하지 않으므로 문제의 요인 자체가 줄어 듭니다.

    Ansible Playbook 변경



    마지막으로 만든 Playbook의 장고롤에서 소켓의 유닛 파일을 템플릿으로부터 생성하는 태스크을 모두 삭제하고 나머지 부분을 다음과 같이 변경했습니다.

    vars 파일



    마지막: vars 파일
    다음 변수를 추가했습니다.
  • gunicorn_allow_ipaddr는 Gunicorn에서 본 Nginx의 IP 주소이고 127.0.0.1은 동일한 인스턴스 내에서만 연결을 허용하는 설정입니다. 0.0.0.0으로 설정하면 어디서나 연결할 수 있습니다.
  • gunicorn_listen_ipaddr는 Nginx에서 본 Gunicorn의 IP 주소입니다.
  • gunicorn_listen_port는 Nginx에서 본 Gunicorn 포트입니다.

  • inventories/development/group_vars/all.yml
    gunicorn_allowed_ipaddr: '127.0.0.1'  # 開発中は 0.0.0.0 でOK
    gunicorn_listen_ipaddr: '127.0.0.1'
    gunicorn_listen_port: 8000
    

    Gunicorn 서비스 단위 파일



    마지막: Gunicorn 서비스의 단위 파일을 템플릿에서 생성하고 시작하는 작업

    유닛 파일의 템플릿을 다음과 같이 변경했습니다.
  • 소켓에 대한 종속성이 사라졌으므로 Requires=gunicorn.socket를 삭제했습니다.
  • ExecStart--bind 값을 소켓에서 IP 주소 : 포트로 변경하고 --bind 127.0.0.1:8000로 설정했습니다.

  • roles/django/templates/gunicorn.service.j2
    [Unit]
    Description=gunicorn daemon
    After=network.target
    
    [Service]
    PIDFile={{ gunicorn_run_dir }}/pid
    User={{ service_user }}
    Group={{ service_group }}
    WorkingDirectory={{ django_project_base_dir }}
    ExecStart=/usr/local/bin/gunicorn --pid {{ gunicorn_run_dir }}/pid   \
              --bind {{ gunicorn_allowed_ipaddr }}:{{ gunicorn_listen_port }} \
              {{ django_project_name }}.wsgi
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s TERM $MAINPID
    PrivateTmp=true
    
    [Install]
    WantedBy=multi-user.target
    

    Nginx 가상 호스트 구성 파일



    마지막: Nginx 가상 호스트 구성 파일을 템플릿에서 생성하는 작업
    proxy_pass에 지정된 대상을 소켓에서 HTTP IP 주소: 포트로 변경하고 proxy_pass http://127.0.0.1:8000;로 설정했습니다.

    roles/django/templates/nginx.conf.j2
    server {
        listen       80;
        server_name  {{ ansible_host }};
        server_tokens off;
    
        location / {
            proxy_pass http://{{ gunicorn_listen_ipaddr }}:{{ gunicorn_listen_port }};  # ソケットから変更
            proxy_set_header Host               $host;
            proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host   $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Real-IP          $remote_addr;
        }
    
        location /static {
            alias {{ django_project_base_dir }}/static;
        }
    }
    

    이것으로 Nginx와 Gunicorn의 연결을 소켓에서 HTTP로 변경할 수있었습니다.

    참고


  • Gunicorn Docs » Deploying Gunicorn (Systemd)
  • 유닉스 도메인 소켓 - Go를 알 수 있는 시스템 프로그래밍 - 제9회
  • 조사해야 잠을 잘 수 없다! 조사하면 불필요하게 자지 못한 소켓 이야기

  • 기사 목록


  • 1/4: Django를 Amazon Linux 2에 Ansible로 구성, Aurora (MySQL)를 CloudFormation에서 UTF-8에 구성하고 연결할 때까지 수수하게 힘들었습니다.
  • 2/4: Nginx + Gunicorn + Django + Aurora (MySQL)의 구성을 그림에서 설명해 보겠습니다.
  • 3/4: Nginx + Gunicorn + Django + Aurora (MySQL) 프로덕션 환경을 Ansible Playbook으로 구성
  • 4/4 : Nginx와 Gunicorn의 연결을 소켓에서 HTTP로 변경
  • 좋은 웹페이지 즐겨찾기