Golang使用Consul详解
作者:Small-K 发布时间:2024-04-26 17:35:56
常用指令
agent指令
-bind=0.0.0.0 指定consul所在机器的ip地址
-http-port 指定web接口服务端口
-client 指定哪些机器可以访问consul, 0.0.0.0表示所有机器
-data-dir=path 指定服务数据文件存储位置
-dev 开发者模式,直接以默认模式启动consul
-node=hostname 服务发现的名字
-rejoin consul启动的时候,加入到的consul集群
-server 以服务方式开启server, 允许其他的consul连接到开启的consul上,不加则以客户端方式开启
-ui 可以谁用web页面来查看服务发现的详情
-config-dir 配置文件地址, 如果是文件夹会将所有文件合并,里面可以配置自己所在节点提供的服务
-bootstrap-expect 在一个集群中期望提供的server节点数目,当该值提供时, consul一直等到达到指定的server数目才会参加选举,推举自己为leader。这个可以避免不一致和脑裂现象
启动
consul agent -server -bootstrap-expect 1 -ui -rejoin -http-port=8080 -bind="127.0.0.1" -data-dir C:\Windows\tmp
members
查看集群中有多少成员
info
查看当前系欸但信息
leave
优雅关闭consul
reload
重新加载配置文件
常用功能
Consul最重要的的功能就是定义服务, 服务管理和健康检查
定义服务
要定义一个服务, 有两种方式:
通过写配置文件, 让Consul读取
通过接口向Consul服务进行注册
一般我们采用第二种方式, 但我们可以通过第一种方式的书写规则来了解服务定义的一些选项
我们可以通过启动时指定-config-dir
来指定配置文件所在位置, 配置文件时json格式, 有多个会合并在一起
例子:
{
"service": {
"name": "redis", // 在consul面板上显示的服务名
"id": "redis", // 服务id, 一般通过服务id对服务进行管理, 若不指定则会使用name作为id
"address": "127.0.0.1", // 服务地址
"port": 80, // 服务运行的端口
"tags": [
"primary"
], // 服务的标签, 可以作为服务的额外信息
// 服务健康检查, 后面介绍
"checks": [
{
"args": [
"/bin/check_redis",
"-p",
"7000"
],
"interval": "30s",
"timeout" : "60s"
}
]
}
}
服务管理
所谓服务管理就是指服务发现\服务注册\服务注销
consul服务端均提供了相应的http\dns等方式的接口可以方便地操作,
一般我们用go是用官方提供的一个api
库进行操作, 对这些http的接口就不再过多赘述, 可以查阅官方文档
Consul API
服务健康检查
健康检查是为了避免服务突然宕机而调用方不知道的情况发生, 原理就是隔一段时间通信一次
consul提供了 tcp\ssl\ttl\udp\script\http等多种方式来进行健康检查,可以在服务注册时指定健康检查的方式
consul根据interval
变量来决定多少时间间隔来通讯
根据timeout
变量来决定发送请求后多久未收到回应算作失败
这里我们介绍三种, http|tcp|script方式
http方式
{
"check": {
"id": "api",
"name": "HTTP API on port 5000",
"http": "https://localhost:5000/health", //调用接口
"method": "POST",
"header": { "Content-Type": ["application/json"] },
"body": "{\"method\":\"health\"}",
"interval": "10s", //
"timeout": "1s"
}
}
tcp方式
{
"check": {
"id": "ssh",
"name": "SSH TCP on port 22",
"tcp": "localhost:22",
"interval": "10s",
"timeout": "1s"
}
}
script脚本方式
脚本方式略有不同,原理是通过调用脚本,查看脚本的返回值来判断健康检查是否通过
脚本退出代码为 0 : 通过健康检查
1 : 警告 其他: 健康检查失败
{
"check": {
"id": "mem-util",
"name": "Memory utilization",
"args": ["/usr/local/bin/check_mem.py", "-limit", "256MB"], // 会被拼成 /usr/local/bin/check_mem.py -limit 256MB 来进行调用
"interval": "10s",
"timeout": "1s"
}
}
grpc方式
检查grpc整个server状态
{
"check": {
"id": "mem-util",
"name": "Service health status",
"grpc": "127.0.0.1:12345",
"grpc_use_tls": true, //是否使用tls, 默认不使用
"interval": "10s"
}
}
只检查服务器上的某一个服务
{
"check": {
"id": "mem-util",
"name": "Service health status",
"grpc": "127.0.0.1:12345/my_service",
"grpc_use_tls": true,
"interval": "10s"
}
}
go使用官方api包来定义服务\查询服务
console的github官网提供了一个go包操作consul服务端的实现, 我们可以使用这个包来实现服务发现
那么编写一个使用consul注册服务的服务端程序的核心逻辑是这样:
创建consul客户端
使用创建的consul客户端连接相应的consul agent
向consul注册服务
运行服务
运行完毕后向consul注销服务
示例代码:
package main
import (
"log"
"net"
"github.com/hashicorp/consul/api"
)
func main() {
// 使用默认配置创建consul客户端
consulClient, err := api.NewClient(api.DefaultConfig())
if err != nil {
log.Fatal(err)
}
// 注册服务
// consulClient.Agent()先获取当前机器上的consul agent节点
consulClient.Agent().ServiceRegister(&api.AgentServiceRegistration{
ID: "MyService",
Name: "My Service",
Address: "127.0.0.1",
Port: 5050,
Check: &api.AgentServiceCheck{
CheckID: "MyService",
TCP: "127.0.0.1:5050",
Interval: "10s",
Timeout: "1s",
},
})
// 运行完成后注销服务
defer consulClient.Agent().ServiceDeregister("MyService")
l, err := net.Listen("tcp", ":5050")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
go func() {
log.Printf("Ip: %s connected", conn.RemoteAddr().String())
}()
}
}
我们通过tcp每10秒进行健康检查, 输出窗口每10秒就会输出有新连接到来, 这是consul做的
$ go run .
2022/06/09 20:17:51 Ip: 127.0.0.1:53011 connected
2022/06/09 20:18:01 Ip: 127.0.0.1:53038 connected
2022/06/09 20:18:11 Ip: 127.0.0.1:53045 connected
那么服务的请求端(客户端)需要通过consul来获取服务的地址和端口,则需要这么几步:
创建consul客户端
使用创建的consul客户端连接相应的consul agent
向consul请求相应服务id的注册信息
如果获取到了相应的注册信息, 就通过地址和端口请求服务
代码示例:
package main
import (
"fmt"
"log"
"github.com/hashicorp/consul/api"
)
func main() {
consulClient, err := api.NewClient(api.DefaultConfig())
if err != nil {
log.Fatal(err)
}
service, _, err := consulClient.Agent().Service("MyService", nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Got Service: ip-%s, port-%d", service.Address, service.Port)
}
保证服务端运行的情况运行客户端:
$ go run .
Got Service: ip-127.0.0.1, port-5050
Consul使用Raft算法保证集群一致性
来源:https://blog.csdn.net/qq_35621436/article/details/125210475


猜你喜欢
- 本文实例形式讲解了Python3的条件与循环控制语句及其用法,是学习Python所必须掌握的重要知识点,现共享给大家供大家参考。具体如下:一
- MySQLMySQL的特点1、性能卓越,服务稳定,很少出现异常宕机;2、开放源代码无版本制约,自主性及使用成本低;3、历史悠久,社区和用户非
- 一、修改操作系统核心参数在Root用户下执行以下步骤:1)修改用户的SHELL的限制,修改/etc/security/limits.conf
- 无法打开用户默认数据库,登录失败,其原因是登录帐户的默认数据库被删除。 解决办
- 本文实例讲述了Django框架视图介绍与使用。分享给大家供大家参考,具体如下:视图视图:即一个python函数,可以叫 视图函数,或者简称
- 最近,带领我的学生进行一个URTP项目设计,需要进行人脸识别。由于现在的OpenCV已经到了2.X版本,因此就不想用原来的1.X版本的代码,
- 前言当你逐渐了解tushare之后,你会发现我们要进行数据分析只靠tushare是不够的,接下来我将介绍如何利用第三方软件将tushare获
- 本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下#!/usr/bin/env python# -*- c
- 前言ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是
- 前言如何从图像中提取特征?第一次听说“特征提取”一词是在 YouTube 上的机器学习视频教程中,它
- 一、维数的变形1. 一维数组转二维数组以及同维变换import numpy as nparr_1d = np.arange(12)# 使用
- 说明:这里仅展示在已经获取图片链接后的下载方式,对于爬虫获取链接部分参考前面的文章1、利用文件读写的方式下载图片#第一种:用urllib2模
- 一、os__file__ 获取当前运行的.py文件所在的路径(D:\PycharmProjects\
- 具体代码如下所示:# 时间的替换import time,datetimetoday = datetime.datetime.today()p
- 前情提要好久没有写Vue了,略有生疏,这个东西还是得多用。下午看到一个需求,选择相册图片作为轮播图显示。接口返回相册列表,用户选一下再扔回去
- 最近看Python看得都不用tab键了,哈哈。今天看了一个经典问题--八皇后问题,说实话,以前学C、C++的时候有这个问题,但是当时不爱学,
- docker-compose.yal文件中: redis: image: redis container_name:
- 我和朋友对此的看法有分歧,我明明记得有不需要返回的时候的?你的看法是对的,例如在表中删除记录。我们来看看下面的例子——在Employee表中
- django是python语言快速实现web服务的大杀器,其开发效率可以非常的高!但因为秉承了语言的灵活性,django框架又太灵活,以至于
- 下面看下python调用函数加括号和不加括号的区别,具体代码如下所示; def bracket(data):return dat