즉시 종료가 무엇을 중단하는지 관찰하기

LinuxBeginner
지금 연습하기

소개

지역 다운로드 창구는 North Pier 현장 노트와 정원 자원봉사자 안내문을 배포합니다. 창구를 닫기 전에 이미 수락한 다운로드는 끝까지 보내려 합니다. 하지만 첫 구현은 연결을 즉시 닫습니다. 먼저 유용한 문서를 온전히 받은 다음, 즉시 중지가 무엇을 중단하는지 정확하게 관찰합니다.

Go 함수, 핸들러, 오류 값과 앞의 두 프로젝트에서 다룬 고루틴/채널의 책임 분담 또는 이에 준하는 경험이 필요합니다. 프로세스 식별 정보와 SIGTERM은 여기서 설명합니다. 이름이 붙은 두 터미널은 같은 머신의 별도 세션입니다. 준비된 관찰 도구는 이 과정에서 빌드한 서버와 curl 자식 프로세스만 기록하므로 네이티브 추적 형식을 배울 필요는 없습니다. 읽기와 일반적인 실수를 포함해 약 45분이라는 저자의 예상 시간입니다. 각 단원은 독립적으로 시작합니다.

문서 하나를 온전히 다운로드하기

이 단계에서는 유용한 문서를 온전히 받고 실제 바이트를 확인합니다.

Downloads에서 시작합니다. 두 터미널 진입점은 기존 작업 공간으로 이동할 뿐이며, 탭을 열어도 환경을 다시 만들지 않습니다. 일반적인 디렉터리 실수가 생기면 다음 명시적인 명령으로 올바른 위치로 돌아갈 수 있습니다.

cd /home/labex/project/download-desk

두 원본 텍스트 파일을 읽어 보세요. 같은 예제의 다른 이름이 아니라 서로 다른 실용 자료입니다. cat은 파일을 변경하지 않고 내용만 표시합니다.

cat documents/north-pier.txt documents/garden-route.txt

단원 전체에서 원본과 준비된 파일을 모두 그대로 유지합니다. desk를 빌드하고, 이름이 있는 관찰 시도를 시작하고, 다운로드를 생성할 수 있습니다. 이 단원에서는 Go 소스를 변경하지 않습니다. 이후 단원에는 각각 새 독립 복사본이 제공됩니다.

Server로 전환합니다. Go 실행 파일은 절대 경로에 준비되어 있습니다. build는 이 패키지를 컴파일하고, .은 현재 패키지이며, -o desk는 빌드 결과의 이름을 지정합니다. go run 래퍼에 신호를 보내는 것과 달리, 빌드한 바이너리를 사용하면 대상 프로세스가 명확해집니다.

cd /home/labex/project/download-desk
/usr/local/go/bin/go build -o desk .

이름을 지정한 시도를 시작합니다. 제공된 관찰기는 바이너리를 시작하고 실제 프로세스, HTTP 요청, 신호, 네이티브 종료 상태를 기록합니다. 정상 종료 조정을 구현해 주는 도구가 아닙니다. first는 시도 이름입니다. 이전 증거를 조용히 덮어쓰지 않도록 기존 이름은 거부합니다.

python3 desk.py serve first

Ready. Use Downloads for client requests.를 기다립니다. 이 터미널은 원래 프로세스가 끝날 때까지 점유됩니다. 표시된 PID는 관찰기가 아니라 빌드된 Go 자식 프로세스입니다. Server를 실행한 채 Downloads로 전환합니다.

준비된 다운로드 클라이언트는 실제 curl을 실행하고 네이티브 프로세스 결과와 실제 출력을 저장합니다. 네 인수는 시도, 새 출력 라벨, 준비된 문서, 32바이트마다 적용할 밀리초 지연을 선택합니다. 지연 0은 일반적인 빠른 예제입니다. normal 라벨은 downloads/normal.txt를 만듭니다.

python3 desk.py download first normal north-pier.txt 0

Original curl native exit: 0이 예상됩니다. 0은 전송 완료를 뜻하지만 내용까지 증명하지는 않습니다. cmp는 실제 파일을 바이트 단위로 비교하고 같으면 아무것도 출력하지 않습니다. 저장된 유용한 문서도 읽어 보세요.

