Sık karşılaşılan Dayanıklı Görev SDK'sı sorunlarını giderme

Bu makale, taşınabilir Dayanıklı Görev SDK'ları ile uygulama oluştururken karşılaşılan yaygın sorunları tanılamanıza ve düzeltmenize yardımcı olur. Aşağıdaki listede senaryonuzu bulun ve sorunu tanılamak ve çözmek için bağlantılı adımları izleyin.

Yaygın senaryolar

Bağlantı ve kurulum

Orkestrasyonlar

Etkinlikler

gRPC

Günlük ve teşhis

Dile özgü

Bu SDK'lar Durable Görev Zamanlayıcı arka ucuna bağlanır ve Azure Container Apps, Kubernetes ve VM'ler dahil olmak üzere herhangi bir barındırma platformunda çalışır.

Uyarı

Bu kılavuz taşınabilir Dayanıklı Görev SDK'larını kapsar. Dayanıklı Görev Zamanlayıcı hizmetine özgü sorunlar için bkz. Dayanıklı Görev Zamanlayıcı sorunlarını giderme. Dayanıklı İşlevler uzantısına özgü sorunlar için bkz. Dayanıklı İşlevler sorun giderme kılavuzu.

Tip

Dayanıklı Görev Zamanlayıcı izleme panosu düzenleme durumunu incelemek, yürütme geçmişini görüntülemek ve hataları tanımlamak için kullanışlıdır. Sorun gidermeyi hızlandırmak için bu kılavuzun yanında kullanın.

Sorununuzu bulun

Hata iletisi veya belirti Bölüm
connection refused veya failed to connect başlangıçta Öykünücü çalışmıyor veya ulaşılamıyor
Başlangıçta bağlantı dizesi ayrıştırma hataları veya kimlik doğrulama hataları Bağlantı dizesi biçimi yanlış
Çalışan bağlanıyor ancak orkestrasyonlar başlamıyor Görev hub'ı yok
401 Unauthorized veya Azure kimlik/rol hataları Azure üzerinde Kimlik tabanlı kimlik doğrulama hataları
Orkestrasyon "bekleme durumunda" takıldı Orkestrasyon "Beklemede" durumu kaldı
Düzenleme "Çalışıyor" içinde takıldı Orkestrasyon "Çalışıyor" durumunda takıldı
Yeniden yürütme hataları, sonsuz döngüler veya beklenmeyen davranış Belirleyici olmayan düzenleyici kodu
Tür uyuşmazlığı veya JSON serileştirme hataları Serileştirme ve deserilize etme hataları
activity not found Etkinlik bulunamadı
RESOURCE_EXHAUSTED veya message too large gRPC ileti boyutu sınırı aşıldı
CANCELLED: Cancelled on client kapatma sırasında Kapatma sırasında akış iptal hataları
CS0419 / VSTHRD105 uyarılar derlemeyi bozar Kaynak oluşturucu uyarıları derleme sürecini bozar (C#)
OrchestratorBlockedException (Java) OrchestratorBlockedException (Java)
retry_policy (Python) kullanılırken yararlı olmayan hata Retry ilkesi max_retry_interval gerektirir (Python)

Bağlantı ve kurulum sorunları

Öykünücü çalışmıyor veya ulaşılamıyor

Uygulamanız başlangıçta "bağlantı reddedildi" veya "bağlanamadı" gibi bir bağlantı hatasıyla başarısız olursa Dayanıklı Görev Zamanlayıcı öykünücüsunun çalışıp çalışmadığını ve erişilebilir olduğunu denetleyin.

  1. Emülatör Docker container'ın çalıştığını denetleyin:

    docker ps | grep durabletask
    
  2. Bağlantı noktası eşlemelerinin doğru olduğunu doğrulayın. Öykünücü iki bağlantı noktasını kullanıma sunar:

    • 8080—gRPC uç noktası (uygulamanız tarafından kullanılır)
    • 8082—Pano Kullanıcı Arabirimi

    Özel port eşlemesi kullanıyorsanız, bağlantı dizesini 8080 kapsayıcı portuyla eşleşen ana makine portuna uygun şekilde güncelleştirin.

  3. gRPC uç noktasına bağlantıyı test edin:

    curl -v http://localhost:8080
    

    Bağlantı reddetme, kapsayıcının çalışmadığını veya bağlantı noktası eşlemesinin yanlış olduğunu gösterir.

Bağlantı dizesi biçimi yanlış

Bağlantı dizesi hataları, başlangıç hatalarının yaygın bir nedenidir. Bağlantı dizenizin beklenen biçime uygun olup olmadığını denetleyin.

Yerel geliştirme (öykünücü):

Endpoint=http://localhost:8080;Authentication=None

Azure (yönetilen kimlik):

Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity

Azure (kullanıcı tarafından atanan yönetilen kimlik):

Endpoint=https://<scheduler-name>.durabletask.io;Authentication=ManagedIdentity;ClientID=<client-id>

Yaygın hatalar:

  • Yerel öykünücü için kullanma https (öykünücü kullanır http)
  • Azure uç noktaları için http kullanma (Azure https gerektirir)
  • Parametresini atlama Authentication
  • gRPC bağlantı noktası (8082) yerine pano bağlantı noktasını (8080) kullanma

İstemci veya çalışan bağlanamıyor

İstemcinizin ve çalışanınızın doğru bağlantı dizesi ve görev merkezi adıyla yapılandırılıp yapılandırılmadığını denetleyin.

using Microsoft.DurableTask.Client.AzureManaged;
using Microsoft.DurableTask.Worker.AzureManaged;

var connectionString = "Endpoint=http://localhost:8080;Authentication=None";

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddOrchestrator<MyOrchestrator>();
        registry.AddActivity<MyActivity>();
    })
    .UseDurableTaskScheduler(connectionString);

