MST

星途 面试题库

面试题:Go语言中Goroutine在分布式系统中的负载均衡应用

在一个简单的分布式系统中,使用Go语言的Goroutine实现一个基本的负载均衡器,假设后端有多个服务实例,每个实例可以处理简单的加法运算请求。请描述你的设计思路,并给出关键代码片段。
30.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 服务实例管理:使用一个切片来存储后端服务实例的地址。
  2. 负载均衡算法:采用简单的轮询算法,每次接收到请求,按顺序选择下一个服务实例。
  3. 请求处理:通过Goroutine并发处理来自客户端的请求,并将请求转发到选定的后端服务实例。
  4. 响应处理:接收后端服务实例的响应,并返回给客户端。

关键代码片段

package main

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

// 后端服务实例地址列表
var backendServers = []string{
    "http://localhost:8081",
    "http://localhost:8082",
    "http://localhost:8083",
}

var currentIndex = 0

// 轮询选择后端服务实例
func getNextBackend() string {
    backend := backendServers[currentIndex]
    currentIndex = (currentIndex + 1) % len(backendServers)
    return backend
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
    backend := getNextBackend()
    // 转发请求到后端服务实例
    backendURL := backend + r.URL.Path
    resp, err := http.Get(backendURL)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadGateway)
        return
    }
    defer resp.Body.Close()

    // 将后端服务实例的响应返回给客户端
    _, err = strings.NewReader(resp.Status).WriteTo(w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}

func main() {
    http.HandleFunc("/", handleRequest)
    fmt.Println("负载均衡器启动,监听在 :8080")
    http.ListenAndServe(":8080", nil)
}

在这个代码中:

  1. backendServers 存储了后端服务实例的地址。
  2. getNextBackend 函数实现了轮询算法,选择下一个后端服务实例。
  3. handleRequest 函数处理客户端请求,转发请求到选定的后端服务实例,并将响应返回给客户端。
  4. main 函数启动HTTP服务器,监听在 :8080 端口。

注意:实际应用中,可能需要处理更多的HTTP方法(如POST等)、错误处理、连接池等优化。