Bash 스크립트에서 수천 개의 컬 백그라운드 프로세스를 병렬로 실행

Bash 스크립트에서 수천 개의 컬 백그라운드 프로세스를 병렬로 실행

난 수천개를 달리고 있어곱슬다음 bash 스크립트의 병렬 백그라운드 프로세스

START=$(date +%s)
for i in {1..100000}
do       
    curl -s "http://some_url_here/"$i  > $i.txt&
    END=$(date +%s)
    DIFF=$(( $END - $START ))
    echo "It took $DIFF seconds"
done

49Gb Corei7-920 전용 서버(비가상)가 있습니다.

명령을 통해 메모리 소비와 CPU를 추적하는데 top한계가 없습니다.

ps aux | grep curl | wc -l현재 수량을 계산하는 데 사용합니다.곱슬프로세스. 이 숫자는 2~4,000명으로 빠르게 증가한 다음 지속적으로 감소하기 시작했습니다.

컬 파이핑을 통해 awk()에 curl | awk > output간단한 구문 분석을 추가 하면 컬 프로세스 수가 1-2천으로 증가한 다음 20-30으로 감소합니다...

프로세스 수가 크게 줄어든 이유는 무엇입니까? 이 아키텍처의 경계는 어디에 있습니까?

답변1

다음 질문을 엄격히 따르십시오.

mycurl() {
    START=$(date +%s)
    curl -s "http://some_url_here/"$1  > $1.txt
    END=$(date +%s)
    DIFF=$(( $END - $START ))
    echo "It took $DIFF seconds"
}
export -f mycurl

seq 100000 | parallel -j0 mycurl

해당 시간에 상용구 텍스트가 필요하지 않은 경우 더 짧게:

seq 100000 | parallel -j0 --joblog log curl -s http://some_url_here/{} ">" {}.txt
cut -f 4 log

1000초 동안 병렬로 실행하려면 몇 가지 제한 사항(예: 파일 핸들)에 직면하게 됩니다. ulimit -n 또는 /etc/security/limits.conf를 높이면 도움이 될 수 있습니다.

답변2

for i in {1..100000}

포트는 65536개뿐입니다. 이것을 조절하십시오.

for n in {1..100000..1000}; do   # start 100 fetch loops
        for i in `eval echo {$n..$((n+999))}`; do
                echo "club $i..."
                curl -s "http://some_url_here/"$i  > $i.txt
        done &
        wait
done

(편집: (편집: 운영 체제 제한에 대한 심각하게 오래된 주장을 제거하고 누락된 주장을 추가했습니다.)echocurl
wait

답변3

일괄 동시 curl요청에 이 쉘스크립트를 사용해 보십시오:

catcurpool.sh

#!/bin/bash
# usage: ./curlpool.sh "-d '{ \"id\": 1, \"jsonrpc\": \"2.0\",  \"method\": \"cfx_getParamsFromVote\", \"params\": []}' -H \"Content-Type: application/json\" -X POST http://127.0.0.1:22537"

target=${1:-http://example.com}
cmd="curl $target"
concurrency=${2:-20}

while true # loop forever, until ctrl+c pressed.
do
    for i in $(seq $concurrency) # perfrom the inner command 100 times.
    do
        eval $cmd & # send out a curl request, the & indicates not to wait for the response.
        # or use `eval $cmd  > /dev/null &` if you don't want see the output.
    done

    wait # after all requests are sent out, wait for their processes to finish before the next iteration.
done

관련 정보