負載平衡器在現代軟體開發中至關重要。如果您曾經想知道如何在多個伺服器之間分配請求,或者為什麼某些網站即使在流量大的情況下也感覺更快,答案通常在於高效的負載平衡。
在這篇文章中,我們將使用 Go 中的 循環演算法 建立一個簡單的應用程式負載平衡器。這篇文章的目的是逐步了解負載平衡器的底層工作原理。
什麼是負載平衡器?
負載平衡器是一個在多個伺服器之間分配傳入網路流量的系統。它確保沒有任何一台伺服器承受過多的負載,防止瓶頸並改善整體使用者體驗。負載平衡方法還確保如果一台伺服器發生故障,則流量可以自動重新路由到另一台可用的伺服器,從而減少故障的影響並提高可用性。
我們為什麼要使用負載平衡器?
- 高可用性:透過分配流量,負載平衡器確保即使一台伺服器發生故障,流量也可以路由到其他健康的伺服器,從而使應用程式更具彈性。
- 可擴展性:負載平衡器可讓您透過隨著流量的增加而添加更多伺服器來水平擴展系統。
- 效率:它透過確保所有伺服器平等地分擔工作負載來最大化資源利用率。
負載平衡演算法
有不同的演算法和策略來分配流量:
- 循環法:最簡單的方法之一。它在可用伺服器之間按順序分配請求。一旦到達最後一個伺服器,它就會從頭開始。
- 加權輪循:與輪循演算法類似,只是每個伺服器都被分配了一些固定的數位權重。這個給定的權重用於確定路由流量的伺服器。
- 最少連接:將流量路由到活動連接最少的伺服器。
- IP 雜湊:根據客戶端的 IP 位址選擇伺服器。
在這篇文章中,我們將專注於實作循環負載平衡器。
什麼是循環演算法?
循環演算法以循環方式將每個傳入請求傳送到下一個可用伺服器。如果伺服器 A 處理第一個請求,伺服器 B 將處理第二個請求,伺服器 C 將處理第三個請求。一旦所有伺服器都收到請求,它就會從伺服器 A 重新開始。
現在,讓我們進入程式碼並建立我們的負載平衡器!
第 1 步:定義負載平衡器和伺服器
type LoadBalancer struct { Current int Mutex sync.Mutex }
我們先定義一個簡單的 LoadBalancer 結構,其中包含一個 Current 欄位來追蹤哪個伺服器應該處理下一個請求。互斥體確保我們的程式碼可以安全地同時使用。
我們負載平衡的每個伺服器都是由 Server 結構體定義的:
type Server struct { URL *url.URL IsHealthy bool Mutex sync.Mutex }
這裡,每個伺服器都有一個 URL 和一個 IsHealthy 標誌,該標誌指示伺服器是否可以處理請求。
第 2 步:循環演算法
我們的負載平衡器的核心是循環演算法。其工作原理如下:
func (lb *LoadBalancer) getNextServer(servers []*Server) *Server { lb.Mutex.Lock() defer lb.Mutex.Unlock() for i := 0; i
- 此方法以循環方式循環遍歷伺服器清單。如果所選伺服器運作狀況良好,則會傳回該伺服器來處理傳入請求。
- 我們使用 Mutex 來確保一次只有一個 Goroutine 可以存取和修改負載平衡器的 Current 欄位。這確保了循環演算法在同時處理多個請求時正確運行。
- 每個伺服器也有自己的互斥鎖。當我們檢查 IsHealthy 欄位時,我們會鎖定伺服器的 Mutex 以防止多個 goroutine 並發存取。
- 如果沒有互斥鎖,另一個 goroutine 可能會更改值,導致讀取不正確或不一致的資料。
- 更新 Current 欄位或讀取 IsHealthy 欄位值後,我們會立即解鎖互斥體,以保持臨界區盡可能小。透過這種方式,我們使用互斥來避免任何競爭條件。
步驟 3:配置負載平衡器
我們的設定儲存在 config.json 檔案中,其中包含伺服器 URL 和執行狀況檢查間隔(更多資訊請參閱下一節)。
type Config struct { Port string `json:"port"` HealthCheckInterval string `json:"healthCheckInterval"` Servers []string `json:"servers"` }
設定檔可能如下所示:
{ "port": ":8080", "healthCheckInterval": "2s", "servers": [ "http://localhost:5001", "http://localhost:5002", "http://localhost:5003", "http://localhost:5004", "http://localhost:5005" ] }
Step 4: Health Checks
We want to make sure that the servers are healthy before routing any incoming traffic to them. This is done by sending periodic health checks to each server:
func healthCheck(s *Server, healthCheckInterval time.Duration) { for range time.Tick(healthCheckInterval) { res, err := http.Head(s.URL.String()) s.Mutex.Lock() if err != nil || res.StatusCode != http.StatusOK { fmt.Printf("%s is down\n", s.URL) s.IsHealthy = false } else { s.IsHealthy = true } s.Mutex.Unlock() } }
Every few seconds (as specified in the config), the load balancer sends a HEAD request to each server to check if it is healthy. If a server is down, the IsHealthy flag is set to false, preventing future traffic from being routed to it.
Step 5: Reverse Proxy
When the load balancer receives a request, it forwards the request to the next available server using a reverse proxy. In Golang, the httputil package provides a built-in way to handle reverse proxying, and we will use it in our code through the ReverseProxy function:
func (s *Server) ReverseProxy() *httputil.ReverseProxy { return httputil.NewSingleHostReverseProxy(s.URL) }
What is a Reverse Proxy?
A reverse proxy is a server that sits between a client and one or more backend severs. It receives the client's request, forwards it to one of the backend servers, and then returns the server's response to the client. The client interacts with the proxy, unaware of which specific backend server is handling the request.
In our case, the load balancer acts as a reverse proxy, sitting in front of multiple servers and distributing incoming HTTP requests across them.
Step 6: Handling Requests
When a client makes a request to the load balancer, it selects the next available healthy server using the round robin algorithm implementation in getNextServer function and proxies the client request to that server. If no healthy server is available then we send service unavailable error to the client.
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { server := lb.getNextServer(servers) if server == nil { http.Error(w, "No healthy server available", http.StatusServiceUnavailable) return } w.Header().Add("X-Forwarded-Server", server.URL.String()) server.ReverseProxy().ServeHTTP(w, r) })
The ReverseProxy method proxies the request to the actual server, and we also add a custom header X-Forwarded-Server for debugging purposes (though in production, we should avoid exposing internal server details like this).
Step 7: Starting the Load Balancer
Finally, we start the load balancer on the specified port:
log.Println("Starting load balancer on port", config.Port) err = http.ListenAndServe(config.Port, nil) if err != nil { log.Fatalf("Error starting load balancer: %s\n", err.Error()) }
Working Demo
TL;DR
In this post, we built a basic load balancer from scratch in Golang using a round robin algorithm. This is a simple yet effective way to distribute traffic across multiple servers and ensure that your system can handle higher loads efficiently.
There's a lot more to explore, such as adding sophisticated health checks, implementing different load balancing algorithms, or improving fault tolerance. But this basic example can be a solid foundation to build upon.
You can find the source code in this GitHub repo.
以上是用 Go 建構一個簡單的負載平衡器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

OpenSSL,作為廣泛應用於安全通信的開源庫,提供了加密算法、密鑰和證書管理等功能。然而,其歷史版本中存在一些已知安全漏洞,其中一些危害極大。本文將重點介紹Debian系統中OpenSSL的常見漏洞及應對措施。 DebianOpenSSL已知漏洞:OpenSSL曾出現過多個嚴重漏洞,例如:心臟出血漏洞(CVE-2014-0160):該漏洞影響OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻擊者可利用此漏洞未經授權讀取服務器上的敏感信息,包括加密密鑰等。

本文演示了創建模擬和存根進行單元測試。 它強調使用接口,提供模擬實現的示例,並討論最佳實踐,例如保持模擬集中並使用斷言庫。 文章

本文探討了GO的仿製藥自定義類型約束。 它詳細介紹了界面如何定義通用功能的最低類型要求,從而改善了類型的安全性和代碼可重複使用性。 本文還討論了局限性和最佳實踐

本文討論了GO的反思軟件包,用於運行時操作代碼,對序列化,通用編程等有益。它警告性能成本,例如較慢的執行和更高的內存使用,建議明智的使用和最佳

本文使用跟踪工具探討了GO應用程序執行流。 它討論了手冊和自動儀器技術,比較諸如Jaeger,Zipkin和Opentelemetry之類的工具,並突出顯示有效的數據可視化

本文討論了GO中使用表驅動的測試,該方法使用測試用例表來測試具有多個輸入和結果的功能。它突出了諸如提高的可讀性,降低重複,可伸縮性,一致性和A


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6
視覺化網頁開發工具

WebStorm Mac版
好用的JavaScript開發工具