2012-08-04 3 views
7

배치 파일에 여러 가지 시작 작업이 있습니다. 특히 IIS를 구성하기 위해 IIS의 appcmd.exe을 호출합니다. Azure의 스타트 업 작업은 웬일인지 롤이 재시작 될 경우 같은 결과로 반복적으로 실행될 수있는 멱등 원 (isempotent)으로되어 있습니다. 안타깝게도 IIS 구성 명령 중 많은 부분이 두 번째로 실패합니다. 예를 들어 후속 실행시 처음으로 구성 노드를 삭제하기 때문입니다.시작 작업을 멱등환으로 만드는 방법은 무엇입니까?

제 질문은 이러한 시작 작업을 멱등환으로 만드는 방법입니다. appcmd.exe에서 오류를 발생시키지 않는 방법이 있습니까? 셸이 오류를 잡을 수있는 방법이 있습니까? Azure 프레임 워크가 오류를 무시하도록하는 방법이 있습니까?

다음은 시작 작업의 예입니다. 이것은 모두 명령 파일 configiis.cmd에 들어 있습니다.

@REM Enable IIS compression for application/json MIME type 
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json',enabled='True']" /commit:apphost 
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost 

@REM Set IIS to automatically start AppPools 
%windir%\system32\inetsrv\appcmd.exe set config -section:applicationPools -applicationPoolDefaults.startMode:AlwaysRunning /commit:apphost 

@REM Set IIS to not shut down idle AppPools 
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00 /commit:apphost 

@REM But don't automatically start the AppPools that we don't use, and do shut them down when idle 
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools "/[name='Classic .NET AppPool'].startMode:OnDemand" "/[name='Classic .NET AppPool'].autoStart:False" "/[name='Classic .NET AppPool'].processModel.idleTimeout:00:01:00" /commit:apphost 
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools "/[name='ASP.NET v4.0'].startMode:OnDemand" "/[name='ASP.NET v4.0'].autoStart:False" "/[name='ASP.NET v4.0'].processModel.idleTimeout:00:01:00" /commit:apphost 
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools "/[name='ASP.NET v4.0 Classic'].startMode:OnDemand" "/[name='ASP.NET v4.0 Classic'].autoStart:False" "/[name='ASP.NET v4.0 Classic'].processModel.idleTimeout:00:01:00" /commit:apphost 


@REM remove IIS response headers 
%windir%\system32\inetsrv\appcmd.exe set config /section:httpProtocol /-customHeaders.[name='X-Powered-By'] 
+0

사용하지 않는 AppPools을 자동으로 시작하지 못하도록하는 행이 제대로 작동하지 않을 수도 있습니다. 이름으로 'Classic .NET AppPool'등을 사용하는 대신 Clr2ClassicAppPool 등을 사용해야합니다. –

+0

실제로 그 이름은 잘 작동하지만 약간 따옴표로 묶어야합니다. 위의 코드를 업데이트했습니다. 누군가 나중에 살펴볼 때를 대비하여. –

답변

4

@ Syntaxc4의 대답 외에도 : 로컬에서 현재 위치 정보 (파일) 사용을 고려하십시오. 스크립트에서 알려진 파일 (생성 한 파일)이 있는지 확인하십시오. 존재하지 않으면 시작 스크립트를 통해 이동 경로 파일을 만듭니다. 다음 번에 VM이 시작될 때, breadcrumb 파일의 존재를 다시 확인하고, 존재한다면 cmd 파일을 종료하십시오. 탐색 경로 파일이 사라지면 이는 일반적으로 VM이 다른 위치 (다른 인스턴스의 새 인스턴스 또는 다시 인스턴스 된 인스턴스)로 다시 구성되었음을 의미하며 IIS 구성이 필요할 것입니다.

+0

좋은 생각 같습니다. .cmd 스크립트에서이를 구현하는 방법에 대한 아이디어가 있습니까? 나는 결국 그것을 이해할 수있을 것이라고 확신하지만, 당신이 전에 이런 식으로했을 수도있는 것처럼 들린다. –

+0

누군가가 이것을 나중에 읽는 경우, 다른 답변에서 이것을 구현하는 코드를 추가했습니다. –

3

조건 설정을 삭제하기 전에 구성 설정이 있는지 확인해야합니다 (조건부 논리 추가). 이것은에 의해 달성 될 수있다 :

'Appcmd.exe에 목록 구성 -details'당신에게, 비교할 출력의 길이 또는 실제 값을 수 뭔가를 줄 것이다 반환 값을 캡처

.

2

David Makogon의 제안을 바탕으로 각 .cmd 파일의 맨 위에 다음을 추가했습니다. 이것은 트릭을 할 것으로 보인다. 실행 파일과 동일한 디렉토리에 플래그 파일 (David가 breadcrumb 파일이라고 부른 것)을 생성 한 다음 후속 실행에서 확인합니다.

@REM A file to flag that this script has already run 
@REM because if we run it twice, it errors out and prevents the Azure role from starting properly 
@REM %~n0 expands to the name of the currently executing file, without the extension 
SET FLAGFILE=c:\%~n0-flag.txt 

IF EXIST "%FLAGFILE%" (
    ECHO %FLAGFILE% exists, exiting startup script 
    exit /B 
) ELSE (
    date /t > %FLAGFILE% 
) 
+0

플래그 파일 이름에도'% ComputerName %'을 넣어야합니다! .. 유용 할거야! – wasatchwizard

+0

왜 유용할까요? –

3

이제 MSDN에는 APPCMD에서 오류 코드를 처리하여이 작업을 수행하는 훌륭한 지침이 포함되어 있습니다.

IF %ERRORLEVEL% EQU 183 DO VERIFY > NUL 

을하고 허용 오류 코드를 무시 :

http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx

은 기본적으로 어떤 APPCMD 명령어 수술 후, 다음을 수행 할 수 있습니다.

+0

아주 좋습니다. 그것이 "올바른"방법일지도 모르는 것처럼 보입니다. 너무 나쁘면 오류 처리가 너무 자세합니다. –

+1

MSDN 기사에 오류가있는 것 같습니다. 'IF'명령의 구문이 다음과 같기 때문에 'DO'가 과도합니다. 'IF [/ I] string1 compare-op string2 명령'입니다. DO 키워드는 'FOR'명령에만 적용됩니다. 따라서 올바른 명령은 다음과 같아야합니다 : 'IF % ERRORLEVEL % EQU 183 VERIFY> NUL'. 원본이 스크립트가 전혀 시작되지 못하게 막는 동안이 스크립트는 저에게 효과적이었습니다. – Vertigo

0

list 명령 끝에 /config:* /xml을 사용하는 것이 좋습니다. 내가 어떻게 iis idempotent를 만드는지에 대한 더 자세한 정보는 다음을 참고하십시오 : https://github.com/opscode-cookbooks/iis Chef는 다중 구성 관리 플랫폼 중 하나이며 현재 설정을 나열하여 멱등 원을 수행하는 코드 (루비로만 표시) 만보고 싶습니다. 변경 요청을받은 설정과 비교합니다.