[nginx] nginx 서비스 시작 스 크 립 트 읽 기

13433 단어
원인
이전에 서비스의 부팅 스 크 립 트 를 설정 해 야 했 지만 안 타 깝 게 도 저 는 좋 은 Linux 시스템 의 사용 과 설정 경험 이 없고 운영 체제 가 익숙 하지 않 으 며 Shell 스 크 립 트 가 익숙 하지 않 습 니 다. 인터넷 의 튜 토리 얼 과 예 가 적지 않 지만 자신의 기초 에 국한 되 어 참고 성 이 크 지 않 습 니 다.기 존의 경험 과 사용 상황 을 바탕 으로 nginx 의 서비스 시작 과 주기 관리 가 좋 은 예 가 아 닙 니까?nginx 의 init 스 크 립 트 를 읽 고 셸 프로 그래 밍 의 지식 점 과 프로 그래 밍 구 조 를 확장 합 니 다.
돌이켜보다
일단 뭐 가 필요 해요?로 컬 실행 가능 한 파일 이 있 습 니 다. 시작 한 후에 제 한 된 http 서 비 스 를 제공 할 수 있 습 니 다. nginx 의 서비스 처럼 시작 하고 세 션 시작 이 닫 히 지 않 는 영향 을 받 지 않도록 해 야 합 니 다.데 몬, 백 스테이지 의 개념 을 익히 는 과정 에서 어떻게 실천 하 는 지 알 아 보 세 요.
nginx 서비스 조작
시작 명령 sudo /etc/init.d/nginx start 닫 기 명령 sudo /etc/init.d/nginx stop 보기 상태 sudo /etc/init.d/nginx status 재 부팅 sudo /etc/init.d/nginx restart 논리 적 으로 루트 권한 을 사용 하여 절대 경로 가 존재 하 는 스 크 립 트 를 실행 하고 매개 변수, start, stop, status restart 등 을 입력 하여 해당 하 는 동작 을 수행 합 니 다. 상호작용 차원 에서 모방 하면 됩 니 다.
sudo /etc/init.d/myservice {start|stop|status|restart}

시작
시작 부분
#!/bin/sh

### BEGIN INIT INFO
# Provides:   nginx
# Required-Start:    $local_fs $remote_fs $network $syslog $named
# Required-Stop:     $local_fs $remote_fs $network $syslog $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

첫 번 째 줄 은 셸 스 크 립 트 의 마법 문자열 입 니 다. 해석 기 를 지정 합 니 다. 모든 스 크 립 트 가 이 렇 습 니 다.그 다음 에 큰 주석 입 니 다. init info 시작 정 보 는 잘 모 르 겠 습 니 다. 0 에서 6 의 숫자 는 실행 단계 인 것 같 습 니 다. 잠시 상관 하지 않 고 주석 이 실 행 될 수 없습니다.
20170605 These comments are definitely not useless. They are used to define LSB info, why I found it? because it has warning when I add it to init daemon use this
sudo update-rc.d myservice defaults

변수 정의
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx

다음 부분 은 변수 설정 부분 입 니 다. 이 컴퓨터 시스템 의 PATH 변수 가 원래 무엇 인지 먼저 살 펴 본 다음 에 PATH DAEMON 을 직접 지정 한 다 는 뜻 자체 가 데 몬 이라는 뜻 입 니 다. 여기 서 지정 한 nginx 의 바 이 너 리 프로그램 은?디 렉 터 리 에 해당 하 는 파일 이 무슨 뜻 인지 볼 까요?파일 은 실제 존재 하고 nginx 의 실행 파일 일 것 입 니 다. 그러면 제 실행 가능 한 파일 도 이 변수 에 설정 해 야 합 니 다. NAME 와 DESC 는 아래 스 크 립 트 의 변수 만 바 뀌 어야 합 니 다. 서비스의 이름과 설명 으로 도 자신의 서비스 이름 으로 바 꿔 야 합 니 다.
기본 설정 실행
# Include nginx defaults if available
if [ -r /etc/default/nginx ]; then
    . /etc/default/nginx
fi

먼저 셸 에 있 는 if 구조 가 어떻게 쓰 여 있 는 지 봐 야 겠 어 요. 잘 모 르 겠 어 요. 이게..............................................
셸 의 if 구조
분기 구조의 기본 형식 은 if 뒤에 중 괄호 를 따라 가 는 것 입 니 다. 중 괄호 안에 조건 식 이 들 어 있 습 니 다. 진짜 와 가 짜 를 나타 내 는 불 값 입 니 다. 그 다음 에 하나의 분점 과 then 입 니 다. 진짜 분기 코드 블록 은 fi 로 끝 납 니 다.
if [ ... ]; then
...
fi

