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

Pemutus Litar dalam apl Go

王林
王林asal
2024-09-03 14:15:11991semak imbas

Hari ini adalah perkara biasa untuk aplikasi kami mempunyai beberapa kebergantungan, terutamanya apabila bekerja dalam persekitaran perkhidmatan mikro. Tidak jarang apabila apl kami melaporkan ralat, kami mendapati bahawa satu pergantungan telah berkurangan.

Satu amalan baik untuk meningkatkan daya tahan kita ialah mematikan komunikasi dengan apl yang tidak berkelakuan baik. Melihat ke dalam bidang lain, kami mempelajari konsep pemutus litar daripada kejuruteraan elektrik, di mana suis dimatikan apabila kegagalan berlaku. Di Brazil, semua rumah mempunyai suis ini yang akan ditutup secara automatik jika rangkaian elektrik kita menjadi tidak stabil.

Dalam sains komputer, pemutus litar kami sedikit lebih kompleks kerana ia juga mempunyai keadaan perantaraan. Lukisan di bawah menerangkan lebih lanjut tentang cara ia berfungsi:

Circuit Breaker in Go apps

Ringkasnya, keadaan yang mungkin adalah:

  • terbuka: tiada komunikasi antara apl. Apabila mencapai keadaan ini, pemasa bermula, membenarkan kebergantungan untuk mewujudkan semula dirinya. Apabila pemasa tamat, kami beralih ke separuh terbuka.
  • ditutup: terdapat komunikasi antara aplikasi. Pada setiap permintaan yang dilakukan dengan kegagalan, kaunter dikemas kini. Jika kami mencapai ambang kegagalan, kami menggerakkan litar untuk dibuka.
  • separuh terbuka: ia adalah keadaan penyembuhan sehingga kita boleh bekerja seperti biasa. Semasa di atasnya, jika kita mencapai ambang kejayaan kita beralih ke ditutup. Jika permintaan terus gagal, kami kembali untuk membuka.

Cukup keren, bukan? Untuk menerangkan konsep dengan lebih baik, mengapa tidak menciptanya?

Pertama, mari kita bina perkhidmatan kami A. Ia akan bertanggungjawab untuk menerima semua permintaan, dengan kata lain, ia akan menjadi perkhidmatan yang bergantung pada aplikasi utama kami. Untuk memudahkan, kami akan mendedahkan dua titik akhir: a /kejayaan yang akan sentiasa bertindak balas dengan 200 dan /kegagalan yang akan sentiasa bertindak balas dengan 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 kami akan bertanggungjawab untuk memanggil perkhidmatan A dan akan membina pemutus litar kami. Komuniti Go sudah mempunyai lib gobreaker yang sudah melaksanakan corak. Pertama sekali, 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 lib membolehkan kami menyesuaikan lebih banyak sifat, kami akan menumpukan pada tiga sahaja:

  • Tamat masa: berapa lama ia akan berada dalam keadaan terbuka. Dalam contoh ini, kami memilih lima saat.
  • MaxRequests: berapa banyak permintaan yang berjaya sebelum ia ditutup. Dalam contoh ini, kami memutuskan dua permintaan.
  • ReadyToTrip: mentakrifkan syarat untuk beralih dari tertutup ke terbuka. Memudahkan, satu kegagalan sudah memadai.

Sekarang kita hanya menyalakan pemutus dan menghantar 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 seperti pembalut di sekeliling fungsi. Jika fungsi mengembalikan ralat, ia akan meningkatkan pembilang kegagalan, dan jika tidak, ia akan meningkatkan pembilang kejayaan. Mari kita takrifkan fungsi itu:

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 itulah cara kita boleh mempunyai aplikasi Go dengan pemutus litar! Apabila menggunakan corak ini, anda boleh meningkatkan daya tahan apl anda dengan menjadikannya lebih bertolak ansur terhadap kegagalan daripada kebergantungan anda. Selain itu, menggunakan lib ini mengalih keluar kebanyakan kerumitan, menjadikannya lebih mudah untuk menggunakan corak dalam apl harian kami. Jika anda ingin melihat kod bukti konsep ini, semak di sini.

Jika anda masih ingin tahu tentang corak daya tahan yang lain, Elton Minetto turut menerbitkan catatan blog yang hebat mengenainya!

Anda juga boleh menyemak ini dan siaran lain di blog peribadi saya. Beritahu saya pendapat anda tentang catatan blog ini dalam ulasan dan satu soalan: adakah anda pernah menggunakan pemutus litar sebelum ini?

Atas ialah kandungan terperinci Pemutus Litar dalam apl 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