1. 程式人生 > >使用consul做服務註冊[附Python微服務demo]

使用consul做服務註冊[附Python微服務demo]

consul是一種分散式管理工具。主要可以作為服務發現或分散式配置工具來使用。此處預設您已經安裝好consul並啟動,請順便啟動ui模組(consul agent -dev -ui),方便後續檢視除錯。

1、服務註冊有什麼用?通俗來講,就是可以知道你有多少種服務在用,是否可用(consul有服務監控檢查)。服務叢集有哪些節點。其次是API閘道器可以通過服務中心獲取到服務轉發的地址。例如consul有個服務的叢集名字為user-groups,我們要訪問這個叢集的api介面,介面的endpoint為/user/info。通過zuul可以這樣訪問:直接訪問 http://<zuul host>:<zuul port>/user-groups/user/info。zuul會通過consul自己找到該轉發的api地址。

2、分散式配置工具,則是將配置存在記憶體中,你的專案可以在不重啟的情況下,讀取一個可以動態改變的配置的值。

以下為一個Flask微服務的Demo,可以自動使用gunicorn啟動並註冊到consul。支援RPC和Restfull API等專案。歡迎Star。

以下為python註冊到consul的方法,呼叫getServices可以獲取所有註冊到consul中心的服務,register方法可以註冊到consul。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
Created by liaoyangyang1 on 2018/10/30 下午3:54.
"""


import json
import requests
from consulate import Consul
from random import randint


# consul 操作類
class ConsulClient():
    def __init__(self, host=None, port=None, token=None):  # 初始化,指定consul主機,埠,和token
        self.host = host  # consul 主機
        self.port = port  # consul 埠
        self.token = token
        self.consul = Consul(host=host, port=port)

    def register(self, name, service_id, address, port, tags, interval, httpcheck):  # 註冊服務 註冊服務的服務名  埠  以及 健康監測埠
        self.consul.agent.service.register(name, service_id=service_id, address=address, port=port, tags=tags,
                                           interval=interval, httpcheck=httpcheck)

    def deregister(self, service_id):
        # 此處有坑,原始碼用的get方法是不對的,改成put,兩個方法都得改
        self.consul.agent.service.deregister(service_id)
        self.consul.agent.check.deregister(service_id)

    def getService(self, name):  # 負債均衡獲取服務例項
        url = 'http://' + self.host + ':' + str(self.port) + '/v1/catalog/service/' + name  # 獲取 相應服務下的DataCenter
        dataCenterResp = requests.get(url)
        if dataCenterResp.status_code != 200:
            raise Exception('can not connect to consul ')
        listData = json.loads(dataCenterResp.text)
        dcset = set()  # DataCenter 集合 初始化
        for service in listData:
            dcset.add(service.get('Datacenter'))
        serviceList = []  # 服務列表 初始化
        for dc in dcset:
            if self.token:
                url = 'http://' + self.host + ':' + self.port + '/v1/health/service/' + name + '?dc=' + dc + '&token=' + self.token
            else:
                url = 'http://' + self.host + ':' + self.port + '/v1/health/service/' + name + '?dc=' + dc + '&token='
            resp = requests.get(url)
            if resp.status_code != 200:
                raise Exception('can not connect to consul ')
            text = resp.text
            serviceListData = json.loads(text)

            for serv in serviceListData:
                status = serv.get('Checks')[1].get('Status')
                if status == 'passing':  # 選取成功的節點
                    address = serv.get('Service').get('Address')
                    port = serv.get('Service').get('Port')
                    serviceList.append({'port': port, 'address': address})
        if len(serviceList) == 0:
            raise Exception('no serveice can be used')
        else:
            service = serviceList[randint(0, len(serviceList) - 1)]  # 隨機獲取一個可用的服務例項
            return service['address'], int(service['port'])

    def getServices(self):
        return self.consul.agent.services()


if __name__ == '__main__':
    c = ConsulClient('localhost', '8500')
    service_id = 'Messer' + '127.0.0.1' + ':' + str(10107)
    print(c.consul.agent.services())

如果是java程式