cmp documents/north-pier.txt downloads/normal.txt
cat downloads/normal.txt

클라이언트가 연결 거부를 보고하면 Server로 돌아가 기존 출력을 읽습니다. 같은 포트에서 다른 프로세스를 반복해서 시작하지 마세요. Go 빌드 오류라면 디렉터리를 고치거나 준비 파일과 비교한 뒤 다시 빌드합니다. 새 셸은 다른 셸의 변수를 상속하지 않지만, 두 세션은 파일과 관찰 시도를 공유합니다.

수락된 다운로드 중 원래 서버 중지하기

이 단계에서는 실제로 수락된 전송을 중단하고 클라이언트 실패와 서버 종료를 구분합니다.

Server에서 first가 계속 실행 중인 상태로 Downloads에서 시작합니다. 프로세스 ID인 PID는 현재 실행 중인 프로세스를 식별하지만, 종료 후에는 운영체제가 같은 번호를 재사용할 수 있습니다. 관찰기는 원래 프로세스를 구별하려고 실행 파일 경로, 현재 사용자 ID, /proc의 Linux 시작 틱도 확인합니다. 이 과정에서 직접 빌드한 프로세스에만 신호를 보내세요. pkill을 사용하거나 관찰기를 대상으로 삼거나 플랫폼 프로세스 및 셸 구성을 변경하면 안 됩니다.

SIGTERM은 프로세스 종료를 요청하는 일반적인 신호입니다. kill -TERM PID는 정확히 한 PID로 요청을 보냅니다. 자체적으로 다운로드를 기다리거나 프로세스 종료를 입증하지는 않습니다. 준비된 Go 프로그램은 신호를 받으면 즉시 Close를 호출하고 main에서 반환합니다. 관찰할 것은 이 동작이며 네트워크 장애가 아닙니다.

느린 전송을 시작하기 전에 예상 실패와 복구를 포함한 나머지 단계를 모두 읽으세요. 그런 다음 작업 블록을 순서대로 실행합니다. 유한한 요청이 실행 중일 때 다음 개념을 배우느라 멈추지 마세요. 이 문서의 시간 창은 약 30초이며 무제한 대기가 아닙니다.

시간이 유한한 느린 다운로드를 백그라운드에서 시작합니다. &는 클라이언트가 실행되는 동안 이 셸이 다음 명령을 받게 합니다. $!는 마지막 백그라운드 작업의 PID이며, 대입은 해당 관찰기 작업을 저장해 나중에 wait로 네이티브 결과를 읽게 합니다. 공개된 300ms 지연은 32바이트 쓰기 사이에 적용되어 읽고 탭을 전환할 시간을 줍니다. 통제된 연습용 전송이지 성능 측정은 아닙니다.

python3 desk.py download first interrupted north-pier.txt 300 & download_job=$!

중지 전에 관찰기에게 이미 기록된 네이티브 요청을 읽도록 합니다. 이 명령은 대체 요청이나 신호를 보내지 않습니다. 원래 서버가 이 실제 클라이언트를 수락했고 두 식별 정보가 여전히 존재한다고 보고해야 합니다. 기본 curl은 작은 파일 쓰기를 버퍼링할 수 있으므로 출력이 잠시 비어 있어도 요청이 시작되지 않았다는 뜻은 아닙니다.

python3 desk.py accepted first interrupted

원래 식별 정보를 가져와 검사합니다. $(...)는 이 명령이 출력한 PID를 셸 변수에 저장하며, 뒤의 따옴표로 감싼 "$server_pid"가 이를 한 인수로 전달합니다. 도우미는 오래된 PID/시작 시각/실행 파일/UID 조합을 거부합니다.

server_pid=$(python3 desk.py pid first)
python3 desk.py identity first

수락된 요청을 관찰한 후에만 정확한 신호를 보냅니다.

kill -TERM "$server_pid"

원래 클라이언트의 결과를 읽습니다. wait는 이 셸의 백그라운드 작업을 기다립니다. 다음 명령은 18을 반환할 것으로 예상되며, curl의 바이트 부족 메시지가 함께 나옵니다. 실패한 전송을 끝까지 관찰한 결과이지, 성공 표시로 숨길 명령 오류가 아닙니다.

