Golang使用Consul详解

2022-06-15 13:10:44
目录
常用指令常用功能定义服务服务管理服务健康检查go使用官方api包来定义服务查询服务

常用指令

agent指令

    -bind=0.0.0.0>-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:Windowstmp

    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服务端均提供了相应的httpdns等方式的接口可以方便地操作,

      一般我们用go是用官方提供的一个api库进行操作,>

      Consul API

      服务健康检查

      健康检查是为了避免服务突然宕机而调用方不知道的情况发生,>

      consul提供了 tcpsslttludpscripthttp等多种方式来进行健康检查,可以在服务注册时指定健康检查的方式

      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算法保证集群一致性

          到此这篇关于Golang使用Consul详解的文章就介绍到这了,更多相关Golang Consul内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!