Panduan Lengkap Spring Boot 4 · Pelajaran

Pemutus Litar dan Pengasingan Sekat

Lindungi panggilan hiliran dengan pemutus litar, sekat dan kaedah sandaran Resilience4j.

Pelajaran 2 daripada 413 langkah

Pemutus Litar dan Pengasingan Sekat ialah pelajaran Panduan Lengkap Spring Boot 4 percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Panduan Lengkap Spring Boot 4, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.

Mengapa Ketahanan Penting

Dalam sistem teragih, satu perkhidmatan hiliran yang perlahan atau gagal boleh menyebabkan gangguan menyeluruh secara berantai. Jika perkhidmatan anda terus memanggil kebergantungan yang tidak berfungsi, benang akan beratur sambil menunggu tamat masa sehingga seluruh aplikasi tidak lagi responsif.

Kejuruteraan ketahanan bertujuan mengehadkan kesan kegagalan. Dua corak asas ialah:

  • Pemutus Litar — hentikan panggilan kepada kebergantungan yang gagal buat sementara waktu dan gagal dengan pantas, bukannya menunggu.
  • Pemisah Sumber — asingkan sumber supaya satu kebergantungan yang terlebih beban tidak menghabiskan benang atau sambungan yang diperlukan oleh bahagian lain.

Dalam Spring Boot 4, kami melaksanakannya dengan Resilience4j, pustaka toleransi kerosakan yang ringan dan berfungsi, yang menggantikan Hystrix yang kini telah tamat hayat.

Menambahkan Resilience4j

Spring Boot 4 mengintegrasikan Resilience4j melalui pemula resilience4j-spring-boot3 (serasi dengan Boot 3.x/4.x) serta Spring AOP. Anotasi diaktifkan oleh aspek yang membalut panggilan kaedah anda.

Anda juga perlu memasukkan spring-boot-starter-aop dan, untuk metrik, spring-boot-starter-actuator bersama Micrometer.

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Cara Pemutus Litar Berfungsi

Pemutus litar ialah mesin keadaan yang memantau kadar kegagalan panggilan:

  • CLOSED — panggilan mengalir seperti biasa. Kegagalan direkodkan dalam tetingkap gelongsor.
  • OPEN — apabila kadar kegagalan melepasi ambang, pemutus litar dicetuskan. Panggilan seterusnya gagal serta-merta (tanpa panggilan hiliran) untuk tempoh menunggu.
  • HALF_OPEN — selepas tempoh menunggu, sebilangan kecil panggilan percubaan dibenarkan. Jika berjaya, keadaan kembali kepada CLOSED; jika gagal, kembali kepada OPEN.

Faedah utamanya: apabila kebergantungan terhenti, anda gagal dengan pantas dan bukannya menyekat benang dengan panggilan yang pasti gagal, di samping memberi ruang kepada kebergantungan itu untuk pulih.

Menganotasi Panggilan yang Dilindungi

Anotasi @CircuitBreaker membalut satu kaedah. name mengaitkannya dengan tika konfigurasi, manakala fallbackMethod menamakan kaedah yang akan dipanggil apabila panggilan gagal atau pemutus litar terbuka.

Kaedah sandaran mesti mempunyai tandatangan yang sama serta parameter Throwable (atau pengecualian yang lebih khusus) pada penghujungnya.

@Service
public class PaymentClient {

    private final RestClient restClient;

    public PaymentClient(RestClient restClient) {
        this.restClient = restClient;
    }

    @CircuitBreaker(name = "paymentService", fallbackMethod = "fallbackCharge")
    public ChargeResult charge(ChargeRequest request) {
        return restClient.post()
                .uri("/charges")
                .body(request)
                .retrieve()
                .body(ChargeResult.class);
    }

    private ChargeResult fallbackCharge(ChargeRequest request, Throwable t) {
        return ChargeResult.deferred(request.id(), "payment temporarily unavailable");
    }
}

Mengkonfigurasi Pemutus Litar

Kelakuan pemutus litar dilaraskan dalam application.yml. Anda mentakrifkan tetapan default dan penggantian bagi setiap instances berdasarkan name yang digunakan dalam anotasi.

  • sliding-window-type — COUNT_BASED atau TIME_BASED.
  • failure-rate-threshold — peratusan kegagalan untuk membuka pemutus litar.
  • wait-duration-in-open-state — tempoh kekal OPEN sebelum HALF_OPEN.
  • permitted-number-of-calls-in-half-open-state — bilangan panggilan percubaan yang dibenarkan.
  • slow-call-duration-threshold / slow-call-rate-threshold — anggap panggilan perlahan sebagai kegagalan.
