Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Aplikasi Pemutus Litar dalam Go

Aplikasi Pemutus Litar dalam Go

PHPz
PHPzasal
2024-08-27 21:31:56679semak imbas

Hari ini, adalah perkara biasa untuk aplikasi kami bergantung kepada orang lain, terutamanya jika kami bekerja dalam persekitaran perkhidmatan mikro. Adalah perkara biasa bagi aplikasi kami untuk mula melaporkan ralat, dan apabila menyiasat, kami mendapati bahawa beberapa API daripada pasukan rakan kongsi atau pembekal tidak berfungsi.

Amalan yang baik untuk meningkatkan daya tahan aplikasi kami ialah memutuskan komunikasi dengan aplikasi yang berada dalam keadaan tidak digunakan lagi. Memerhati kawasan lain, kami menyerap konsep Pemutus Litar daripada Kejuruteraan Elektrik. Peralatan, atau pemutus litar, diletakkan di dalamnya, yang akan dimatikan secara automatik jika kegagalan berlaku. Ini adalah perkara biasa di rumah kita, yang mempunyai pemutus litar yang dimatikan dengan sendirinya jika rangkaian elektrik mula menjadi tidak stabil.

Dalam pengkomputeran, Pemutus Litar kami sedikit lebih kompleks, kerana kami juga mentakrifkan keadaan perantaraan. Lukisan di bawah menerangkan dengan lebih baik cara Pemutus Litar berfungsi:

Circuit Breaker em aplicações Go

Akhir sekali, negeri-negeri itu ialah:

  • terbuka: tiada komunikasi antara aplikasi. Apabila mencapai keadaan ini, pemasa mula memberi masa untuk perkhidmatan penetapan semula. Pada penghujung pemasa, kami beralih kepada separuh terbuka.
  • ditutup: terdapat komunikasi antara aplikasi. Untuk setiap permintaan yang gagal, kaunter dikemas kini. Jika had kegagalan dicapai, kami mengalihkan litar untuk membuka.
  • separuh terbuka: keadaan pemulihan sehingga komunikasi dapat mengalir sepenuhnya. Di dalamnya, kaunter kejayaan dikemas kini dengan setiap permintaan. Jika bilangan kejayaan yang ideal dicapai, kami mengalihkan litar ke tertutup. Jika permintaan gagal, kami beralih kembali ke buka.

Cukup keren, bukan? Tetapi untuk memberi contoh konsep yang lebih baik, bagaimana kalau kita melakukannya secara praktikal?

Pertama, mari kita bina perkhidmatan kami A. Ia akan bertanggungjawab untuk menerima permintaan, iaitu, ia akan menjadi perkhidmatan yang permohonan kami bergantung kepada, perkhidmatan pembekal, atau lain-lain. Untuk memudahkannya, kami akan mendedahkan dua titik akhir, /kejayaan yang akan sentiasa mengembalikan 200 dan /kegagalan yang akan sentiasa mengembalikan 500.

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/success", func(w http.ResponseWriter, r *http.Request) { 
    w.WriteHeader(http.StatusOK) })
    http.HandleFunc("/failure", func(w http.ResponseWriter, r *http.Request) { 
    w.WriteHeader(http.StatusInternalServerError) })

    fmt.Println("Server is running at http://localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Perkhidmatan B akan bertanggungjawab untuk memanggil perkhidmatan A. Ia akan membina pemutus litar kami. Beruntung bagi kami, komuniti Go sudah mempunyai perpustakaan gobreaker yang melaksanakan corak tersebut! Pertama, kami mentakrifkan sifat pemutus kami:

var st gobreaker.Settings
st.Name = "Circuit Breaker PoC"
st.Timeout = time.Second * 5
st.MaxRequests = 2
st.ReadyToTrip = func(counts gobreaker.Counts) bool {
    return counts.ConsecutiveFailures >= 1
}

Walaupun perpustakaan membenarkan kami menyesuaikan lebih banyak perkara, kami akan menumpukan pada tiga:

  • Tamat masa: masa litar akan kekal dalam keadaan terbuka. Dalam kes kami, masa ditetapkan kepada 5 saat.
  • MaxRequests: bilangan permintaan yang berjaya sebelum ditutup. Dalam contoh kami, kami menetapkannya kepada 2 permintaan.
  • ReadyToTrip: mentakrifkan syarat untuk beralih daripada tertutup kepada terbuka. Untuk memudahkannya, katakan satu kegagalan sudah memadai.

Kemudian kita boleh memulakan pemutus dan membuat permintaan:

cb := gobreaker.NewCircuitBreaker[int](st)

url := "http://localhost:8080/success"
cb.Execute(func() (int, error) { return Get(url) })
fmt.Println("Circuit Breaker state:", cb.State()) // closed!

url = "http://localhost:8080/failure"
cb.Execute(func() (int, error) { return Get(url) })
fmt.Println("Circuit Breaker state:", cb.State()) // open!

time.Sleep(time.Second * 6)
url = "http://localhost:8080/success"
cb.Execute(func() (int, error) { return Get(url) })
fmt.Println("Circuit Breaker state:", cb.State()) // half-open!

url = "http://localhost:8080/success"
cb.Execute(func() (int, error) { return Get(url) })
fmt.Println("Circuit Breaker state:", cb.State()) // closed!

Kita dapat perhatikan bahawa gobreaker berfungsi sebagai pembalut di sekeliling fungsi. Jika fungsi mengembalikan ralat, ia meningkatkan bilangan ralat, jika tidak, ia meningkatkan bilangan kejayaan. Jadi mari kita takrifkan fungsi ini:

func Get(url string) (int, error) {
    r, _ := http.Get(url)

    if r.StatusCode != http.StatusOK {
        return r.StatusCode, fmt.Errorf("failed to get %s", url)
    }

    return r.StatusCode, nil
}

Dan kami mempunyai perkhidmatan Go menggunakan pemutus litar! Dengan menggunakan corak ini, anda boleh meningkatkan daya tahan dan toleransi kesalahan perkhidmatan anda. Kita dapat perhatikan bahawa apabila menggunakan perpustakaan, kerumitan itu telah disarikan sepenuhnya, menjadikan proses penyepaduan ini ke dalam kehidupan seharian kita sangat mudah. Jika anda ingin melihat keseluruhan bukti kod konsep, sila pergi ke sini.

Jika anda ingin tahu corak daya tahan yang lain, Elton Minetto menerbitkan siaran hebat mengenai topik tersebut!

Beritahu saya pendapat anda tentang siaran ini dalam ulasan dan inilah soalan: adakah anda pernah menggunakan pemutus litar sebelum ini? Oh, anda juga boleh mencari saya di blog peribadi saya!

Atas ialah kandungan terperinci Aplikasi Pemutus Litar dalam Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn