GitHub 웹후크를 통해 자동으로 호출되는 간단한 배포 스크립트를 사용하여 Debian 서버에서 실행되는 Django 애플리케이션이 있습니다.
#!/bin/sh
git pull
/home/criticalnotes/.local/bin/poetry install --with prod --sync
/home/criticalnotes/.local/bin/poetry run ./manage.py migrate
sudo /usr/sbin/service api.critical-notes.com restart
echo "service api.critical-notes.com restarted"
따라서 이 배포 스크립트는 git에서 최신 코드를 가져와 종속성을 설치하고 마이그레이션 스크립트를 실행한 다음 서비스를 다시 시작합니다.
내 api.critical-notes.com.service
파일:
[Unit]
Description=api.critical-notes.com
[Service]
User=criticalnotes
Group=criticalnotes
Restart=on-failure
WorkingDirectory=/home/criticalnotes/api.critical-notes.com
ExecStart=/home/criticalnotes/.local/bin/poetry run uvicorn criticalnotes.asgi:application --log-level warning --workers 8 --uds /tmp/uvicorn.sock
[Install]
WantedBy=multi-user.target
이 설정은 오랫동안 잘 작동했지만 오늘 GitHub에 새 코드를 푸시하자 사이트 작동이 중단되었습니다. 무슨 일이 일어나고 있는지 살펴본 후 api.critical-notes.com
서비스가 더 이상 실행되지 않고 오류로 인해 계속 종료되는 것을 발견했으며 백엔드를 수동으로 시작하려고 할 때 다음 오류가 발생했습니다.
Address already in use
특히 이전에 이런 일이 발생한 적이 없고 오늘(또는 최근) 배포나 설정을 변경한 적이 없기 때문에 이 문제의 원인이 무엇인지 전혀 모릅니다. 그래서 내 질문은 이것이 어떻게 발생하는가입니다. 백엔드가 실행되지 않을 때 주소가 계속 사용되는 것이 어떻게 가능합니까? 둘째, 이런 일이 다시 발생하지 않도록 배포 스크립트를 어떻게 개선할 수 있습니까?
코드 푸시에 문제가 있는 이유를 알아내려고 할 때 백엔드가 오프라인이어서 사이트가 약 30분 동안 오프라인 상태였는데 꽤 무서웠습니다. 이런 일이 다시는 일어나지 않았으면 좋겠어
답변1
애플리케이션 및 배포 프로세스에 대해 더 자세히 알지 못하면 이 질문에 확실하게 대답하는 것이 거의 불가능합니다. 일반적인 문제에는 구성 스크립트 충돌, 예약된 범위 내의 포트 사용 또는 마지막 다시 시작에서 필요한 바인딩을 유지하는 지연 프로세스가 포함됩니다. 지난 몇 달 동안 필수 라이브러리/종속성(예: uvicorn, python 등)을 업데이트한 경우 기본 구성이 변경되었을 수 있으므로 이제 제대로 작동하려면 추가 매개변수를 지정해야 합니다. 특히 시작 스크립트에서 UDS 파일을 생성해야 하는 경우에는 UDS 파일과 관련될 수도 있습니다. 어떤 이유로든 열려 있는 상태로 잠겨 있으면 이와 같은 오류가 발생할 수 있습니다. 해당 소켓을 사용하는 방법을 모르는 경우 파일이 열려 있는 근본 원인은 코드의 거의 모든 부분에 있는 버그일 수 있습니다. (또는 마지막 작업 이후 업데이트된 종속성.)
더 자세한 내용을 추가하신 것으로 확인되면 돌아가서 좀 더 구체적인 답변으로 편집해 보겠습니다. 하지만 이것이 최소한 올바른 방향을 제시해주기를 바랍니다.
답변2
주소가 이미 사용 중입니다.
이것이 실제로 여기서 고려해야 할 유일한 것입니다. 서비스가 사용하는 주소(특히 포트)를 지정하지 않았습니다. 웹 서비스라면 해당 포트는 아마도 80 및/또는 443일 것입니다. 이 포트를 사용하는 것이 무엇인지 알아내야 합니다. 데비안 버전에 따라 사용하는 명령은 (루트로) netstat -nap | grep :80
또는 ss -nlp | grep :80
.
다음을 사용하여 관련 포트에서 수신 대기 중인 항목이 있는지 확인할 수도 있습니다.nc -zv localhost 80
(443번 반복)
실제로 아무것도 듣지 않는다면 서버가 두 번 자체 시작을 시도하는 것처럼 들립니다.
systemctl status api.critical-notes.com
출력을 보고 터미널 세션에서 실행할 때 어떤 일이 발생하는지 확인할 수도 있습니다 .systemctl restart api.critical-notes.com