wait "$download_job"

echo $?는 직전 네이티브 상태를 즉시 표시하며 예상값은 18입니다. 이후 성공한 cat은 셸 상태를 바꾸므로 바로 읽어야 합니다.

echo $?
cat downloads/interrupted.txt

원본과 비교합니다.

cmp documents/north-pier.txt downloads/interrupted.txt

비교는 1을 반환하고 부분 파일이 일찍 끝났다고 보고할 것으로 예상됩니다. 받은 텍스트는 실제 North Pier 내용으로 시작하지만 불완전합니다. 따라서 같은 파일명이나 비어 있지 않은 파일만으로 완전하고 유용한 다운로드를 증명할 수 없습니다. Server로 전환해 Original server native exit: 0을 읽습니다. 정상 종료한 서버도 클라이언트를 중단했을 수 있습니다.

Downloads로 돌아가 두 결과를 유지합니다. 과정 검사는 기존 관찰과 실제 파일만 읽습니다. 실행 중인 프로세스를 중지하거나 누락된 중단 과정을 대신 만들지 않습니다.

너무 오래 기다려 신호 전에 느린 전송이 끝났다면 이를 중단이라고 부르지 마세요. 네이티브 결과 0을 읽고 전체 바이트를 비교해 보존합니다. first가 계속 실행 중이면 interrupted2 같은 새 라벨로 같은 느린 명령을 시작하고 새 작업을 저장한 다음, 신호 전에 같은 라벨로 accepted를 실행합니다. 원래 서버가 이미 끝났다면 Server로 바꿔 이전 시도를 보존하면서 retry1 같은 새 시도를 명시적으로 시작합니다. 이후 download, accepted, pid, identity 명령에 새 시도와 새 출력 라벨을 사용합니다. 검사는 이런 새 이름을 허용합니다. 부분 파일을 복사하지 말고 실제 관찰을 반복하세요. 끝났거나 알 수 없는 전송은 재사용된 PID에 신호를 다시 보낼 권한이 아닙니다.

다음은 여전히 실행 중인 같은 first에서 하는 완전한 재시도입니다. 이전 클라이언트가 실제로 끝난 뒤에만 사용하고 downloads/interrupted.txt를 보존하세요. 시작 전에 모든 블록을 읽으세요. 새 라벨은 별도 출력을 만듭니다.

python3 desk.py download first interrupted2 north-pier.txt 300 & download_job=$!
python3 desk.py accepted first interrupted2
server_pid=$(python3 desk.py pid first)
python3 desk.py identity first
kill -TERM "$server_pid"

다음 wait도 18이 예상됩니다. 즉시 읽은 뒤 새로운 실제 부분 파일을 비교합니다(비교 예상값 1).

wait "$download_job"
echo $?
cmp documents/north-pier.txt downloads/interrupted2.txt

first가 이미 끝났다면 대신 Server에서 별도 시도를 시작합니다.

python3 desk.py serve retry1

준비 메시지 뒤에 Downloads에서 세 번째 새 출력 라벨로 다음 전체 순서를 실행합니다.

python3 desk.py download retry1 interrupted3 north-pier.txt 300 & download_job=$!
python3 desk.py accepted retry1 interrupted3
server_pid=$(python3 desk.py pid retry1)
python3 desk.py identity retry1
kill -TERM "$server_pid"
wait "$download_job"
echo $?

wait는 18을 반환해야 합니다. 실제 출력을 보존하고 불완전한지 확인합니다(비교 예상값 1).

cmp documents/north-pier.txt downloads/interrupted3.txt

원래 창구를 중지하고 결과를 보존한 상태로 마칩니다. 정상 다운로드 파일은 이미 완전하며 계속 읽을 수 있습니다. 검사 전에 대체 리스너를 실행한 채 두지 마세요. 다음 독립 단원에서는 활성 전송을 보존하는 방법을 배웁니다.

요약

실제 완전한 다운로드를 관찰한 뒤, 전송 중단을 원래 서버에 대한 정확한 중지와 연결했습니다. 연결 거부, 부분 전송, 프로세스의 정상 종료는 서로 다른 사실을 나타냅니다.