builder.Services.AddDurableTaskClient()
    .UseDurableTaskScheduler(connectionString);

Görev hub'ı yok

Orkestrasyonlarınız başlatılamıyorsa veya çalışan bağlandığında ancak işleri işleyemiyorsa, görev hub'ı zamanlama biriminde olmayabilir. Öykünücü genellikle ortam değişkenini kullanarak görev hub'larını DTS_TASK_HUB_NAMES otomatik olarak oluşturur.

Öykünücünün doğru görev hub'ı adıyla başlatıldığını denetleyin:

docker run -d -p 8080:8080 -p 8082:8082 \
  -e DTS_TASK_HUB_NAMES="my-taskhub" \
  mcr.microsoft.com/dts/dts-emulator:latest

Azure barındırılan zamanlayıcılar için Azure CLI kullanarak görev hub'ını oluşturun:

az durabletask taskhub create \
  --resource-group <resource-group> \
  --scheduler-name <scheduler-name> \
  --name <taskhub-name>

Azure kimlik tabanlı kimlik doğrulama hataları

Uygulamanız yerel olarak çalışıyorsa ancak Azure dağıtıldığında başarısız oluyorsa, sorun büyük olasılıkla kimlik doğrulamasıyla ilgilidir:

  1. Uygulamanıza bir yönetilen kimlik atandığını (sistem tarafından atanan veya kullanıcı tarafından atanan) kontrol edin.
  2. Kimliğin zamanlayıcı kaynağında veya belirli görev hub'larında Dayanıklı Görev Verileri Katkıda Bulunanı rolüne sahip olup olmadığını denetleyin.
  3. bağlantı dizesi doğru Authentication değerini (ManagedIdentity) kullandığından emin olun. Python DefaultAzureCredential() örneğini bağlantı dizesi kullanmak yerine token_credential parametresi olarak geçirin.
  4. Kullanıcı tarafından atanan kimlikler için, bağlantı dizesi içindeki ClientID'nin kimliğin istemci kimliğiyle eşleştiğinden emin olun.

Ayrıntılı yönergeler için bkz. Dayanıklı Görev Zamanlayıcı için Yönetilen Kimliği Yapılandırma.

Düzenleme sorunları

Orkestrasyon "Beklemede" durumunda takıldı

"Beklemede" durumundaki düzenleme, zamanlandığını ancak bir çalışanın bunu almadığını gösterir. Aşağıdaki öğeleri denetleyin:

  • İşçi çalışıyor. Çalışan işleminizin çalıştığından ve düzenlemenin zamanlandığı görev hub'ına bağlı olduğundan emin olun.
  • Görev merkezi adı eşleşiyor. Çalışanın ve istemcinin aynı görev merkezi adını referans aldığını kontrol edin. Uyuşmazlık, çalışanın farklı bir görev hub'ını yoklamasına neden olur.
  • Orchestrator, kayıtlıdır. Zamanlama sırasında referans verilen yönlendirici işlevi veya sınıfı çalışana kaydedilmelidir.

