Golang ialah bahasa pengaturcaraan yang cekap, ringkas dan selamat yang boleh membantu pembangun melaksanakan sistem teragih yang tersedia. Dalam artikel ini, kami akan meneroka cara Golang melaksanakan sistem teragih yang sangat tersedia dan menyediakan beberapa contoh kod khusus.
Sistem teragih ialah sistem yang dilengkapkan dengan kerjasama berbilang peserta. Peserta dalam sistem teragih mungkin nod berbeza yang diedarkan dalam pelbagai aspek seperti lokasi geografi, rangkaian dan struktur organisasi. Apabila melaksanakan sistem teragih, banyak cabaran perlu diselesaikan, seperti:
Golang menyediakan jaringan perpustakaan standard, yang boleh melaksanakan komunikasi rangkaian dengan mudah. Dalam sistem teragih, kami boleh menggunakan beberapa protokol matang untuk mencapai komunikasi, seperti gRPC, HTTP, dsb. Berikut ialah contoh mudah yang dilaksanakan menggunakan protokol HTTP:
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
Dalam contoh ini, kami menggunakan perpustakaan standard http untuk mengendalikan permintaan HTTP Apabila laluan akar diminta, rentetan "Hello World!" Melalui fungsi http.ListenAndServe, kami menentukan port perkhidmatan sebagai 8080 supaya ia boleh menerima permintaan HTTP daripada pelanggan.
2.2. Ketekalan
Ketekalan adalah salah satu isu teras sistem teragih. Dalam sistem teragih, kita biasanya perlu menggunakan beberapa algoritma untuk mengekalkan keadaan yang konsisten antara nod yang berbeza. Proses melaksanakan algoritma ini di Golang biasanya memerlukan penggunaan beberapa perpustakaan, seperti go-kit, etcd, dsb. Berikut ialah contoh mudah menggunakan etcd untuk melaksanakan kunci teragih:
package main import ( "context" "fmt" "time" "go.etcd.io/etcd/clientv3" "go.etcd.io/etcd/clientv3/concurrency" ) func main() { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"localhost:2379"}, DialTimeout: 5 * time.Second, }) if err != nil { panic(err) } defer cli.Close() session, err := concurrency.NewSession(cli) if err != nil { panic(err) } defer session.Close() mutex := concurrency.NewMutex(session, "/my-lock") for i := 0; i < 10; i++ { go func() { for { err := mutex.Lock(context.Background()) if err == nil { fmt.Println("lock success") time.Sleep(1 * time.Second) mutex.Unlock(context.Background()) break } else { time.Sleep(50 * time.Millisecond) } } }() } time.Sleep(10 * time.Second) }
Dalam contoh ini, kami melaksanakan kunci teragih melalui etcd. Mula-mula, kami mencipta klien etcd menggunakan fungsi clientv3.New, kemudian mencipta sesi menggunakan fungsi concurrency.NewSession, dan akhirnya mencipta kunci menggunakan fungsi concurrency.NewMutex. Dalam fungsi utama, kami mencipta 10 coroutine Setiap coroutine akan cuba memperoleh kunci Jika kunci itu sudah diduduki oleh coroutine lain, tunggu 50 milisaat sebelum terus mencuba sehingga pemerolehan berjaya.
2.3. Toleransi Kesalahan
Dalam sistem teragih, komunikasi antara nod tidak boleh dipercayai dan masalah seperti kehilangan mesej dan pembahagian rangkaian mungkin berlaku. Oleh itu, kita perlu bertoleransi terhadap masalah ini. Di Golang, kami boleh menggunakan beberapa perpustakaan untuk mencapai toleransi kesalahan, seperti Netflix's Hystrix, Go kit, dsb. Berikut ialah contoh penggunaan Hystrix untuk mencapai toleransi kesalahan:
package main import ( "fmt" "math/rand" "time" "github.com/afex/hystrix-go/hystrix" ) func main() { rand.Seed(time.Now().UnixNano()) hystrix.ConfigureCommand("hello", hystrix.CommandConfig{ Timeout: 1000, MaxConcurrentRequests: 100, ErrorPercentThreshold: 50, }) for { result := make(chan string, 1) errs := hystrix.Go("hello", func() error { // Do something that might fail. if rand.Int()%2 == 1 { time.Sleep(1100 * time.Millisecond) return nil } else { time.Sleep(500 * time.Millisecond) return fmt.Errorf("failure") } }, func(err error) error { // Handle the error. fmt.Printf("failed with error: %v ", err) result <- "error" return nil }) select { case r := <-result: fmt.Println("result:", r) case <-time.After(1200 * time.Millisecond): fmt.Println("timeout") errs = append(errs, fmt.Errorf("timeout")) } if len(errs) > 0 { fmt.Printf("request failed: %v ", errs) } } }
Dalam contoh ini, kami menggunakan perpustakaan Hystrix untuk mencapai toleransi kesalahan. Pertama, kami menggunakan fungsi hystrix.ConfigureCommand untuk mengkonfigurasi perintah bernama "hello", tetapkan tamat masa kepada 1000 milisaat, bilangan maksimum permintaan serentak kepada 100 dan ambang kadar ralat kepada 50%. Kemudian, dalam gelung tak terhingga, kami memanggil fungsi hystrix.Go untuk melaksanakan permintaan olok-olok. Permintaan ini secara rawak mengembalikan kejayaan atau kegagalan. Kejayaan mengembalikan rentetan "kejayaan", dan kegagalan mengembalikan mesej ralat. Jika permintaan itu berjaya dilaksanakan, rentetan "kejayaan" akan dikembalikan melalui saluran hasil, jika tidak, ia akan diproses melalui fungsi yang diluluskan dalam parameter ketiga, mesej ralat akan dicetak dan rentetan "ralat" akan dikembalikan melalui saluran hasil.
2.4. Kebolehskalaan
Dalam sistem teragih, kebolehskalaan adalah sangat penting. Golang menyediakan banyak alatan untuk menyokong kebolehskalaan, seperti goroutin dan saluran. Goroutine ialah benang ringan yang membolehkan kami membuat beribu-ribu tugasan serentak, dan saluran ialah mekanisme untuk komunikasi antara coroutine. Berikut ialah contoh mudah menggunakan goroutin dan saluran untuk mencapai keselarasan:
package main import ( "fmt" "time" ) func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Println("worker", id, "processing job", j) time.Sleep(time.Second) results <- j * 2 } } func main() { jobs := make(chan int, 100) results := make(chan int, 100) for w := 0; w < 3; w++ { go worker(w, jobs, results) } for j := 0; j < 5; j++ { jobs <- j } close(jobs) for a := 0; a < 5; a++ { res := <-results fmt.Println("result:", res) } }
Dalam contoh ini, kami mencipta kumpulan pekerja dengan 3 goroutin. Dalam fungsi utama, 5 tugasan ditulis ke saluran kerja, dan setiap tugas adalah nombor. Fungsi pekerja membaca tugasan daripada saluran kerja, memprosesnya dan mengembalikan hasil melalui saluran hasil. Akhir sekali, fungsi utama membaca hasil daripada saluran hasil dan mencetaknya. Memandangkan terdapat tiga goroutine dilaksanakan pada masa yang sama, tugasan diproses secara serentak.
2.5 Keselamatan
Dalam sistem teragih, keselamatan komunikasi dan data adalah penting. Golang menyediakan banyak alatan untuk menyokong keselamatan, seperti TLS, algoritma penyulitan, dsb. Di bawah ialah contoh mudah menggunakan TLS untuk melaksanakan komunikasi yang disulitkan:
package main import ( "crypto/tls" "fmt" "net/http" ) func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Hello, HTTPS!") }) srv := &http.Server{ Addr: ":8443", Handler: mux, TLSConfig: &tls.Config{ MinVersion: tls.VersionTLS12, PreferServerCipherSuites: true, CurvePreferences: []tls.CurveID{tls.CurveP256, tls.X25519}, }, } err := srv.ListenAndServeTLS("cert.pem", "key.pem") if err != nil { fmt.Println(err) } }
在这个例子中,我们使用了TLS来加密通信,通过http.NewServeMux函数创建了一个路由器,将根路径"/"与一个处理函数绑定。然后使用http.Server结构体创建了一个HTTP服务器,设定了端口为8443,将路由器绑定到Handler字段中。在TLSConfig字段中,我们设定了最小TLS版本为1.2,启用了服务器优先的密码套件偏好,并设定了支持的曲线类型。最后,我们通过srv.ListenAndServeTLS函数启动了HTTPS服务器,参数"cert.pem"和"key.pem"分别为证书和私钥的路径。
Golang可以帮助我们很方便地实现高可用的分布式系统,通过使用标准库和第三方库,可以很好地解决通信、一致性、容错、可扩展性和安全性等问题。在本文中,我们介绍了一些常用的库和示例,希望对你的分布式系统开发有所帮助。
Atas ialah kandungan terperinci Penyelesaian Golang untuk melaksanakan sistem teragih yang sangat tersedia. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!