네모 난 괄호 안의 조건 식 의 쓰 기 는 고정된 형식 이 있 습 니 다. 위의 표현 식 의 구체 적 인 의 미 는 파일 이 읽 을 수 있 는 지 확인 하 는 것 입 니 다 -r /etc/default/nginx.조건 이 성립 되 었 을 때 실 행 된 코드 블록 에 있 는 명령 을 살 펴 보 겠 습 니 다. 한 점, 빈 칸, 파일 을 더 하면 이 파일 을 실행 하 는 것 을 표시 합 니 다. source file;. /file ; . file 이 몇 가지 명령 은 모두 파일 을 실행 하 는 것 같 지만 약간 다 릅 니 다. 구체 적 인 차 이 는 잠시 깊이 연구 하지 않 겠 습 니 다.
다시 읽 기 에서 이 단락 의 뜻 은 아마도 이 프로필 이 읽 을 수 있 는 지 확인 하 는 것 입 니 다. 만약 그렇다면 이 프로필 을 실행 하고 이 프로필 의 내용 을 보십시오. / etc / defaults / nginx
 # Note: You may want to look at the following page before setting the ULIMIT.
#  http://wiki.nginx.org/CoreModule#worker_rlimit_nofile
# Set the ulimit variable if you need defaults to change.
#  Example: ULIMIT="-n 4096"
#ULIMIT="-n 4096"

내용 이 모두 주석 이 떨 어 졌 으 니, 아무것도 실행 하지 않 았 다 고 말 해라.
테스트 실행 파일
test -x $DAEMON || exit 0