Orchestrator sınıfının başlatma sırasında çalışana kaydedildiğini denetleyin. Kaynak oluşturucuları ([DurableTask] öznitelik) kullanıyorsanız, kayıt otomatiktir. Aksi takdirde el ile kaydolun:

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddOrchestrator<MyOrchestrator>();
        registry.AddActivity<MyActivity>();
    })
    .UseDurableTaskScheduler(connectionString);

Orkestrasyon "Çalışıyor" durumunda takıldı

Orkestrasyonun "Çalışıyor" durumunda takılması, genellikle tamamlanmamış bir görevi beklediği anlamına gelir. Tanılamak için Dayanıklı Görev Zamanlayıcı panosunu açın ve düzenlemenin yürütme geçmişini inceleyin. Son tamamlanan olayı arayın; sıradaki bir sonraki olay engelleyen olaydır.

Yaygın nedenler:

  • Etkinlik kaydedilmedi. Orkestrasyon, çalışana kayıtlı olmayan bir etkinlik adını çalıştırır. Panoda karşılık gelen TaskScheduledolmayan bir TaskCompleted olay gösterilir. Etkinlik adının düzenleyici kodunuzla çalışan kaydı arasında eşleşip eşleşmediğini denetleyin (bkz . Etkinlik bulunamadı).
  • Harici bir olay bekleniyor. Orkestrasyon waitForExternalEvent çağırıyor ve olay henüz tetiklenmedi. Panoda bir EventRaised olayın beklendiği ancak eksik olduğu gösterilir. Etkinlik adını ve gönderenin doğru orkestrasyon örneği kimliğini hedeflediğini doğrulayın.
  • Dayanıklı bir zamanlayıcı bekleniyor. Orkestrasyon, süresi henüz dolmamış bir zamanlayıcı oluşturur. Panoda bir TimerCreated etkinlik gösteriliyor. Süreölçerin tetiklemesini bekleyin veya sürenin beklenenden uzun olup olmadığını denetleyin.
  • Etkinlik işlenmeyen bir özel durum fırlatır. Panoda bir TaskFailed etkinlik gösteriliyor. Özel durum iletisi ve yığın izleme için hata ayrıntılarını denetleyin.

Belirleyici olmayan düzenleyici kodu

Orchestrator kodu deterministik olmalıdır. Belirsiz kod beklenmeyen davranışlara, sonsuz döngülere veya hatalara neden olan yeniden yürütme hatalarına neden olur. Geçerli saati, rastgele sayıları, GUID'leri veya G/Ç'yi (HTTP çağrıları gibi) doğrudan düzenleyici kodunda kullanmayın. Bağlam tarafından sağlanan alternatifleri kullanın veya etkinlikler için temsilci belirleyin.

// ❌ Wrong - non-deterministic
var now = DateTime.UtcNow;
var id = Guid.NewGuid();
var data = await httpClient.GetAsync("https://example.com/api");

// ✅ Correct - deterministic
var now = context.CurrentUtcDateTime;
var id = context.NewGuid();
var data = await context.CallActivityAsync<string>("FetchData");

Serileştirme ve deserileştirme hataları

Düzenleme girişleri, çıkışları veya etkinlik sonuçları için kullanılan türler çağıran ve çağrılan arasında eşleşmediğinde serileştirme hataları oluşur. Bu hatalar, düzenleme geçmişinizde beklenmeyen null değerler JsonExceptionveya tür atama hataları olarak görünebilir.

Nasıl tanılama yapılır?:

  1. Dayanıklı Görev Zamanlayıcı panosunu açın ve düzenleme geçmişini inceleyin. Başarısız olan etkinliklerin Input ve Result alanlarına bakın.
  2. Düzenleyici tarafından beklenen türün etkinlik tarafından döndürülen türle eşleştigini doğrulayın. Örneğin, etkinlik bir string döndürür ancak düzenleyici bir intbeklerse seri durumdan çıkarma başarısız olur.
  3. Serileştirilemeyen türleri denetleyin. JSON'a serileştirilemeyen özel türler (örneğin, döngüsel başvurulara sahip olan veya varsayılan oluşturucu içermeyen türler) sessizce başarısız olur veya özel durumlar oluşturur.

Bilinen sorun (Java):String doğrudan bir aktiviteye geçirmek çift tırnaklı metinlerle sonuçlanabilir (örneğin, "\"hello\"" yerine "hello"). Bu davranış bilinen bir sorundur. Sonucu açıkça dönüştürün veya sarmalayıcı nesneleri kullanın.

Tip

Düzenleme ve etkinlik girişleri ve çıkışları için basit veri türlerini (dizeler, sayılar, diziler ve düz nesneler veya POCO'lar/POCO'lar/veri sınıfları) kullanın. Özel serileştirme mantığıyla karmaşık türlerden kaçının.

Etkinlik sorunları

Etkinlik bulunamadı

Düzenleme "etkinlik bulunamadı" hatasıyla başarısız olursa, çalışana kaydedilen etkinlik adı düzenleme kodunda kullanılan adla eşleşmiyor.

.NET'da etkinlikler sınıf adına göre veya kaynak oluşturucularla [DurableTask] özniteliği kullanılarak kaydedilebilir. Etkinlik sınıfının çalışan kaydına dahil olduğunu doğrulayın:

builder.Services.AddDurableTaskWorker()
    .AddTasks(registry =>
    {
        registry.AddActivity<SayHello>();
    })
    .UseDurableTaskScheduler(connectionString);

Etkinliği bir düzenleyiciden çağırırken sınıf adını kullanın:

string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo");

Etkinlik hatası işleme

Bir etkinlik bir istisna oluşturduğunda, orchestrator bir TaskFailedException (veya dil eşdeğeri) alır. Bu özel durumu yakalayın ve kök nedeni bulmak için iç hata ayrıntılarını inceleyin. C# dilinde hata türüne ve iletiye erişmek ve ex.FailureDetails belirli özel durum türlerini denetlemek için kullanınIsCausedBy<T>().

Her dilde ayrıntılı hata işleme ve yeniden deneme ilkesi örnekleri için bkz. Hata işleme ve yeniden denemeler.

gRPC sorunları

gRPC ileti boyutu sınırı aşıldı

Veya RESOURCE_EXHAUSTEDmessage too large hatası görürseniz, düzenleme veya etkinlik girişi/çıkışı gRPC varsayılan ileti boyutu üst sınırı olan 4 MB'ı aşıyor.

Azaltma Önlemleri:

  • Girişlerin ve çıkışların boyutunu küçültün. Büyük yükleri Azure Blob Depolama gibi dış depolama alanlarına kaydedin ve sadece referansları iletin.
  • Büyük fan-out sonuçlarını alt orkestrasyonlar aracılığıyla işlenen daha küçük toplu işlemler halinde ayırın.

Kapatma sırasında veri akışı iptal hataları

Bir çalışanı durdururken hatalar görebilirsiniz CANCELLED: Cancelled on client . Bu hatalar genellikle zararsızdır ve çalışan ile zamanlayıcı arasındaki gRPC akışı kapatma sırasında kapandığı için oluşur. .NET, Python ve Java SDK'ları bu hataları dahili olarak işler.

JavaScript'teStream error Error: 1 CANCELLED: Cancelled on client çağrılırken SDK worker.stop() atabilir. Bu hata bilinen bir sorundur. Hata kapatma mantığınızı etkiliyorsa durdurma çağrısını bir try-catch içinde sarmalayın:

try {
  await worker.stop();
} catch (error) {
  // Ignore stream cancellation errors during shutdown
  if (!error.message.includes("CANCELLED")) {
    throw error;
  }
}

Kayıt tutma ve tanı

Ayrıntılı günlük yapılandırması

SDK işlemleri hakkında daha fazla ayrıntı elde etmek için, gRPC iletişimi ve orkestrasyon yeniden oynatma olayları da dahil olmak üzere günlük kayıt ayrıntı düzeyini artırın.

appsettings.json veya log yapılandırma dosyanızda:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.DurableTask": "Debug"
    }
  }
}

Düzenleme yenilemeleri sırasında yinelenen günlük kayıtlarını önlemek için yinelenemez günlük kaydediciler kullanın.

public override async Task<string> RunAsync(
    TaskOrchestrationContext context, string input)
{
    ILogger logger = context.CreateReplaySafeLogger<MyOrchestrator>();
    logger.LogInformation("Processing input: {Input}", input);
    // ...
}

Application Insights entegrasyonu

Üretim uygulamaları için Application Insights'ı Dayanıklı Görev SDK'sı uygulamanızdan telemetri toplayacak şekilde yapılandırın. Tümleştirme yaklaşımı barındırma platformunuza bağlıdır:

