Scala for Backend Engineering & Functional Programming · Ders

Gözetim ve Hata Toleransı

Arızalardan düzgün biçimde kurtulabilen dayanıklı sistemler oluşturmak için Akka'nın gözetim stratejilerini keşfedin.

3. ders / 312 adım

Gözetim ve Hata Toleransı, CoddyKit'te ücretsiz bir Scala for Backend Engineering & Functional Programming dersidir. Bu, 3 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Scala for Backend Engineering & Functional Programming öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Scala for Backend Engineering & Functional Programming kursu toplamda 3 dersten oluşur.

Dayanıklı Sistemler Oluşturma

Eşzamanlı uygulamalarda işler ters gidebilir. Bir aktör çökebilir, bir ağ çağrısı başarısız olabilir veya bir veritabanına erişilemeyebilir.

Hata toleransı, bir sistemin bazı bölümleri başarısız olsa bile doğru şekilde çalışmaya devam edebilmesidir. Akka, bunu gerçekleştirmek için güçlü mekanizmalar sunar.

Üst ve Alt Aktör Denetimi

Akka aktörleri, aile ağacına çok benzeyen bir hiyerarşi içinde düzenlenir. Bir aktör başka bir aktör oluşturduğunda onun üst aktörü olur.

  • Üst aktörler, alt aktörlerini denetlemekten sorumludur.
  • Bir alt aktör başarısız olursa üst aktörü bir bildirim alır.
  • Ardından üst aktör, alt aktörün başarısızlığını nasıl ele alacağına karar verir. Buna denetim stratejisi denir.

Başarısızlık Durumunda Karar Verme

Bir aktör başarısız olduğunda üst aktörü dört yönergeden birini verebilir:

  • Resume: Aktör, başarısızlığı yok sayarak iletileri işlemeye devam eder.
  • Restart: Aktör durdurulur, yeniden oluşturulur ve ardından işlemeye devam eder. Dahili durumu sıfırlanır.
  • Stop: Aktör kalıcı olarak sonlandırılır.
  • Escalate: Başarısızlık, üst aktörün denetleyicisine (aktörün büyük üst aktörüne) aktarılır.

OneForOne Stratejisi

OneForOneStrategy, yaygın bir denetim stratejisidir. Bu stratejide yönerge yalnızca başarısız olan alt aktöre uygulanır.

Örneğin, bir alt aktör çökerse üst aktör yalnızca o alt aktörü yeniden başlatmaya karar verebilir; diğer alt aktörler etkilenmez.

OneForOne Uygulamada

OneForOneStrategy'yi görelim. Bir ArithmeticException oluştuğunda alt aktörü yeniden başlatan, diğer istisnalarda ise durduran bir üst aktör oluşturacağız.

import akka.actor._
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._

object OneForOneExample extends App {
  class Child extends Actor {
    override def preStart(): Unit = {
      println(s"Child ${self.path.name}: Started!")
    }
    override def postStop(): Unit = {
      println(s"Child ${self.path.name}: Stopped!")
    }
    override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
      println(s"Child ${self.path.name}: Pre-restart due to ${reason.getMessage}")
    }
    override def postRestart(reason: Throwable): Unit = {
      println(s"Child ${self.path.name}: Post-restart!")
    }
    def receive = {
      case "divideByZero" => throw new ArithmeticException("Oops, dividing by zero!")
      case "nullPointer"  => throw new NullPointerException("Something is null!")
      case msg            => println(s"Child ${self.path.name}: Received $msg")
    }
  }

  class Parent extends Actor {
    override val supervisorStrategy: SupervisorStrategy =
      OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.minute) {
        case _: ArithmeticException => Restart
        case _: NullPointerException => Stop
        case _                      => Escalate
      }

    val child = context.actorOf(Props[Child], "myChild")

    def receive = {
      case msg => child ! msg
    }
  }

  val system = ActorSystem("OneForOneSystem")
  val parent = system.actorOf(Props[Parent], "myParent")

  parent ! "Hello"
  parent ! "divideByZero" // Should cause a restart
  Thread.sleep(100)
  parent ! "Hello again"
  Thread.sleep(1000) // Give time for restart to complete

  parent ! "nullPointer"  // Should cause a stop
  Thread.sleep(100)
  parent ! "Hello after null" // This message will not be processed by child
  Thread.sleep(2000)

  system.terminate()
}

OneForOne'ı Gözlemleme

Önceki kodu çalıştırdınız mı? Şunlar oldu:

  • "divideByZero" gönderildiğinde alt aktör bir ArithmeticException fırlattı. Üst aktör Restart uyguladı. "Pre-restart" ve "Post-restart" günlüklerini gördünüz.
  • Ardından alt aktör "Hello again" iletisini işledi.
  • "nullPointer" gönderildiğinde alt aktör bir NullPointerException fırlattı. Üst aktör Stop uyguladı. Alt aktör sonlandırıldı.
  • "Hello after null" gönderildi; ancak alt aktör zaten durdurulmuş olduğundan bu iletiyi işleyemedi.

AllForOne Stratejisi

Bazen bir alt aktördeki başarısızlık, tüm kardeş alt aktörlerin de zarar görmüş veya doğru çalışamaz durumda olabileceği anlamına gelir.

AllForOneStrategy, yönergeyi yalnızca başarısız olan alt aktöre değil, denetleyicinin tüm alt aktörlerine uygular. Bir alt aktör başarısız olursa seçilen yönergeden tüm alt aktörler etkilenir.

AllForOne Uygulamada

Üst aktörümüzü AllForOneStrategy kullanacak şekilde değiştirelim. Bir alt aktördeki başarısızlığın kardeşini nasıl etkilediğine dikkat edin.

import akka.actor._
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._

object AllForOneExample extends App {
  class Child extends Actor {
    override def preStart(): Unit = {
      println(s"Child ${self.path.name}: Started!")
    }
    override def postStop(): Unit = {
      println(s"Child ${self.path.name}: Stopped!")
    }
    override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
      println(s"Child ${self.path.name}: Pre-restart due to ${reason.getMessage}")
    }
    override def postRestart(reason: Throwable): Unit = {
      println(s"Child ${self.path.name}: Post-restart!")
    }
    def receive = {
      case "fail" => throw new RuntimeException("Child failed!")
      case msg    => println(s"Child ${self.path.name}: Received $msg")
    }
  }

  class Parent extends Actor {
    override val supervisorStrategy: SupervisorStrategy =
      AllForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.minute) {
        case _: RuntimeException => Restart
        case _                   => Escalate
      }

    val childA = context.actorOf(Props[Child], "childA")
    val childB = context.actorOf(Props[Child], "childB")

    def receive = {
      case "failA" => childA ! "fail"
      case "msgB"  => childB ! "Hello from B"
      case msg     => println(s"Parent received: $msg")
    }
  }

  val system = ActorSystem("AllForOneSystem")
  val parent = system.actorOf(Props[Parent], "myParent")

  parent ! "msgB" // Child B receives a message
  Thread.sleep(100)

  parent ! "failA" // Child A fails, causing all children to restart
  Thread.sleep(1000)

  parent ! "msgB" // Child B (restarted) receives another message
  Thread.sleep(2000)

  system.terminate()
}

Karar Vericileri Özelleştirme

Karar verici işlevi kullanarak son derece özelleştirilmiş denetim mantığı oluşturabilirsiniz. Bu işlev bir Throwable (istisna) alır ve bir Directive döndürür.

Bu sayede istisnanın türüne, istisnaya neden olan iletiye veya hatta denetleyicinin durumuna dayalı karmaşık kurallar uygulayabilirsiniz.

Gelişmiş Denetim

Ayrıntılı denetim sağlamak için denetleyici stratejiniz içinde özel bir karar vericiyi nasıl tanımlayacağınız aşağıda gösterilmiştir.

import akka.actor._
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._

object CustomDeciderExample extends App {
  class Worker extends Actor {
    def receive = {
      case "criticalError" => throw new IllegalStateException("Critical state!")
      case "minorError"    => throw new IllegalArgumentException("Bad input!")
      case msg             => println(s"Worker: Received $msg")
    }
  }

  class Supervisor extends Actor {
    override val supervisorStrategy: SupervisorStrategy =
      OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 10.seconds) {
        case _: IllegalArgumentException => Resume // Minor error, just resume
        case _: IllegalStateException    => Restart // Critical, restart
        case _: Exception                => Stop    // Unknown, stop
        case _                           => Escalate // Others, escalate
      }

    val worker = context.actorOf(Props[Worker], "myWorker")

    def receive = {
      case msg => worker ! msg
    }
  }

  val system = ActorSystem("CustomDeciderSystem")
  val supervisor = system.actorOf(Props[Supervisor], "mySupervisor")

  supervisor ! "Hello"
  supervisor ! "minorError" // Should Resume
  Thread.sleep(100)
  supervisor ! "Hello again" // Worker should still be active
  Thread.sleep(500)

  supervisor ! "criticalError" // Should Restart
  Thread.sleep(100)
  supervisor ! "After critical" // Worker should be restarted
  Thread.sleep(1500)

  system.terminate()
}

Bilginizi Kontrol Edin

childA ve childB adlı iki alt aktörü denetleyen bir üst aktörü inceleyin. Üst aktör, tüm istisnalar için Restart yönergesini kullanan bir AllForOneStrategy kullanıyor.

childA bir istisna fırlatırsa ne olur?

Özet: Hata Toleransı

Harika iş çıkardınız! Bu derste Akka'nın güçlü denetim mekanizmalarını öğrendiniz:

  • Denetim Hiyerarşisi: Üst aktörler, alt aktörleri denetler.
  • Yönergeler: Resume, Restart, Stop, Escalate.
  • OneForOneStrategy: Yönergeleri yalnızca başarısız olan alt aktöre uygular.
  • AllForOneStrategy: Yönergeleri tüm alt aktörlere uygular.
  • Özel Karar Vericiler: Başarısızlıkların ele alınmasını ayrıntılı şekilde denetlemek için kullanılır.

Bu araçlar, Akka Aktörleri ile sağlam ve dayanıklı eşzamanlı uygulamalar oluşturmak için gereklidir!

Başlamak ücretsiz

Yapay zeka eğitmeniyle Scala öğren — ücretsiz

Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.

Kurslar
39
Dersler
143

Sıkça Sorulan Sorular

“Gözetim ve Hata Toleransı” dersi ücretsiz mi?

Evet — “Gözetim ve Hata Toleransı” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Scala for Backend Engineering & Functional Programming kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Scala for Backend Engineering & Functional Programming kursu toplamda 3 dersten oluşur.

“Gözetim ve Hata Toleransı” dersinde ne öğreneceğim?

Arızalardan düzgün biçimde kurtulabilen dayanıklı sistemler oluşturmak için Akka'nın gözetim stratejilerini keşfedin. Scala for Backend Engineering & Functional Programming ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Scala for Backend Engineering & Functional Programming öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Scala for Backend Engineering & Functional Programming, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 3 dersinin 3. dersidir.

“Gözetim ve Hata Toleransı” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Scala for Backend Engineering & Functional Programming dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Scala for Backend Engineering & Functional Programming dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Akka Aktör Modelinin Temelleri
  2. Aktör Sistemleri Tasarlama
  3. Gözetim ve Hata Toleransı
← Scala for Backend Engineering & Functional Programming Sayfasına Dön