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中使用M2Crypto模块实现AES加密的教程
Apr 08 Python
Python中的random()方法的使用介绍
May 15 Python
python监控文件或目录变化
Jun 07 Python
python实现自动发送邮件发送多人、群发、多附件的示例
Jan 23 Python
Django添加favicon.ico图标的示例代码
Aug 07 Python
python2.7 安装pip的方法步骤(管用)
May 05 Python
python pyinstaller 加载ui路径方法
Jun 10 Python
python爬虫 基于requests模块发起ajax的get请求实现解析
Aug 20 Python
分享8点超级有用的Python编程建议(推荐)
Oct 13 Python
python序列类型种类详解
Feb 26 Python
解决运行出现'dict' object has no attribute 'has_key'问题
Jul 15 Python
Jupyter安装拓展nbextensions及解决官网下载慢的问题
Mar 03 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
php生成圆角图片的方法
2015/04/07 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
Javascript 刷新全集常用代码
2009/11/22 Javascript
asp.net+js 实现无刷新上传解析csv文件的代码
2010/05/17 Javascript
那些年,我还在学习jquery 学习笔记
2012/03/05 Javascript
js导航栏单击事件背景变换示例代码
2014/01/13 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
2014/10/30 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
JQuery给网页更换皮肤的方法
2015/05/30 Javascript
用JS实现图片轮播效果代码(一)
2016/06/26 Javascript
window.close(); 关闭浏览器窗口js代码的总结介绍
2016/07/14 Javascript
ASP.NET jquery ajax传递参数的实例
2016/11/02 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】
2018/05/07 Javascript
微信小程序自定义可滑动日历界面
2018/12/28 Javascript
vue以组件或者插件的形式实现throttle或者debounce
2019/05/22 Javascript
js正则匹配多个全部数据问题
2019/12/20 Javascript
PyMongo安装使用笔记
2015/04/27 Python
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
python中的break、continue、exit()、pass全面解析
2017/08/05 Python
python 多维切片之冒号和三个点的用法介绍
2018/04/19 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
python中cPickle类使用方法详解
2018/08/27 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
Python读取指定日期邮件的实例
2019/02/01 Python
python之pexpect实现自动交互的例子
2019/07/25 Python
Python 3.8 新功能全解
2019/07/25 Python
Python3直接爬取图片URL并保存示例
2019/12/18 Python
整理HTML5中支持的URL编码与字符编码
2016/02/23 HTML / CSS
五分钟学会HTML5的WebSocket协议
2019/11/22 HTML / CSS
机械专业应届生求职信
2013/12/12 职场文书
2014年国庆节广播稿
2014/09/19 职场文书
云台山导游词
2015/02/03 职场文书
2015年客服工作总结范文
2015/04/02 职场文书
python解决12306登录验证码的实现
2021/04/18 Python
TV动画《八十龟酱观察日记》第四季宣传PV公布
2022/04/06 日漫