Barındırma platformu Kurulum yönergeleri
Azure Konteyner Uygulamaları Azure Container Apps'te Log Analytics ile günlükleri izleyin
Azure App Service Azure App Service'te uygulamalar için tanılama günlüğünü etkinleştir
Azure Kubernetes Service Azure Kubernetes Service'i izleme

Tanılama hakkında daha fazla bilgi için bkz . Dayanıklı Görev SDK'larında Tanılama.

Dile özgü sorunlar

C#

Kaynak oluşturucu uyarıları derlemeleri bozuyor

Eğer projenizde <TreatWarningsAsErrors>true</TreatWarningsAsErrors> kullanırsanız, Dayanıklı Görev kaynak oluşturucuları, derlemenizi bozabilecek uyarılar (CS0419, VSTHRD105) üretebilir. Bu belirli uyarıları gizleme:

<PropertyGroup>
  <NoWarn>$(NoWarn);CS0419;VSTHRD105</NoWarn>
</PropertyGroup>

Bu bilinen sorun GitHub'da takip edilmektedir ve yakında çıkacak bir sürümde ele alınacaktır.

Roslyn çözümleyicisi foreach döngüleri atar

Dayanıklı Görev Roslyn çözümleyicisi, orchestrator lambda kodu belirli bir ArgumentNullException döngüsünün içinde olduğunda bir foreach atabilir. Bu davranış, çalışma zamanı davranışını etkilemeyen bilinen bir sorundur . Düzeltmeyi almak için en son çözümleyici paketi sürümüne güncelleştirin.

Java

Gradle izni reddedildi hatası

macOS veya Linux'ta çalıştırma ./gradlew işlemi "izin reddedildi" hatasıyla başarısız olabilir. Dosyayı yürütülebilir hale getirerek bu hatayı düzeltin:

chmod +x gradlew

OrchestratorBlockedException

, OrchestratorBlockedException orchestrator kodu SDK'nın potansiyel olarak belirsiz olarak algılediği bir engelleme işlemi gerçekleştirdiğinde oluşur. Bu özel durum, orchestrator kodunun orchestrator kod kısıtlamalarını ihlal etmesini önlemeye yönelik bir korumadır.

Yaygın nedenler:

  • Orchestrator kodunda engelleyici bir dış API çağırma.
  • Thread.sleep()'yı doğrudan ctx.createTimer() yerine kullanma.
  • Orchestrator kodunda dosya veya ağ girdi/çıktı gerçekleştirme.

Tüm engelleme veya G/Ç işlemlerini etkinliklere taşıyın.

Python

Yeniden deneme ilkesi için max_retry_interval gerekir

Python'da bir retry_policy yapılandırırken, max_retry_interval parametresinin atlanması, nedenini açıkça belirtmeyen bir hataya neden olur. Her zaman belirtin max_retry_interval:

from datetime import timedelta
from durabletask import task

retry_policy = task.RetryPolicy(
    max_number_of_attempts=3,
    first_retry_interval=timedelta(seconds=5),
    max_retry_interval=timedelta(minutes=1),  # Required
)

WhenAllTask özel durum davranışı

Birden çok görevi paralel olarak çalıştırmak için kullandığınızda when_all , bir veya daha fazla görev başarısız olursa, özel durum davranışı beklentilerle eşleşmeyebilir. Yalnızca ilk özel durum oluşturulur ve kalan görev özel durumları kaybolabilir. Tam hata bilgilerine ihtiyacınız varsa tek tek görev sonuçlarını inceleyin:

tasks = [ctx.call_activity(process_item, input=item) for item in items]
try:
    results = yield task.when_all(tasks)
except TaskFailedError as e:
    # Only the first failure is raised
    # Check individual tasks for comprehensive error handling
    print(f"At least one task failed: {e}")

Destek alın

Sorular ve raporlama hataları için ilgili SDK'nın GitHub deposunda bir sorun açın. Bir hata bildirdiğinizde şunları ekleyin:

  • Etkilenen orkestrasyon örneği kimlikleri
  • Utc'de sorunu gösteren zaman aralığı
  • Uygulama adı ve dağıtım bölgesi (uygunsa)
  • SDK sürümü ve barındırma platformu
  • İlgili günlükler veya hata iletileri
SDK GitHub depo alanı
.NET microsoft/durabletask-dotnet
Java microsoft/durabletask-java
JavaScript microsoft/durabletask-js
Python microsoft/durabletask-python