이 줄 코드 에는 몇 가지 볼 점 이 있 습 니 다. test 명령 이 무엇 입 니까? -x 매개 변 수 는?하나의 세로 선 은 파이프 이 고, 두 개의 세로 선 은 또 무엇 입 니까?exit 0 은 탈퇴 를 의미 합 니까?
  • test 명령: test 자체 의 역할 은 파일 형식 을 검사 하고 값 을 비교 하 는 것 입 니 다. - x 매개 변 수 를 결합 하 는 역할 은 파일 이 존재 하 는 지, 실행 권한 이 있 는 지 확인 하 는 것 입 니 다
  • 단락 논리 또는 |: exit 0 왼쪽 의 두 세로 선 | | 일반적인 의미 와 마찬가지 로 논리 연산 자 입 니 다. 단락 의 논 리 를 표시 하거나 | | 왼쪽 test 명령 이 가짜 로 돌아 갈 때 오른쪽 exit 0 종료 명령 이 실 행 됩 니 다. 스 크 립 트 가 종료 되 었 음 을 표시 합 니 다.위의 두 가지 점 을 결합 하면 이 문 구 는 실행 가능 한 파일 DAEMON 에 실행 가능 한 병기 가 있 는 지 테스트 하고 그렇지 않 으 면 프로그램 을 종료 한 다 는 뜻 이다.

  • 환경 초기 화
     . /lib/init/vars.sh
     . /lib/lsb/init-functions
    

    이것 은 두 개의 파일 을 실 행 했 습 니 다. 이름 을 보 세 요. 하 나 는 초기 화 변수 정의 입 니 다. 하 나 는 초기 화 함수 입 니 다. 구체 적 인 내용 에서 일부 변수 와 함수 의 정 의 를 실 행 했 습 니 다. 아래 에 사용 할 때 뒤 돌아 보 세 요.
    PID 가 져 오기 시도
    # Try to extract nginx pidfile
     PID=$(cat /etc/nginx/nginx.conf | grep -Ev '^\s*#' | awk 'BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1)
    if [ -z "$PID" ]
    then
        PID=/run/nginx.pid
    fi
    

    먼저 이 파일 / etc / nginx / nginx. conf 와 관련 이 있 을 것 입 니 다. cat 명령 으로 내용 을 인쇄 한 다음 grep 로 무엇 을 선별 한 다음 awk 명령 에 맡 기 고 마지막 으로 head 명령 입 니 다.한 사람 씩 보다
  • cat 명령 은 익숙 합 니 다. 그 렇 죠? 파일 의 내용 을 콘 솔 에 인쇄 하 는 것 입 니 다. 즉, 파이프 의 첫 번 째 단 계 는 이 프로필 의 내용 을 콘 솔 에 인쇄 하 는 것 입 니 다
  • .
  • grep 는 선별 이라는 것 만 알 고 선별 한 내용 이 있 는 줄 을 되 돌려 줍 니 다. 이렇게 매개 변수 - ev 의 구체 적 인 의 미 는?뒤 꿈 치 는 정규 표현 식 이 분명 합 니 다. 관계 가 있 을 겁 니 다 ~ ~
  • - E 매개 변 수 는 뒤에 정규 표현 식 이 따 르 고 - v 는 반 선택 을 나타 내 며 출력 은 표현 식 과 일치 하 는 것 이 아니 라 일치 하지 않 는 다 는 뜻 입 니 다.정규 를 보면 뜻 은 임의의 빈 칸 으로 시작 하고 그 다음은 우물 번호 입 니 다. 모든 주석 줄 을 뜻 합 니까?반대로 선택 하면 모든 주석 을 지 우 는 거 예요.
  • 여기까지 도 분명 합 니 다. 첫 번 째 단 계 는 프로필 을 인쇄 하고 두 번 째 단 계 는 모든 주석 줄 을 삭제 한 다음 세 번 째 단계 awk
  • 에 왔 습 니 다.
  • awk 명령 은 별로 접촉 하지 않 았 고 강력 하 다 는 것 을 알 고 있 습 니 다.awk 는 패턴 스 캔 과 텍스트 처리 언어 입 니 다. 이것 은 언어 입 니까?음.......................................................................................그럼 두 번 째 부분 을 출력 합 니 다.여기 서 알 수 있 습 니 다. 마지막 으로 얻 은 것 은 pid 를 저장 하 는 파일 입 니 다.
  • head 가 파일 을 가 져 오기 전 줄 입 니 다. - n1 은 첫 줄 을 가 져 오 는 것 입 니 다
  • 설정 파일 을 분석 한 후에 pid 를 저장 하 는 파일 을 얻 었 습 니 다. 그래서 나중에 변수 pid 의 길이 가 0 인지 확인 하 십시오. 설정 파일 을 찾 지 못 하면 기본 / run / ngix. pid 를 사용 합 니 다.
    ulimit 검사
    # Check if the ULIMIT is set in /etc/default/nginx
    if [ -n "$ULIMIT" ]; then
        # Set the ulimits
        ulimit $ULIMIT
    fi
    

    이 파일 의 ulimit 설정 옵션 이 설명 되 었 기 때문에 - n 매개 변 수 는 뒤의 매개 변수 문자열 의 길이 부위 가 0 일 때 진실 임 을 표시 합 니 다.그래서 이 코드 는 실행 되 지 않 습 니 다. ulimit 는 무엇 을 표시 하 든 잠시 상관 하지 않 습 니 다.
    함수 정의 부분
    #
    # Function that starts the daemon/service
    #
    do_start()
    {
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON --test > /dev/null \
            || return 1
        start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON -- \
            $DAEMON_OPTS 2>/dev/null \
            || return 2
    }
    

    함수 의 이름 을 통 해 알 수 있 듯 이 이것 은 서비스 가 시 작 될 때 실 행 된 함수 입 니 다. 주석 에서 도 반환 값 의 구체 적 인 의 미 를 알 수 있 습 니 다. 0 - 서 비 스 는 이미 시작 되 었 고 1 - 서 비 스 는 이미 실행 되 었 습 니 다. 2 - 서 비 스 는 시작 되 지 않 습 니 다. start - stop - daemon 은 시스템 의 명령 으로 서 비 스 를 닫 는 데 사 용 됩 니 다. 그러면 나머지 는 설정 매개 변수 입 니 다.유일한 문 제 는 그 DAEMON 을 찾 지 못 했다 는 거 예요.OPTS 변수 가 어디 에 있 는 지 정의 하면 다음 함수 들 은 각자 의 기능 을 수행 합 니 다 start stop 등등.
    스 크 립 트 매개 변수 분석
    마지막 부분 은 다 중 분기 의 구조 로 입력 한 첫 번 째 매개 변수 에 따라 어떤 함 수 를 실행 할 지 결정 합 니 다.
    총결산
    보아하니 데 몬 의 유지보수 에 필요 한 것 이 꽤 많은 것 같 습 니 다. 불 러 올 설정 이 없 으 면 두 개의 파일 이 필요 합 니 다. 하 나 는 / etc / init / myservice 이 고, 또 하 나 는 필요 한 pid 파일 입 니 다. / run / myservice. pid 는 그대로 쓰 면 OK 일 것 입 니 다. 구체 적 인 실행 은 시스템 내부 에 맡 길 수 있 는 명령 입 니 다.
    파일 원본 - nginx 서비스 스 크 립 트 / etc / init. d / nginx
    #!/bin/sh
    
    ### BEGIN INIT INFO
    # Provides:   nginx
    # Required-Start:    $local_fs $remote_fs $network $syslog $named
    # Required-Stop:     $local_fs $remote_fs $network $syslog $named
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: starts the nginx web server
    # Description:       starts nginx using start-stop-daemon
    ### END INIT INFO
    
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    DAEMON=/usr/sbin/nginx
    NAME=nginx
    DESC=nginx
    
    # Include nginx defaults if available
    if [ -r /etc/default/nginx ]; then
        . /etc/default/nginx
    fi
    
    test -x $DAEMON || exit 0
    
    . /lib/init/vars.sh
    . /lib/lsb/init-functions
    
    # Try to extract nginx pidfile
    PID=$(cat /etc/nginx/nginx.conf | grep -Ev '^\s*#' | awk 'BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1)
    if [ -z "$PID" ]
    then
        PID=/run/nginx.pid
    fi
    
    # Check if the ULIMIT is set in /etc/default/nginx
    if [ -n "$ULIMIT" ]; then
        # Set the ulimits
        ulimit $ULIMIT
    fi
    
    #
    # Function that starts the daemon/service
    #
    do_start()
    {
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON --test > /dev/null \
            || return 1
        start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON -- \
            $DAEMON_OPTS 2>/dev/null \
            || return 2
    }
    
    test_nginx_config() {
        $DAEMON -t $DAEMON_OPTS >/dev/null 2>&1
    }
    
    #
    # Function that stops the daemon/service
    #
    do_stop()
    {
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PID --name $NAME
        RETVAL="$?"
    
        sleep 1
        return "$RETVAL"
    }
    
    #
    # Function that sends a SIGHUP to the daemon/service
    #
    do_reload() {
        start-stop-daemon --stop --signal HUP --quiet --pidfile $PID --name $NAME
        return 0
    }
    
    #
    # Rotate log files
    #
    do_rotate() {
        start-stop-daemon --stop --signal USR1 --quiet --pidfile $PID --name $NAME
        return 0
    }
    
    #
    # Online upgrade nginx executable
    #
    # "Upgrading Executable on the Fly"
    # http://nginx.org/en/docs/control.html
    #
    do_upgrade() {
        # Return
        #   0 if nginx has been successfully upgraded
        #   1 if nginx is not running
        #   2 if the pid files were not created on time
        #   3 if the old master could not be killed
        if start-stop-daemon --stop --signal USR2 --quiet --pidfile $PID --name $NAME; then
            # Wait for both old and new master to write their pid file
            while [ ! -s "${PID}.oldbin" ] || [ ! -s "${PID}" ]; do
                cnt=`expr $cnt + 1`
                if [ $cnt -gt 10 ]; then
                    return 2
                fi
                sleep 1
            done
            # Everything is ready, gracefully stop the old master
            if start-stop-daemon --stop --signal QUIT --quiet --pidfile "${PID}.oldbin" --name $NAME; then
                return 0
            else
                return 3
            fi
        else
            return 1
        fi
    }
    
    case "$1" in
        start)
            [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
            do_start
            case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
        stop)
            [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
            do_stop
            case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
        restart)
            log_daemon_msg "Restarting $DESC" "$NAME"
    
            # Check configuration before stopping nginx
            if ! test_nginx_config; then
                log_end_msg 1 # Configuration error
                exit 0
            fi
    
            do_stop
            case "$?" in
                0|1)
                    do_start
                    case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                    esac
                    ;;
                *)
                    # Failed to stop
                    log_end_msg 1
                    ;;
            esac
            ;;
        reload|force-reload)
            log_daemon_msg "Reloading $DESC configuration" "$NAME"
    
            # Check configuration before reload nginx
            #
            # This is not entirely correct since the on-disk nginx binary
            # may differ from the in-memory one, but that's not common.
            # We prefer to check the configuration and return an error
            # to the administrator.
            if ! test_nginx_config; then
                log_end_msg 1 # Configuration error
                exit 0
            fi
    
            do_reload
            log_end_msg $?
            ;;
        configtest|testconfig)
            log_daemon_msg "Testing $DESC configuration"
            test_nginx_config
            log_end_msg $?
            ;;
        status)
            status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $?
            ;;
        upgrade)
            log_daemon_msg "Upgrading binary" "$NAME"
            do_upgrade
            log_end_msg 0
            ;;
        rotate)
            log_daemon_msg "Re-opening $DESC log files" "$NAME"
            do_rotate
            log_end_msg $?
            ;;
        *)
            echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}" >&2
            exit 3
            ;;
    esac
    

    좋은 웹페이지 즐겨찾기