你可以使用 Go 语言中的 net/http
包来实现根据不同 URL 路径进行处理并转发到不同目的地的功能。以下是一个简单的示例,展示了如何根据请求的 URL 将其转发到不同的目标服务器。
package main
import (
"io/ioutil"
"log"
"net/http"
"net/url"
)
func main() {
http.HandleFunc("/", handler)
log.Println("Starting server on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
var targetURL string
// 根据请求的路径选择目标URL
switch r.URL.Path {
case "/service1":
targetURL = "http://localhost:8001" // 第一个服务的地址
case "/service2":
targetURL = "http://localhost:8002" // 第二个服务的地址
default:
http.Error(w, "Service not found", http.StatusNotFound)
return
}
// 创建新的请求,转发到目标服务器
req, err := http.NewRequest(r.Method, targetURL+r.URL.Path, r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 转发原始请求的头部信息
for key, values := range r.Header {
for _, value := range values {
req.Header.Add(key, value)
}
}
// 执行请求并获取响应
client := &http.Client{}
resp, err := client.Do(req)
// 确保我们关闭响应体,以防止资源泄漏。
defer func() {
if resp != nil {
ioutil.ReadAll(resp.Body) // 消耗响应体
resp.Body.Close()
}
}()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 将目标服务器的响应写回给客户端
for key, values := range resp.Header {
for _, value := range values {
w.Header().Add(key, value)
}
}
w.WriteHeader(resp.StatusCode)
bodyBytes, _ := ioutil.ReadAll(resp.Body)
w.Write(bodyBytes)
}
说明:
- 启动 HTTP 服务器:该代码启动了一个 HTTP 服务器,监听在端口
8080
。 - 路由选择:在
handler
函数中,根据请求的 URL 路径(例如/service1
或/service2
)决定将请求转发到哪个目标地址。 - 创建新请求:使用
http.NewRequest
创建新的 HTTP 请求,并将原始请求的方法和主体传递给它。 - 复制头部信息:把原始请求中的头部信息复制到新的请求中。
- 发送转发请求:通过
http.Client
发送这个新创建的请求,并获取响应,然后将其返回给客户端。
使用方法:
- 启动这个程序后,可以向
http://localhost:8080/service1
和http://localhost:8080/service2
发起请求,它们会被转发到相应的服务(你需要替换成实际存在且可访问的服务地址)。 - 请确保在本地或网络上有对应地址服务运行以测试这个代理功能。
如果你对其他特性或更复杂逻辑有需求,可以进一步扩展此示例。
内容由零声教学AI助手提供,问题来源于学员提问