consul在node中的实现

493 阅读2分钟

一、使用docker在本地电脑上启动安装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
    
  • 3、启动服务

    docker run -d -p 8500:8500 --restart=always --name=consul consul:latest agent -server -bootstrap -ui -node=1 -client='0.0.0.0'
    
    • 8500 http 端口,用于 http 接口和 web ui
    • 8300 server rpc 端口,同一数据中心 consul server 之间通过该端口通信
    • 8301 serf lan 端口,同一数据中心 consul client 通过该端口通信
    • 8302 serf wan 端口,不同数据中心 consul server 通过该端口通信
    • 8600 dns 端口,用于服务发现
    • -bbostrap-expect 2: 集群至少两台服务器,才能选举集群leader
    • -ui:运行 web 控制台
    • -bind: 监听网口,0.0.0.0 表示所有网口,如果不指定默认未127.0.0.1,则无法和容器通信
    • -client : 限制某些网口可以访问
  • 4、设置开机启动

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

    image-20211030130514878.png

二、封装一个方法获取你本机的ip地址

  • 1、一般我们正常使用方式在黑窗口中输入

    ifconfig
    

    image-20211030125725284.png

  • 2、这里我们提供直接通过程序的方式来获取,方便切换环境的时候不需要手动去修改

    const os = require('os');
    
    const getIPAddress = () => {
      const interfaces = os.networkInterfaces();
      for (const devName in interfaces) {
        const iface = interfaces[devName];
        for (let i = 0; i < iface.length; i++) {
          const alias = iface[i];
          if (
            alias.family === 'IPv4' &&
            alias.address !== '127.0.0.1' &&
            !alias.internal
          ) {
            return alias.address;
          }
        }
      }
    };
    
    module.exports = getIPAddress;
    

三、关于consul的常见的API

四、node中实现注册服务

  • 1、服务注册

    const axios = require('axios');
    const getIPAddress = require('./ip.address');
    
    const register = async (address, port, name, id, tags) => {
      // 这里地址根据你部署的consul的来
      const url = 'http://localhost:8500/v1/agent/service/register';
      const data = {
        Address: address,
        Port: port,
        Name: name,
        ID: id,
        Tags: tags,
      };
      // 注册服务
      await axios.put(url, data);
    };
    const ipAddress = getIPAddress();
    // 这里的name尽量和id保存一致,也可以不一致
    register(ipAddress, 50000, 'node-consul', 'node-consul', [
      'test',
      'node',
      'axios',
    ]);
    
  • 2、查看本地ui的控制台

    image-20211030131524724.png

  • 3、点击这个刚刚注册的服务

    image-20211030132411532.png

五、删除服务

  • 1、调用官方接口实现删除服务

    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.data);
    };
    
    deregister('node-consul');
    
  • 2、刷新浏览器查看页面

六、健康检查

  • 1、本地启动一个express服务,或者你可以写一个死循环的服务,只有服务在不停的运行就可以

    const express = require('express');
    
    const app = express();
    
    app.get('/health', (req, res) => {
      res.json({
        message: '成功',
      });
    });
    
    app.listen(3000, () => {
      console.log('服务已经启动:localhost:3000');
    });
    
  • 2、在注册服务的时候加上健康检查

    const axios = require('axios');
    const getIPAddress = require('./ip.address');
    const ipAddress = getIPAddress();
    
    const register = async (address, port, name, id, tags) => {
      // 这里地址根据你部署的consul的来
      const url = 'http://localhost:8500/v1/agent/service/register';
      const data = {
        Address: address,
        Port: port,
        Name: name,
        ID: id,
        Tags: tags,
        Check: {
          // 刚刚启动的express服务,但是这个地方地址不能写localhost
          HTTP: `http://${ipAddress}:3000/health`,
          Timeout: '5s',
          Interval: '5s',
          DeregisterCriticalServiceAfter: '10s',
        },
      };
      // 注册服务
      await axios.put(url, data);
    };
    
    // 这里的name尽量和id保存一致
    register(ipAddress, 50000, 'node-consul', 'node-consul', [
      'test',
      'node',
      'axios',
    ]);
    
  • 3、查看浏览器上的页面

    image-20211030133039391.png

七、查询全部的服务

  • 1、封装一个方法

    const axios = require('axios');
    
    const servicesList = async (servicesId = '') => {
      let url;
      if (servicesId) {
        url = `http://localhost:8500/v1/agent/service/${servicesId}`;
      } else {
        url = 'http://localhost:8500/v1/agent/services';
      }
      const response = await axios.get(url);
      console.log(response.data);
    };
    
    servicesList('node-consul');
    

八、已经将现有的代码封装成工具包

九、结尾

后期会继续跟新这个包来支持node中的grpc的服务发现,也会将这个服务发现用于nestjs微服务开源项目中