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中封装GObject模块进行图形化程序编程的教程
Apr 14 Python
Python+Socket实现基于UDP协议的局域网广播功能示例
Aug 31 Python
Python实现的归并排序算法示例
Nov 21 Python
Python迭代器与生成器基本用法分析
Jul 26 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
Dec 24 Python
关于 Python opencv 使用中的 ValueError: too many values to unpack
Jun 28 Python
python opencv捕获摄像头并显示内容的实现
Jul 11 Python
Python笔记之代理模式
Nov 20 Python
TensorFlow dataset.shuffle、batch、repeat的使用详解
Jan 21 Python
keras 使用Lambda 快速新建层 添加多个参数操作
Jun 10 Python
Django项目创建及管理实现流程详解
Oct 13 Python
python 实现有道翻译功能
Feb 26 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
广播爱好者需要了解的天线知识
2021/03/01 无线电
Laravel中使用FormRequest进行表单验证方法及问题汇总
2016/06/19 PHP
PHP中利用sleep函数实现定时执行功能实现代码
2016/08/25 PHP
php微信公众号开发(3)php实现简单微信文本通讯
2016/12/15 PHP
Laravel5.5新特性之友好报错以及展示详解
2017/08/13 PHP
javascript css在IE和Firefox中区别分析
2009/02/18 Javascript
Javascript类定义语法,私有成员、受保护成员、静态成员等介绍
2011/12/08 Javascript
jquery zTree异步加载简单实例分享
2013/02/05 Javascript
JSON.parse()和JSON.stringify()使用介绍
2014/06/20 Javascript
js中直接声明一个对象的方法
2014/08/10 Javascript
js实现右键菜单功能
2016/11/28 Javascript
javascript 取小数点后几位几种方法总结
2017/08/02 Javascript
jQuery中 DOM节点操作方法大全
2017/10/12 jQuery
iview table render集成switch开关的实例
2018/03/14 Javascript
浅谈如何通过node.js对数据进行MD5加密
2018/05/16 Javascript
layDate日期控件使用方法详解
2018/11/15 Javascript
JavaScript递归函数定义与用法实例分析
2019/01/24 Javascript
python使用循环实现批量创建文件夹示例
2014/03/25 Python
浅谈python中的__init__、__new__和__call__方法
2017/07/18 Python
将字典转换为DataFrame并进行频次统计的方法
2018/04/08 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
python如何创建TCP服务端和客户端
2018/08/26 Python
在python中对变量判断是否为None的三种方法总结
2019/01/23 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
2019/06/03 Python
windows下python虚拟环境virtualenv安装和使用详解
2019/07/16 Python
Django filter动态过滤与排序实现过程解析
2020/11/26 Python
优秀员工自荐信范文
2013/10/05 职场文书
应届大学毕业生找工作的求职信范文
2013/11/29 职场文书
个人简历自我评价
2014/01/06 职场文书
2014年妇幼卫生工作总结
2014/12/09 职场文书
个人工作表现自我评价
2015/03/06 职场文书
2015年小学教科研工作总结
2015/07/20 职场文书
只需要这一行代码就能让python计算速度提高十倍
2021/05/24 Python
python操作xlsx格式文件并读取
2021/06/02 Python
Python爬取奶茶店数据分析哪家最好喝以及性价比
2022/09/23 Python