resilience4j:
  circuitbreaker:
    configs:
      default:
        sliding-window-type: COUNT_BASED
        sliding-window-size: 20
        failure-rate-threshold: 50
        slow-call-duration-threshold: 2s
        slow-call-rate-threshold: 80
        wait-duration-in-open-state: 10s
        permitted-number-of-calls-in-half-open-state: 5
        automatic-transition-from-open-to-half-open-enabled: true
    instances:
      paymentService:
        base-config: default
        failure-rate-threshold: 40

Memodelkan Mesin Keadaan dalam Java Biasa

Untuk memahami logiknya, berikut ialah model ringkas tanpa rangka kerja tentang peralihan CLOSED kepada OPEN menggunakan tetingkap berasaskan kiraan. Secara konsepnya, inilah yang dilakukan oleh Resilience4j untuk anda di sebalik anotasi.

Jalankannya untuk melihat pemutus litar dicetuskan apabila kadar kegagalan melepasi ambang.

public class MiniBreaker {
    enum State { CLOSED, OPEN }
    static State state = State.CLOSED;
    static int window = 10, threshold = 50;
    static boolean[] results = new boolean[window];
    static int idx = 0, count = 0;

    static void record(boolean failure) {
        results[idx] = failure;
        idx = (idx + 1) % window;
        if (count < window) count++;
        int fails = 0;
        for (int i = 0; i < count; i++) if (results[i]) fails++;
        int rate = count == 0 ? 0 : (fails * 100 / count);
        if (count == window && rate >= threshold) state = State.OPEN;
    }

    public static void main(String[] args) {
        boolean[] calls = {false,true,false,true,true,false,true,true,false,true};
        for (boolean fail : calls) {
            record(fail);
            System.out.println((fail ? "FAIL" : "OK  ") + " -> state=" + state);
        }
    }
}

Mengira Rekod berbanding Mengabaikan Pengecualian

Bukan setiap pengecualian patut mencetuskan pemutus litar. 400 Bad Request bermaksud input anda salah, bukannya kebergantungan tidak sihat — mengiranya sebagai kegagalan akan membuka pemutus litar untuk trafik yang sah.

Gunakan record-exceptions untuk menyenaraikan objek yang boleh dilontar dan dikira sebagai kegagalan, serta ignore-exceptions untuk pengecualian yang patut diteruskan tanpa menjejaskan keadaan pemutus litar.

resilience4j:
  circuitbreaker:
    instances:
      paymentService:
        base-config: default
        record-exceptions:
          - java.io.IOException
          - java.util.concurrent.TimeoutException
          - org.springframework.web.client.HttpServerErrorException
        ignore-exceptions:
          - com.example.payments.InvalidCardException
          - org.springframework.web.client.HttpClientErrorException$BadRequest

Pengasingan Pemisah Sumber

Corak sekat (dinamakan sempena ruang kedap air pada kapal) mengehadkan bilangan panggilan serentak yang boleh digunakan oleh sesuatu kebergantungan, supaya satu perkhidmatan yang perlahan tidak menghabiskan seluruh himpunan utas.

Resilience4j menawarkan dua jenis:

  • SemaphoreBulkhead — mengehadkan panggilan serentak pada utas pemanggil. Ringan dan tidak memerlukan utas tambahan.
  • ThreadPoolBulkhead — menjalankan panggilan pada himpunan utas khusus yang mempunyai had serta baris gilir. Menyediakan pengasingan sebenar dan hanya berfungsi dengan pemulangan tak segerak (CompletableFuture).

Jika sekat penuh, panggilan ditolak dengan BulkheadFullException, yang boleh dikendalikan oleh kaedah sandaran anda.

Menggunakan Sekat

Anotasi @Bulkhead mengehadkan keserentakan. Dengan type = THREADPOOL, kaedah tersebut mesti memulangkan CompletableFuture dan dijalankan pada himpunan milik sekat itu sendiri. Anda boleh menggabungkannya dengan @CircuitBreaker — anotasi tersebut saling membentuk gubahan.

@Service
public class InventoryClient {

    private final RestClient restClient;

    public InventoryClient(RestClient restClient) {
        this.restClient = restClient;
    }

    @CircuitBreaker(name = "inventory", fallbackMethod = "fallbackStock")
    @Bulkhead(name = "inventory", type = Bulkhead.Type.THREADPOOL)
    public CompletableFuture<StockLevel> getStock(String sku) {
        return CompletableFuture.completedFuture(
            restClient.get().uri("/stock/{sku}", sku)
                      .retrieve().body(StockLevel.class));
    }

    private CompletableFuture<StockLevel> fallbackStock(String sku, Throwable t) {
        return CompletableFuture.completedFuture(StockLevel.unknown(sku));
    }
}

Mengkonfigurasi Sekat

