概述
- 现在,我们使用consul客户端的api来把Http服务注册到consul上,非Go-Micro的形式
- 其实,consul官方提供了对应的接口调用来实现,golang中的consul/api包对其进行了封装
- 我们使用consul/api来进行展示
目录结构
gitee.com/go-micro-services/consul-http├── conf│ └── conf.go├── controllers│ └── ctl.go├── utils│ └── consul.go├── main.go└── go.mod
1 ) conf/conf.go
package confvar (ConsulAddr = "127.0.0.1:8500"HttpAddr = "127.0.0.1:8100"HttpHost = "127.0.0.1"HttpPort = 8100HttpName = "http_consul_001"HttpId = "hc_xxxxx"HttpTags = []string{"a", "b"}
)
- 这里,定义了一些全局配置的变量值
- 注意,HttpName 这里在后面过滤服务时默认是不能使用
-
的 - 这里,使用下划线来代替连字符
2 ) controllers/ctl.go
package controllerimport ("net/http""gitee.com/go-micro-services/consul-http/conf""gitee.com/go-micro-services/consul-http/utils""github.com/gin-gonic/gin"
)// 用于健康检查的处理程序
func HealthHandler(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "ok",})
}// 获取服务列表的处理程序
func ServiceListHandler(c *gin.Context) {services, err := utils.GetServiceList()if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}// 将服务列表转换为 JSON 并返回c.JSON(http.StatusOK, services)
}// 获取服务列表的处理程序
func CurrentServiceHandler(c *gin.Context) {services, err := utils.FilterService(conf.HttpName) // 这里默认来说,名称不能用连字符 - 否则会报错,否则就需要自定义函数if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}// 将服务列表转换为 JSON 并返回c.JSON(http.StatusOK, services)
}
- 这里定义了三个控制器,用于处理对应的路由
3 ) utils/consul.go
package utilsimport ("fmt""gitee.com/go-micro-services/consul-http/conf""github.com/hashicorp/consul/api"
)var ConsulClient *api.Client// 获取consul客户端
func GetConsulClient() (*api.Client, error) {// 获取缓存if ConsulClient != nil {return ConsulClient, nil}// 获取注册中心连接客户端defaultConfig := api.DefaultConfig()defaultConfig.Address = conf.ConsulAddrConsulClient, err := api.NewClient(defaultConfig)return ConsulClient, err
}// 当前http服务注册到consul
func ConsulHttpReg() error {// 获取注册中心连接客户端client, err := GetConsulClient()if err != nil {return err}// 注册实例配置agentServiceRegistration := new(api.AgentServiceRegistration)agentServiceRegistration.Address = conf.HttpHostagentServiceRegistration.Port = conf.HttpPortagentServiceRegistration.Name = conf.HttpNameagentServiceRegistration.ID = conf.HttpIdagentServiceRegistration.Tags = conf.HttpTagshttpAddr := fmt.Sprintf("http://%s/health", conf.HttpAddr)check := api.AgentServiceCheck{HTTP: httpAddr,Timeout: "3s",Interval: "1s",DeregisterCriticalServiceAfter: "3s",}agentServiceRegistration.Check = &check// 注册return client.Agent().ServiceRegister(agentServiceRegistration)
}// 工具函数-获取所有服务列表
func GetServiceList() (map[string]*api.AgentService, error) {// 获取注册中心连接客户端client, err := GetConsulClient()if err != nil {return nil, err}services, err := client.Agent().Services()return services, err
}// 工具函数-过滤服务
func FilterService(service string) (map[string]*api.AgentService, error) {// 获取注册中心连接客户端client, err := GetConsulClient()if err != nil {return nil, err}// 过滤条件filterCondition := fmt.Sprintf("Service==%v", service)services, err := client.Agent().ServicesWithFilter(filterCondition)return services, err
}
- 这里,缓存了ConsulClient客户端
- 提供了把http服务注册到consul 的方法
- 提供了获取所有服务列表的方法
- 提供了过滤当前服务的方法
4 ) main.go
package mainimport ("gitee.com/go-micro-services/consul-http/conf"ctl "gitee.com/go-micro-services/consul-http/controller""gitee.com/go-micro-services/consul-http/utils""github.com/gin-gonic/gin"
)func init() {// 到consul注册中心进行注册err := utils.ConsulHttpReg()if err != nil {panic(err)}
}func main() {r := gin.Default()r.GET("/health", ctl.HealthHandler) // 提供一个 /health 接口r.GET("/serviceList", ctl.ServiceListHandler) // 提供一个 /serviceList 展示r.GET("/currentService", ctl.CurrentServiceHandler) // 提供一个 /currentService 展示r.Run(conf.HttpAddr) // 运行当前http服务
}
- 在 init 函数中注册到consul
- 提供了三个路由:健康检查,获取所有服务,获取当前服务
运行效果
1 )运行后,可以看到立即进行了健康检查
2 ) 查看consul面板,发现已经注册成功,并且配置的信息都有了
可见,配置的一些信息都对应上了
3 ) /health 路由
4 ) /serviceList 路由
5 )/currentService 路由
其他
- 源码地址:https://gitee.com/go-micro-services/consul-http
- consul官方文档:https://developer.hashicorp.com/consul/docs/services/configuration/services-configuration-reference