python通过consul完成服务发现及访问

consul简介

consul是一种分布式管理工具。主要可以作为服务发现或分布式配置工具来使用。此处默认您已经安装好consul并启动。

1、服务注册有什么用?

通俗来讲,就是可以知道你有多少种服务在用,是否可用(consul有服务监控检查)。服务集群有哪些节点。其次是API网关可以通过服务中心获取到服务转发的地址。例如consul有个服务的集群名字为user-groups,我们要访问这个集群的api接口,接口的endpoint为/user/info。通过zuul可以这样访问:直接访问 http://<zuul host>:<zuul port>/user-groups/user/info。zuul会通过consul自己找到该转发的api地址。

2、分布式配置工具

分布式配置工具将配置存在内存中,你的项目可以在不重启的情况下,读取一个可以动态改变的配置的值。

python通过consul完成服务注册

import consul
import threading
from flask import Flask
from random import choice, choices

class AiopsConsul(object):
    def __init__(self, consul_host="127.0.0.1", consul_port=8500, host="127.0.0.1"):
        """初始化,连接consul服务器"""
        self.host = host
        self._consul = consul.Consul(consul_host, consul_port)
        self.service_weight = {}

    def register_service(self, name, host, port, tags=None):
        tags = tags or []
        # 注册服务
        self._consul.agent.service.register(
            name,
            name,
            host,
            port,
            tags,
            # 健康检查ip端口,检查时间:5,超时时间:30,注销时间:30s
            check=consul.Check().tcp(host, port, "5s", "30s", "30s"))

    def get_service(self, name):
        _, nodes = self._consul.health.service(service=name, passing=True)
        if len(nodes) == 0:
            raise Exception('service is empty.')
        weights = []
        for node in nodes:
            service = node.get('Service')
            address = "http://{0}:{1}".format(service['Address'], service['Port'])
            if self.service_weight.get(address) is None:
                self.service_weight[address] = 100
            weights.append(self.service_weight[address])
        service = choices(nodes, weights=weights, k=1)[0].get("Service")
        return "http://{0}:{1}".format(service['Address'], service['Port'])

    def update_weight(self, address, success):
        if success is True:
            self.service_weight[address] = max(100, self.service_weight[address]+5)
        else:
            self.service_weight[address] = max(100, self.service_weight[address]/2)

    def app(self):
        app = Flask(__name__)
        @app.route('/health', methods=['GET'])
        def get_task():
            return '{"status":"UP"}'

        app.run(debug=False, host='0.0.0.0', port=8893)

    def health(self):
        """注册服务"""
        self.register_service("XXXXX", self.host, 8893)
        consul.Check().tcp(self.host, 8893, "5s", "30s", "30s")

        t = threading.Thread(target=self.app, name='LoopThread')
        t.start()


if __name__ == '__main__':
    c = AiopsConsul('default.consul_url')
    print(c.get_service("task"))

python通过consul完成服务发现

我们实现Feign类:一个使用起来更加方便的 HTTP 客户端。采用接口的方式, 将需要调用的其他服务的方法定义成抽象方法, 不需要自己构建 http 请求。然后就像是调用自身工程的方法调用,而感觉不到是调用远程方法,使得编写 客户端变得非常容易。

import requests
import logging
from manage.aiops_consul import AiopsConsul


class XXXXXFeign(object):
    def __init__(self, project='aiops-station-model'):
        """初始化,连接consul服务器"""
        self.sr = SR(project)
        self.aiops_consul = AiopsConsul(consul_host=self.sr.getProperty('default.consul_url'),
                                        consul_port='default.consul_port')
        self.client = requests.session()
        self.headers = {'Content-Type': 'application/json', 'Connection': 'keep-alive',
                        'buc-auth-token': 'default.buc-auth-token'}

    def get(self, uri):
        try_count = 0
        while try_count < 5:
            address = self.aiops_consul.get_service('service')
            url = '{0}{1}'.format(address, uri)
            response = self.client.get(
                url=url,
                headers=self.headers)
            if response.status_code is 200:
                self.aiops_consul.update_weight(address, success=True)
                return response.content
            self.aiops_consul.update_weight(address, success=False)
            try_count += 1
            logging.warning('{0}: status_code is {1}'.format(url, response.status_code))
        raise Exception('service service is error')

    def post(self, uri, data):
        try_count = 0
        while try_count < 5:
            address = self.aiops_consul.get_service('service)
            url = '{0}{1}'.format(address, uri)
            response = self.client.post(
                url=url,
                headers=self.headers,
                data=data)
            if response.status_code is 200:
                self.aiops_consul.update_weight(address, success=True)
                return response.content
            self.aiops_consul.update_weight(address, success=False)
            try_count += 1
            logging.warning('{0}: status_code is {1}'.format(url, response.status_code))
        raise Exception('service service is error')

    def get_task(self, task_id, user):
        return self.get('/task/get/{0}?user={1}'.format(task_id, user))

    def get_and_run_task(self, task, user):
        return self.get('/task/getAndRun/{0}?user={1}'.format(task, user))


if __name__ == '__main__':
    feign = AiopsStarLinkFeign()
    print(feign.get_task('', user='sun'))
    print(feign.get_and_run_task(task="task", user='sun'))

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352