Sekat semaphore dan sekat himpunan utas mempunyai bahagian konfigurasi yang berasingan.

  • bulkhead (semaphore): max-concurrent-calls dan max-wait-duration (tempoh panggilan menunggu permit sebelum ditolak).
  • thread-pool-bulkhead: max-thread-pool-size, core-thread-pool-size dan queue-capacity.

Tetapkan saiznya mengikut kapasiti sebenar kebergantungan: sekat yang lebih besar daripada kemampuan sistem hiliran akan menggagalkan tujuannya.

resilience4j:
  bulkhead:
    instances:
      paymentService:
        max-concurrent-calls: 25
        max-wait-duration: 50ms
  thread-pool-bulkhead:
    instances:
      inventory:
        core-thread-pool-size: 8
        max-thread-pool-size: 16
        queue-capacity: 20

Susunan, Kaedah Sandaran dan Kebolehlihatan

Apabila beberapa anotasi Resilience4j menghiasi satu kaedah, anotasi tersebut digunakan mengikut susunan aspek yang tetap (keutamaan tertinggi dahulu): Bulkhead → TimeLimiter → RateLimiter → CircuitBreaker → Retry. Oleh itu, Retry membungkus pemutus litar — panggilan yang masih gagal selepas cuba semula akan dikira terhadap pemutus tersebut.

Peraturan reka bentuk kaedah sandaran:

  • Pastikan kaedah sandaran pantas dan bebas daripada kesan sampingan; jangan panggil semula kebergantungan yang gagal.
  • Pulangkan data yang merosot tetapi sah (nilai cache, nilai lalai atau data yang dibaris gilir untuk kemudian).
  • Periksa Throwable untuk membezakan CallNotPermittedException (pemutus terbuka) daripada BulkheadFullException (terlebih muatan).

Actuator mendedahkan keadaan dan metrik di /actuator/circuitbreakers serta melalui Micrometer (resilience4j_circuitbreaker_state), supaya anda boleh membuat amaran bagi pemutus yang OPEN.

private ChargeResult fallbackCharge(ChargeRequest request, CallNotPermittedException ex) {
    return ChargeResult.deferred(request.id(), "breaker open");
}

private ChargeResult fallbackCharge(ChargeRequest request, BulkheadFullException ex) {
    return ChargeResult.rejected(request.id(), "system busy");
}

private ChargeResult fallbackCharge(ChargeRequest request, Throwable t) {
    return ChargeResult.deferred(request.id(), "payment unavailable");
}

Semakan Pantas

Uji pemahaman anda tentang pengasingan sekat.

Ulang Kaji

Anda telah mempelajari cara melindungi panggilan hiliran dalam Spring Boot 4 dengan Resilience4j:

  • Pemutus litar gagal dengan pantas melalui mesin keadaan CLOSED → OPEN → HALF_OPEN, yang dilaraskan menggunakan saiz tetingkap gelongsor, ambang kadar kegagalan dan panggilan perlahan, serta tempoh menunggu.
  • Gunakan record-exceptions / ignore-exceptions supaya ralat pelanggan (4xx) tidak mengaktifkan pemutus litar.
  • Sekat mengehadkan keserentakan — SemaphoreBulkhead pada utas pemanggil, ThreadPoolBulkhead untuk pengasingan sebenar dengan CompletableFuture.
  • Kaedah sandaran berkongsi tandatangan serta Throwable pada hujungnya; pulangkan data yang merosot tetapi sah dan jangan panggil semula kebergantungan yang gagal.
  • Susunan anotasi ialah Bulkhead → TimeLimiter → RateLimiter → CircuitBreaker → Retry; pantau keadaan melalui Actuator dan Micrometer.

Secara bersama, corak ini menghalang satu kebergantungan yang gagal daripada menjatuhkan keseluruhan perkhidmatan anda.

Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
21
Pelajaran
84

Soalan Lazim

Adakah pelajaran “Pemutus Litar dan Pengasingan Sekat” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Panduan Lengkap Spring Boot 4, termasuk “Pemutus Litar dan Pengasingan Sekat”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Pemutus Litar dan Pengasingan Sekat”?

Lindungi panggilan hiliran dengan pemutus litar, sekat dan kaedah sandaran Resilience4j. Anda berlatih Panduan Lengkap Spring Boot 4 menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Panduan Lengkap Spring Boot 4?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Panduan Lengkap Spring Boot 4 di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.

Berapa lamakah pelajaran “Pemutus Litar dan Pengasingan Sekat” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Panduan Lengkap Spring Boot 4 ini?

Ya. Setiap pelajaran Panduan Lengkap Spring Boot 4 menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Penyebaran Konteks dan Instrumentasi Rentang
  2. Pemutus Litar dan Pengasingan Sekat
  3. Pengehadan Kadar, Percubaan Semula dan Pengehad Masa
  4. Menghubungkaitkan Log, Metrik dan Jejak
← Kembali ke Panduan Lengkap Spring Boot 4