Incapient instabilidade no Microsoft Task Scheduler?

3

Contexto: Microsoft Azure; Windows Server 2012 R2.

Eu tenho um pequeno número de tarefas no Agendador. Todos são marcados, na guia Configurações, como "Se a tarefa já estiver em execução, aplica-se a seguinte regra: 'Não iniciar uma nova instância'".

Isso está bem por alguns dias. Em seguida, o agendador parece iniciar uma nova instância de cada tarefa enquanto uma está em execução. Estes aparecem no Gerenciador de Tarefas ao lado da tarefa já em execução, mas marcados como "Suspenso".

Este parece ser um sinal geral de instabilidade do sistema. Pouco depois desse comportamento, o SQL Server começa a se comportar mal.

Eu estou no processo de escrever um script de manutenção (que terá que usar o agendador também, mais é a pena) que contará instâncias de aplicações de produção e enviará ao time de desenvolvimento um sms se houver mais de um na memória (um correndo, um suspenso.) Essa é a solução alternativa de curto prazo. Uma correção a longo prazo seria melhor.

Alguém encontrou algo assim e, em caso afirmativo, qual é a correção?

Resposta a sugestões

Eu poderia colocar

var currProcName = Process.GetCurrentProcess().ProcessName;
if (Process.GetProcessesByName(currProcName).Length > 1)
{
    Warn($"An instance of {currProcName} is already running. Only one instance of this application is allowed.");
    return;
}

ou seu equivalente em todos os EXEs. No entanto, na configuração atual, isso nunca Emitir um aviso porque a segunda instância do EXE não é executado como tal, mas aparece no Gerenciador de tarefas como "Suspenso".

Permitir que o Agendador inicie um trabalho quer já esteja em execução ou não e exija que o próprio EXE demore se ele deve ser executado ou não parece um tanto ineficiente, pois requer que cada EXE seja iniciado e possivelmente morrer a cada minuto, em vez de permitir o Agendador para determinar se um lançamento é necessário ou não.

Ter cerca de 20 tarefas sendo agendadas, algumas a cada minuto, algumas a cada 5, algumas a cada 60.

Respostas às perguntas feitas nos comentários # 1

P: O que você está executando exatamente com o Agendador de Tarefas como um script em lote, um arquivo exe, um script do PowerShell ou o quê?

A: apenas EXEs, por exemplo,

<Actions Context="Author">
  <Exec>
    <Command>Handler.exe</Command>
    <WorkingDirectory>C:\Web\Project</WorkingDirectory>
  </Exec>
</Actions>

P: Como você tem a configuração da tarefa nas opções do agendador?

A: Configurações de amostra do arquivo XML:

  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>

Triggers de amostra do arquivo XML

<Triggers>
  <CalendarTrigger>
    <Repetition>
      <Interval>PT1M</Interval>
      <Duration>P1D</Duration>
      <StopAtDurationEnd>false</StopAtDurationEnd>
    </Repetition>
    <StartBoundary>2016-03-09T14:20:00</StartBoundary>
    <ExecutionTimeLimit>PT30M</ExecutionTimeLimit>
    <Enabled>true</Enabled>
    <ScheduleByDay>
      <DaysInterval>1</DaysInterval>
    </ScheduleByDay>
  </CalendarTrigger>
</Triggers>

Respostas às perguntas feitas nos comentários # 2

Q: Você desativou e ativou essas tarefas?

R: As tarefas são desativadas regularmente e reativadas quando as atualizações são aplicadas.

P: As tarefas foram importadas de um arquivo XML?

A: A tarefa original (em outro servidor) foi criada usando a GUI. O resultado foi exportado para XML, movido para o servidor atual, editado e importado.

P: Se você recriar a tarefa, isso corrige o problema?

A: Não.

P: A tarefa termina com um código de saída?

A: Se você quer dizer "a tarefa termina com um Environment.Exit (n)?" então sim. No entanto, o valor não é verificado, pois a tarefa é definida como um EXE, e não como parte de um CMD maior.

P: É possível que a tarefa agendada tenha terminado exatamente quando a nova tarefa deve começar?

A: Como eu estabeleceria isso?

P: Duas instâncias da mesma tarefa em execução explicam a instabilidade que você está vendo?

R: Não tenho certeza se entendi a pergunta. Em nenhum momento permitimos que duas instâncias sejam executadas simultaneamente. A situação atual é que, no momento de sua escolha, o Windows permite que uma instância seja executada e permite que outra seja executada, mas no modo "suspenso". Curiosamente, nossa experiência atual é que uma tarefa suspensa não pode ser terminada. Apenas uma tarefa em execução pode ser finalizada.

    
por bugmagnet 06.12.2017 / 08:30

2 respostas

0

Agendador de tarefas e condições ociosas

Parece haver duas maneiras de configurar um trabalho Agendador de Tarefas em relação às Condições Ociosas .

  1. Se o StopOnIdleEnd estiver definido como true , o RestartOnIdle também deverá ser true se o resultado desejado for terminar e reiniciar um tarefa .

    Cycling Idle Condition

    If the computer is cycling in and out of the idle state, you can terminate and restart the task using the following idle conditions.

    To terminate and restart a task, both properties and elements must be set to True:

    • To terminate the task when the idle condition ends, set the StopOnIdleEnd property or the StopOnIdleEnd element to True.

    • To restart the task when the computer cycles into the idle condition again, set the RestartOnIdle property or the RestartOnIdle element to True.


    Example Config

    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>true</RestartOnIdle>
    </IdleSettings>
    

    Ambos devem ser definidos como True .

  1. Se o resultado desejado for não interromper a execução da tarefa em uma condição ociosa , convém garantir o RestartOnIdle e o StopOnIdleEnd estão definidos para false .

    Example Config

    <IdleSettings>
      <StopOnIdleEnd>false</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    

Ambos devem ser definidos como False .

    
por 18.12.2017 / 05:35
0

Minha opinião sobre o problema é que isso é causado pela linha:

<StopOnIdleEnd>true</StopOnIdleEnd>

Aqui está o que eu teorizo é o seu cenário:

  • O processo pára em estado de espera em uma chamada do kernel. Neste estado, não pode ser parado.
  • O computador entrou no estado ocioso e saiu dele.
  • O Agendador de Tarefas tentou interromper o processo, mas só conseguiu suspendê-lo no estado zumbi (parou, mas não pode terminar).
  • A tarefa sendo marcada como finalizada, o Agendador de Tarefas iniciou uma nova.
  • Como a tarefa original talvez estivesse no meio de uma transação SQL e ainda pode conter bloqueios, o comportamento do banco de dados SQL foi prejudicado.

A solução deve ser definir StopOnIdleEnd para false . Não há motivo para encerrar a tarefa porque o computador entrou o estado ocioso, por mais breve que seja. Na verdade, é uma péssima ideia parar brutalmente qualquer tarefa que seja conectado a um servidor SQL, porque deixa a transação em andamento incompleta e nem mesmo revertida.

    
por 18.12.2017 / 10:42