NodeJs和go中使用consul做服务发现

·  阅读 1015
NodeJs和go中使用consul做服务发现

一、环境的安装

  • 1、安装docker

    curl -fsSL https://get.docker.com | bash -s docker --mirror aliyun
    复制代码
    curl -sSL https://get.daocloud.io/docker | sh
    复制代码
    docker version
    复制代码
  • 2、使用docker安装consul

    安装镜像

    docker pull consul
    复制代码

    启动容器

    docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp consul consul agent -dev -client=0.0.0.0
    复制代码

    一直启动

    docker container update --restart=always 容器的ID
    复制代码
  • 3、在客户端浏览器上输入ip地址:8500,注意如果是服务器端配置的话要开放端口号

二、关于consul的常见的API

三、NodeJs自己实现API操作

  • 1、在nodejs中使用上面的API来注册一个服务

    const axios = require('axios');
    
    const register = async (name, id, address, port) =>{
      const url = 'http://xxx:8500/v1/agent/service/register';
      const data = {
        "Name":name,
        "ID":id,
        "Tags":["test","node","axios"],
        "Address":address,
        "Port":port,
      };
      // 注册服务
      await axios.put(url,data);
    }
    register("node-consul", "node-consul","127.0.0.1", 50000)
    复制代码

在这里插入图片描述

  • 2、删除服务

    const axios = require('axios');
    const deregister = async (id) => {
      const url = `http://localhost:8500/v1/agent/service/deregister/${id}`;
      const response = await axios.put(url);
      console.log(response);
    }
    
    deregister('node-consul');
    复制代码
  • 3、配置健康检查

    gin启动一个服务(这里你也可以用nodejava来启动一个服务)

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	router :=gin.Default()
    	router.GET("/health", func(ctx *gin.Context) {
    		ctx.JSON(http.StatusOK, gin.H{
    			"code": "0",
    			"message": "成功",
    		})
    	})
    	router.Run(":8080")
    }
    复制代码

    使用node来实现服务器注册和健康检查

    注意这里你本地的启动的服务必须要和consuleip可以ping通,因此这里选用本地的consul

    const axios = require('axios');
    
    const register = async (name, id, address, port) => {
      // 使用本地的consul
      const url = 'http://localhost:8500/v1/agent/service/register';
      const data = {
        Name: name,
        ID: id,
        Tags: ['test', 'node', 'axios'],
        Address: address,
        Port: port,
        Check: {
          // gin项目启动的地址
          HTTP: 'http://localhost:8080/health',
          Timeout: '5s',
          Interval: '5s',
          DeregisterCriticalServiceAfter: '5s',
        },
      };
      // 注册服务
      await axios.put(url, data);
    };
    // 注意这里是gin的地址和端口号
    register('node-consul', 'node-consul', 'localhost', 8080);
    复制代码

    没有配置健康检查的时候

    在这里插入图片描述

    配置了健康检查的时候 在这里插入图片描述

    gin后台中每个5s就重新请求一次,也有点类似socket中的心跳检测

    在这里插入图片描述

  • 4、获取服务列表

    const axios = require('axios');
    
    const servicesList = async (filter='') =>{
      let url;
      if (filter) {
        url = `http://localhost:8500/v1/agent/services?filter=${filter}`
      } else {
        url = 'http://localhost:8500/v1/agent/services'
      }
      const response = await axios.get(url);
      console.log(response.data);
    }
    
    servicesList()
    复制代码
    # 返回结果
    {
      'node-consul': {
        ID: 'node-consul',
        Service: 'node-consul',
        Tags: [ 'test', 'node', 'axios' ],
        Meta: {},
        Port: 50000,
        Address: '127.0.0.1',
        SocketPath: '',
        TaggedAddresses: { lan_ipv4: [Object], wan_ipv4: [Object] },
        Weights: { Passing: 1, Warning: 1 },
        EnableTagOverride: false,
        Datacenter: 'dc1'
      }
    }
    复制代码

四、在go中实现与consul对接

  • 1、安装依赖包 官方地址

    go get -u github.com/hashicorp/consul/api
    复制代码
  • 2、服务注册

    package main
    
    import (
    	"fmt"
    	"github.com/hashicorp/consul/api"
    )
    
    func Register(name string, id string, address string, port int, tags []string) error {
    	cfg := api.DefaultConfig()
    	cfg.Address = "localhost:8500"
    	client, err := api.NewClient(cfg)
    	if err != nil {
    		panic(err)
    	}
    	// 健康检查
    	check := &api.AgentServiceCheck{
    		HTTP:                           "http://localhost:8080/health",
    		Timeout:                        "5s",
    		Interval:                       "5s",
    		DeregisterCriticalServiceAfter: "10s",
    	}
    	// 注册对象
    	registration := new(api.AgentServiceRegistration)
    	registration.Name = name
    	registration.ID = id
    	registration.Port = port
    	registration.Tags = tags
    	registration.Address = address
    	registration.Check = check
    
    	err = client.Agent().ServiceRegister(registration)
    	// 注意这个地方不能直接写id
    	_ = client.Agent().ServiceDeregister(fmt.Sprintf("%s_test", id))
    	if err != nil {
    		panic(err)
    	}
    	fmt.Println("服务注册完成")
    	return nil
    }
    
    func main() {
    	Register("go_consul", "go_consul", "localhost", 8080, []string{"go", "consul", "test"})
    }
    复制代码
  • 3、服务注销

    package main
    
    import (
    	"github.com/hashicorp/consul/api"
    )
    
    func Deregister(address, serviceName string) {
    	cfg := api.DefaultConfig()
    	cfg.Address = address
    
    	client, err := api.NewClient(cfg)
    	if err != nil {
    		panic(err)
    	}
    
    	err = client.Agent().ServiceDeregister(serviceName)
    	if err != nil {
    		panic(err)
    	}
    }
    
    func main() {
    	Deregister("localhost:8500", "go_consul")
    }
    复制代码
  • 4、获取服务列表

    package main
    
    import (
    	"fmt"
    	"github.com/hashicorp/consul/api"
    )
    
    func AllServices(address string) {
    	cfg := api.DefaultConfig()
    	cfg.Address = address
    	client, err := api.NewClient(cfg)
    	if err != nil {
    		panic(err)
    	}
    	// 获取全部的服务
    	data, err := client.Agent().Services()
    	if err != nil {
    		panic(err)
    	}
    
    	for key,_ := range data {
    		fmt.Println(key)
    	}
    }
    
    func main() {
    	AllServices("localhost:8500")
    }
    复制代码
  • 5、过滤服务

    package main
    
    import (
    	"fmt"
    	"github.com/hashicorp/consul/api"
    )
    
    func FilterService(address, filterId string) {
    	cfg := api.DefaultConfig()
    	cfg.Address = address
    
    	client, err := api.NewClient(cfg)
    	if err != nil {
    		panic(err)
    	}
    
    	data, err := client.Agent().ServicesWithFilter(fmt.Sprintf("Service ==%s", filterId))
    	if err != nil {
    		panic(err)
    	}
    	for key, _ := range data {
    		fmt.Println(key)
    	}
    }
    
    func main() {
    	FilterService("localhost:8500", "go_consul")
    }
    复制代码
分类:
后端
标签: