Python通过zookeeper实现分布式服务代码解析


Posted in Python onJuly 22, 2020

借助zookeeper可以实现服务器的注册与发现,有需求的时候调用zookeeper来发现可用的服务器,将任务均匀分配到各个服务器上去.

这样可以方便的随任务的繁重程度对服务器进行弹性扩容,客户端和服务端是非耦合的,也可以随时增加客户端.

zk_server.py

import threading
import json
import socket
import sys
from kazoo.client import KazooClient


# TCP服务端绑定端口开启监听,同时将自己注册到zk
class ZKServer(object):
  def __init__(self, host, port):
    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.host = host
    self.port = port
    self.sock.bind((host, port))
    self.zk = None

  def serve(self):
    """
    开始服务,每次获取得到一个信息,都新建一个线程处理
    """
    self.sock.listen(128)
    self.register_zk()
    print("开始监听")
    while True:
      conn, addr = self.sock.accept()
      print("建立链接%s" % str(addr))
      t = threading.Thread(target=self.handle, args=(conn, addr))
      t.start()

  # 具体的处理逻辑,只要接收到数据就立即投入工作,下次没有数据本次链接结束
  def handle(self, conn, addr):
    while True:
      data=conn.recv(1024)
      if not data or data.decode('utf-8') == 'exit':
        break
      print(data.decode('utf-8'))
    conn.close()
    print('My work is done!!!')

  # 将自己注册到zk,临时节点,所以连接不能中断
  def register_zk(self):
    """
    注册到zookeeper
    """
    self.zk = KazooClient(hosts='127.0.0.1:2181')
    self.zk.start()
    self.zk.ensure_path('/rpc') # 创建根节点
    value = json.dumps({'host': self.host, 'port': self.port})
    # 创建服务子节点
    self.zk.create('/rpc/server', value.encode(), ephemeral=True, sequence=True)

if __name__ == '__main__':
  if len(sys.argv) < 3:
    print("usage:python server.py [host] [port]")
    exit(1)
  host = sys.argv[1]
  port = sys.argv[2]
  server = ZKServer(host, int(port))
  server.serve()

zk_client.py

import random
import sys
import time
import json
import socket

from kazoo.client import KazooClient


# 客户端连接zk,并从zk获取可用的服务器列表
class ZKClient(object):
  def __init__(self):
    self._zk = KazooClient(hosts='127.0.0.1:2181')
    self._zk.start()
    self._get_servers()

  def _get_servers(self, event=None):
    """
    从zookeeper获取服务器地址信息列表
    """
    servers = self._zk.get_children('/rpc', watch=self._get_servers)
    # print(servers)
    self._servers = []
    for server in servers:
      data = self._zk.get('/rpc/' + server)[0]
      if data:
        addr = json.loads(data.decode())
        self._servers.append(addr)

  def _get_server(self):
    """
    随机选出一个可用的服务器
    """
    return random.choice(self._servers)

  def get_connection(self):
    """
    提供一个可用的tcp连接
    """
    sock = None
    while True:
      server = self._get_server()
      print('server:%s' % server)
      try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((server['host'], server['port']))
      except ConnectionRefusedError:
        time.sleep(1)
        continue
      else:
        break
    return sock
if __name__ == '__main__':
  # 模拟多个客户端批量生成任务,推送给服务器执行
  client = ZKClient()
  for i in range(40):
    sock = client.get_connection()
    sock.send(bytes(str(i), encoding='utf8'))
    sock.close()
    time.sleep(1)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现二分法算法实例
Feb 02 Python
Python中处理字符串的相关的len()方法的使用简介
May 19 Python
详解用TensorFlow实现逻辑回归算法
May 02 Python
python中的数据结构比较
May 13 Python
Python 虚拟空间的使用代码详解
Jun 10 Python
Python 获取 datax 执行结果保存到数据库的方法
Jul 11 Python
Python 多线程其他属性以及继承Thread类详解
Aug 28 Python
Python流程控制 if else实现解析
Sep 02 Python
Pytorch之卷积层的使用详解
Dec 31 Python
PyTorch和Keras计算模型参数的例子
Jan 02 Python
使用tensorflow框架在Colab上跑通猫狗识别代码
Apr 26 Python
Python 如何展开嵌套的序列
Aug 01 Python
Selenium python时间控件输入问题解决方案
Jul 22 #Python
Python基于字典实现switch case函数调用
Jul 22 #Python
Jmeter HTTPS接口测试证书导入过程图解
Jul 22 #Python
使用python批量修改XML文件中图像的depth值
Jul 22 #Python
Python持续监听文件变化代码实例
Jul 22 #Python
Python不支持 i ++ 语法的原因解析
Jul 22 #Python
基于selenium及python实现下拉选项定位select
Jul 22 #Python
You might like
Zend Framework分页类用法详解
2016/03/22 PHP
PHP编程实现微信企业向用户付款的方法示例
2017/07/26 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
2018/06/20 PHP
php的RSA加密解密算法原理与用法分析
2020/01/23 PHP
javascript 限制输入和粘贴(IE,firefox测试通过)
2008/11/14 Javascript
js点击页面其它地方将某个显示的DIV隐藏
2012/07/12 Javascript
js日期对象兼容性的处理方法
2014/01/28 Javascript
js打开新窗口方法整理
2014/02/17 Javascript
jquery操作checked属性以及disabled属性的多种方法
2014/06/20 Javascript
移动手机APP手指滑动切换图片特效附源码下载
2015/11/30 Javascript
js仿微博实现统计字符和本地存储功能
2015/12/22 Javascript
TinyMCE汉化及本地上传图片功能实例详解
2016/05/31 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
2016/09/12 Javascript
jQuery 实时保存页面动态添加的数据的示例
2017/08/14 jQuery
Vue仿支付宝支付功能
2018/05/25 Javascript
使用JavaScript中的lodash编写双色球效果
2018/06/24 Javascript
vue中通过使用$attrs实现组件之间的数据传递功能
2019/09/01 Javascript
VUEX采坑之路之获取不到$store的解决方法
2019/11/08 Javascript
jQuery加PHP实现图片上传并提交的示例代码
2020/07/16 jQuery
vue+echarts实现动态折线图的方法与注意
2020/09/01 Javascript
[03:09]2014DOTA2国际邀请赛 赛场上的美丽风景线 中国Coser也爱DOTA2
2014/07/20 DOTA
[02:12]2015国际邀请赛 SHOWOPEN
2015/08/05 DOTA
[01:04:48]VGJ.S vs TNC Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[01:01:36]Optic vs paiN 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
使用Python编写爬虫的基本模块及框架使用指南
2016/01/20 Python
python如何使用unittest测试接口
2018/04/04 Python
神经网络(BP)算法Python实现及应用
2018/04/16 Python
Python内存管理实例分析
2019/07/10 Python
Python定义一个Actor任务
2020/07/29 Python
基于 Python 实践感知器分类算法
2021/01/07 Python
薇诺娜官方网上商城:专注敏感肌肤
2017/05/25 全球购物
如何利用cmp命令比较文件
2013/09/23 面试题
为什么要做架构设计
2015/07/08 面试题
网上商城创业计划书范文
2014/01/31 职场文书
乡镇庆八一活动方案
2014/02/02 职场文书
企业承诺书格式范文
2015/04/28 职场文书