服务注册:服务启动时向注册中心注册自己的地址
服务发现:客户端从注册中心获取服务地址列表
package main
import (
"fmt"
"github.com/hashicorp/consul/api"
)
func RegisterService(consulAddr, serviceName, serviceAddr string, port int) error {
config := api.DefaultConfig()
config.Address = consulAddr
client, err := api.NewClient(config)
if err != nil {
return err
}
registration := &api.AgentServiceRegistration{
ID: fmt.Sprintf("%s-%d", serviceName, port),
Name: serviceName,
Port: port,
Address: serviceAddr,
Check: &api.AgentServiceCheck{
HTTP: fmt.Sprintf("http://%s:%d/health", serviceAddr, port),
Interval: "10s",
Timeout: "3s",
DeregisterCriticalServiceAfter: "30s",
},
}
return client.Agent().ServiceRegister(registration)
}func DiscoverService(consulAddr, serviceName string) ([]string, error) {
config := api.DefaultConfig()
config.Address = consulAddr
client, err := api.NewClient(config)
if err != nil {
return nil, err
}
services, _, err := client.Health().Service(serviceName, "", true, nil)
if err != nil {
return nil, err
}
var addrs []string
for _, service := range services {
addr := fmt.Sprintf("%s:%d", service.Service.Address, service.Service.Port)
addrs = append(addrs, addr)
}
return addrs, nil
}func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}
func main() {
// 注册健康检查接口
http.HandleFunc("/health", HealthCheckHandler)
// 注册服务
RegisterService("localhost:8500", "my-service", "localhost", 8080)
// 启动服务
http.ListenAndServe(":8080", nil)
}| 特性 | Consul | Nacos | etcd | Eureka |
|---|---|---|---|---|
| 语言 | Go | Java | Go | Java |
| CAP | CP | AP | CP | AP |
| 健康检查 | ✅ | ✅ | ❌ | ✅ |
| KV存储 | ✅ | ✅ | ✅ | ❌ |
| 多数据中心 | ✅ | ✅ | ❌ | ❌ |
| UI界面 | ✅ | ✅ | ❌ | ✅ |
关键要点:
- ✅ 服务注册与发现是微服务基础设施
- ✅ Consul适合云原生场景
- ✅ 健康检查保证高可用
- ✅ 客户端负载均衡
💡 思考题:CP和AP模式如何选择?