golang服务发现路由
时间: 2023-10-03 09:07:55 浏览: 256
在Golang中实现服务发现和路由的常见做法是使用服务发现工具(如Consul、Etcd、ZooKeeper等)来注册和发现服务,并使用反向代理来进行路由。下面是一个简单的示例:
1. 添加服务注册和发现依赖:
```go
go get github.com/hashicorp/consul/api
```
2. 注册服务:
```go
package main
import (
"log"
"net"
"os"
consulapi "github.com/hashicorp/consul/api"
)
func main() {
// 创建Consul客户端
consulCfg := consulapi.DefaultConfig()
consulClient, err := consulapi.NewClient(consulCfg)
if err != nil {
log.Fatal(err)
}
// 获取主机名和端口
hostname, _ := os.Hostname()
port := 8080
// 创建ServiceEntry
serviceID := hostname + "-service"
service := &consulapi.AgentServiceRegistration{
ID: serviceID,
Name: "my-service",
Port: port,
Address: net.JoinHostPort("", strconv.Itoa(port)),
}
// 注册服务到Consul
err = consulClient.Agent().ServiceRegister(service)
if err != nil {
log.Fatal(err)
}
log.Printf("Service '%s' registered with Consul", serviceID)
// ...
}
```
3. 路由请求:
```go
package main
import (
"log"
"net/http"
consulapi "github.com/hashicorp/consul/api"
)
func main() {
// 创建Consul客户端
consulCfg := consulapi.DefaultConfig()
consulClient, err := consulapi.NewClient(consulCfg)
if err != nil {
log.Fatal(err)
}
// 创建反向代理
proxy := &Proxy{
consul: consulClient,
}
// 启动HTTP服务器
http.HandleFunc("/", proxy.HandleRequest)
log.Fatal(http.ListenAndServe(":8080", nil))
}
type Proxy struct {
consul *consulapi.Client
}
func (p *Proxy) HandleRequest(w http.ResponseWriter, r *http.Request) {
// 从Consul中获取服务实例
serviceEntries, _, err := p.consul.Health().Service("my-service", "", true, nil)
if err != nil || len(serviceEntries) == 0 {
http.Error(w, "Service not available", http.StatusServiceUnavailable)
return
}
// 选择一个服务实例进行转发
targetURL := "http://" + serviceEntries[0].Service.Address + ":" + strconv.Itoa(serviceEntries[0].Service.Port) + r.URL.Path
// 发送请求到服务实例
resp, err := http.Get(targetURL)
if err != nil {
http.Error(w, "Failed to proxy request", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
// 将服务实例的响应返回给客户端
for k, v := range resp.Header {
w.Header().Set(k, v[0])
}
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}
```
这是一个简单的示例,使用Consul作为服务发现工具,并使用反向代理进行请求路由。你可以根据自己的需求进行相应调整,例如使用其他服务发现工具、实现更复杂的路由策略等。
阅读全文