Commit 0a87eb9b authored by abdullh.alsoleman's avatar abdullh.alsoleman

commit

parent 60b211e0
module go/hello
go 1.22.0
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from Server 1!")
})
fmt.Println("Server 1 listening on port 8081...")
http.ListenAndServe(":8081", nil)
}
module go/hello
go 1.22.0
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from Server 2!")
})
fmt.Println("Server 2 listening on port 8082...")
http.ListenAndServe(":8082", nil)
}
{
"listenPort": ":8000",
"healthCheckInterval": "5s",
"servers": [
"http://localhost:8081",
"http://localhost:8082"
]
}
module go/load_balancer
go 1.22.0
package main
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"sync"
"time"
)
// Server represents a backend server
type Server struct {
URL *url.URL // URL of the backend server.
ActiveConnections int // Count of active connections
Mutex sync.Mutex
Healthy bool
}
// Config represents the configuration for the load balancer
type Config struct {
HealthCheckInterval string `json:"healthCheckInterval"`
Servers []string `json:"servers"`
ListenPort string `json:"listenPort"`
}
// Load configuration from file
func loadConfig(file string) (Config, error) {
var config Config
bytes, err := ioutil.ReadFile(file)
if err != nil {
return config, err
}
err = json.Unmarshal(bytes, &config)
if err != nil {
return config, err
}
return config, nil
}
// Select the server with the least active connections
func nextServerLeastActive(servers []*Server) *Server {
leastActiveConnections := -1
var leastActiveServer *Server
for _, server := range servers {
server.Mutex.Lock()
if (server.ActiveConnections < leastActiveConnections || leastActiveConnections == -1) && server.Healthy {
leastActiveConnections = server.ActiveConnections
leastActiveServer = server
}
server.Mutex.Unlock()
}
return leastActiveServer
}
func main() {
// Load configuration
config, err := loadConfig("C:\\Users\\Abdullah\\Desktop\\go\\config.json")
if err != nil {
log.Fatalf("Error loading configuration: %s", err.Error())
}
// Parse health check interval
healthCheckInterval, err := time.ParseDuration(config.HealthCheckInterval)
if err != nil {
log.Fatalf("Invalid health check interval: %s", err.Error())
}
// Initialize servers
var servers []*Server
for _, serverURL := range config.Servers {
u, _ := url.Parse(serverURL)
servers = append(servers, &Server{URL: u})
}
// Start health checks for each server
for _, server := range servers {
go func(s *Server) {
for range time.Tick(healthCheckInterval) {
res, err := http.Get(s.URL.String())
if err != nil || res.StatusCode >= 500 {
s.Healthy = false
} else {
s.Healthy = true
}
}
}(server)
}
// Handle incoming requests
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
server := nextServerLeastActive(servers)
if server != nil {
server.Mutex.Lock()
server.ActiveConnections++
server.Mutex.Unlock()
defer func() {
server.Mutex.Lock()
server.ActiveConnections--
server.Mutex.Unlock()
}()
serverProxy := httputil.NewSingleHostReverseProxy(server.URL)
serverProxy.ServeHTTP(w, r)
} else {
http.Error(w, "No healthy server available", http.StatusServiceUnavailable)
}
})
// Start the load balancer
log.Println("Starting server on port", config.ListenPort)
err = http.ListenAndServe(config.ListenPort, nil)
if err != nil {
log.Fatalf("Error starting server: %s\n", err)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment