• consul 下线服务 服务注销脚本


    一、获取服务名

    1. 登陆 consul UI 平台, 找到我们对应的服务,他们服务在 consul 中的名称。

    二、 脚本

    注销基于的api: http://{}:{}/v1/agent/service/deregister/{}

    注销脚本:

    #!/usr/bin/env   python3
    # -*- coding: utf-8 -*-
    # @Time    : 2021/3/29 10:26
    # @Author  : dongjiaxiao
    # @Email   : 
    # @File    : consul_deregister.py
    # @Desc    :
    
    import requests
    import json
    import logging
    import sys
    
    
    def http_request(url, methods):
        if methods == 'get':
            try:
                responce = requests.get(url=url, timeout=5)
                res_data = responce.json()
            except Exception as e:
                logging.error(e)
        elif methods == 'put':
            try:
                responce = requests.put(url=url, timeout=5)
                res_data = responce.status_code
            except Exception as e:
                logging.error(e)
        return res_data
    
    
    def get_node_ip(nodeName):
        """
        获取nodeName 对应的IP
        :param nodeName:
        :return:
        """
        node_url = "http://{}:{}/v1/catalog/node/{}".format(consul_host, consul_port, nodeName)
        node_data = http_request(node_url, 'get')
        node_ip = node_data["Node"].get('Address', '')
        return node_ip
    
    
    def check_service(service_name):
        """
        检查服务
        :return:
        """
        res = {'critical':[], 'passing': []}
        chek_url = 'http://{}:{}/v1/health/checks/{}'.format(consul_host, consul_port, service_name)
        check_data = http_request(chek_url, 'get')
        if check_data:
            for i in check_data:
                if i['Status'] == 'critical':
                    node_ip = get_node_ip(i['Node'])
                    res['critical'].append({'serviceID': i['ServiceID'], 'node': i['Node'], 'ip': node_ip})
                elif i['Status'] == 'passing':
                    node_ip = get_node_ip(i['Node'])
                    res['passing'].append({'serviceID': i['ServiceID'], 'node': i['Node'], 'ip': node_ip})
            return res
        else:
            logging.error("未找到服务 {}".format(service_name))
            return "未找到服务 {}".format(service_name)
    
    
    def check_node_service(service_name, hostIp):
        """
        基于 服务名和 主机ip 进行查找节点信息
        :param service_name:
        :return:
        """
        res = []
        chek_url = 'http://{}:{}/v1/health/checks/{}'.format(consul_host, consul_port, service_name)
        check_data = http_request(chek_url, 'get')
        if check_data:
            for i in check_data:
                node_ip = get_node_ip(i['Node'])
                if node_ip == hostIp:
                    res.append({'serviceID': i['ServiceID'], 'node': i['Node'], 'ip': hostIp})
        return res
    
    
    
    def deregister_operation(nodeIp, serviceId):
        """
        注销服务
        :param nodeIp:
        :param serviceId:
        :return:
        """
        deregister_url = 'http://{}:{}/v1/agent/service/deregister/{}'.format(nodeIp, consul_port, serviceId)
        res = http_request(deregister_url, 'put')
        logging.info("注销节点url: {}  res: {}".format(deregister_url, res))
        return res
    
    
    def deregister_service(service_name):
        res = check_service(service_name)
        if isinstance(res, dict):
            critical_service = res.get('critical')
            if critical_service:
                data = {"异常节点": [], '已经注销节点': []}
                for service_data in critical_service:
                    serviceId = service_data.get('serviceID')
                    nodeIp = service_data.get('ip')
                    data['异常节点'].append(serviceId)
                    if serviceId and nodeIp:
                        res_code = deregister_operation(nodeIp, serviceId)
                        if res_code == 200:
                            data['已经注销节点'].append(serviceId)
                    else:
                        logging.error("serviceId  {} and nodeIp {}  缺少参数".format(serviceId, nodeIp))
                return data
            else:
                return "未找到异常节点"
        return res
    
    
    def deregister_service_host(service_name, hostIp):
        """
        基于 服务名和 主机ip 进行注销对应主机上的节点信息
        :param service_name:
        :return:
        """
        res = check_node_service(service_name, hostIp)
        if res:
            data = {"需要注销节点": [], '已经注销节点': []}
            for service_data in res:
                serviceId = service_data.get('serviceID')
                nodeIp = service_data.get('ip')
                data['需要注销节点'].append(serviceId)
                if serviceId and nodeIp:
                    res_code = deregister_operation(nodeIp, serviceId)
                    if res_code == 200:
                        data['已经注销节点'].append(serviceId)
                        logging.info("serviceId  {} and nodeIp {}, res: {} ".format(serviceId, nodeIp, res))
                else:
                    logging.error("serviceId  {} and nodeIp {}  缺少参数".format(serviceId, nodeIp))
            return data
        return '在主机未找到该服务'
    
    
    if __name__ == '__main__':
        consul_host = '10.60.6.37'
        consul_port = '8500'
        file_handler = logging.FileHandler(filename='./consul_deregister.log', encoding='utf-8')
        logging.basicConfig(format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt='%Y-%m-%d %H:%M:%S',
                            level=logging.INFO, handlers={file_handler})
        if len(sys.argv) == 3 and sys.argv[1] == "check":  # 获取异常节点
            service_name = sys.argv[2]
            data = check_service(service_name)
            if isinstance(data, dict):
                print("异常节点信息: {}".format(data.get('critical')))
                print("正常节点信息: {}".format(data.get('passing')))
            else:
                print(data)
        elif len(sys.argv) == 3 and sys.argv[1] == "deregister":  # 注销异常节点, 指定服务名
            service_name = sys.argv[2]
            print(deregister_service(service_name))
        elif len(sys.argv) == 4 and sys.argv[1] == "deregister":  # 注销异常节点, 指定服务名和ip
            service_name = sys.argv[2]
            hostIp = sys.argv[3]
            print(deregister_service_host(service_name, hostIp))
        elif len(sys.argv) == 4 and sys.argv[1] == "deregister_serviceid":  # 注销异常节点, 指定nodeip(注册的consul client ip) 和  service_id
            hostIp = sys.argv[3]
            service_id = sys.argv[2]
            print(deregister_operation(hostIp, service_id))
        else:
            print("please  use parameter  check|deregister  service_name")
    

    三、基本功能操作

    1. 获取某个服务当前状态。

       python3 consul_tools.py check cmdb-front-dp-test
      

      响应:

      [root@djx scripts]# python3 consul_tools.py check cmdb-front-dp-test
      异常节点信息: []
      正常节点信息: [{'serviceID': 'docker-57-58.baidu.com:cmdb-front-dp_0_22fecc7-190308.170959:80', 'node': 'docker-57-58.baidu.com', 'ip': '192.168.57.58'}]
      
      
    2. 注销服务当前异常节点

      会拿上面异常节点的信息,然后进行注销服务

      python3 consul_tools.py deregister  cmdb-front-dp-test
      

      响应:

      • 未找到节点

      • {'异常节点': ['docker-110-89.baidu.com:user-server-sit-skywalking_0_v2.1:8080'], '已经注销节点': ['docker-110-89.baidu.com:user-server-sit-skywalking_0_v2.1:8080']}
        
    3. 下线指定机器 ip 上的指定服务

      适用场景:

      • 某机器上的某个节点忽好忽坏,我们获取机器ip 和 服务名后,不管该服务是否健康检查通过,都将其下线。

      不管该机器上的对应服务节点是正常,还是异常都会进行下线。

      python3 consul_tools.py deregister  cmdb-front-dp-test  10.57.57.58
      

      响应:

      1. 如果在主机上未找到

        在主机未找到该服务
        
      2. 下线

        {'需要注销节点': ['docker-10-58.baidu.com:cmdb-front-dp_0_22fecc7-190308.170959:80'], '已经注销节点': ['docker-10-58.baidu.com:cmdb-front-dp_0_22fecc7-190308.170959:80']}
        
    4. 已经知道要下线的服务的 ID ,形如, docker-10-58.baidu.com:cmdb-front-dp_0_22fecc7-190308.170959:80 和 知道该服务注册的 consul ip

      python3 consul_tools.py deregister_serviceid   192.168.57.58  docker-10-58.baidu.com:cmdb-front-dp_0_22fecc7-190308.170959:80
      
    作者:理想三旬
    出处:
    如果觉得文章写得不错,或者帮助到您了,请点个赞,加个关注哦。运维学习交流群:544692191
    本文版权归作者所有,欢迎转载,如果文章有写的不足的地方,或者是写得错误的地方,请你一定要指出,因为这样不光是对我写文章的一种促进,也是一份对后面看此文章的人的责任。谢谢。
  • 相关阅读:
    spring boot 2.1学习笔记【五】SpringBootTest单元测试及日志
    Java网络编程-UDP
    Java网络编程-TCP
    String的特性
    内存池的使用
    软件定时器的使用
    邮箱
    事件集
    线程优先级翻转
    临界区,互斥量与信号量
  • 原文地址:https://www.cnblogs.com/operationhome/p/14953693.html
Copyright © 2020-2023  润新知