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代码检查工具pylint 让你的python更规范
Sep 05 Python
Python连接PostgreSQL数据库的方法
Nov 28 Python
python构建自定义回调函数详解
Jun 20 Python
Python使用正则表达式过滤或替换HTML标签的方法详解
Sep 25 Python
python如何通过twisted实现数据库异步插入
Mar 20 Python
详解Django rest_framework实现RESTful API
May 24 Python
python3之模块psutil系统性能信息使用
May 30 Python
说说如何遍历Python列表的方法示例
Feb 11 Python
django框架模板语言使用方法详解
Jul 18 Python
python实现批量修改服务器密码的方法
Aug 13 Python
python实现复制大量文件功能
Aug 31 Python
Python pip安装模块提示错误解决方案
May 22 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进行MySQL删除记录操作代码
2008/06/07 PHP
php判断当前操作系统类型
2015/10/28 PHP
PHP实现留言板功能的详细代码
2017/03/25 PHP
Javascript Global对象
2009/08/13 Javascript
JavaScript 原型学习总结
2010/10/29 Javascript
基于jquery的图片的切换(以数字的形式)
2011/02/14 Javascript
基于JQUERY的多级联动代码
2012/01/24 Javascript
Javascript 鼠标移动上去小三角形滑块缓慢跟随效果
2013/04/26 Javascript
jQuery验证元素是否为空的两种常用方法
2015/03/17 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
jquery滚动到顶部底部代码
2015/04/20 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
2016/03/05 Javascript
bootstrap table操作技巧分享
2017/02/15 Javascript
vue嵌套路由与404重定向实现方法分析
2018/05/04 Javascript
layui输入框只允许输入中文且判断长度的例子
2019/09/18 Javascript
javascript设计模式之装饰者模式
2020/01/30 Javascript
Python脚本实现集群检测和管理功能
2015/03/06 Python
Python生成随机密码
2015/03/10 Python
python判断字符串编码的简单实现方法(使用chardet)
2016/07/01 Python
Python爬虫实例_利用百度地图API批量获取城市所有的POI点
2018/01/10 Python
Tensorflow中使用tfrecord方式读取数据的方法
2018/06/19 Python
Python txt文件加入字典并查询的方法
2019/01/15 Python
python爬取微信公众号文章的方法
2019/02/26 Python
Python队列、进程间通信、线程案例
2019/10/25 Python
opencv3/python 鼠标响应操作详解
2019/12/11 Python
python读取csv文件指定行的2种方法详解
2020/02/13 Python
CSS3中引入多种自定义字体font-face
2020/06/12 HTML / CSS
AmazeUI 单选框和多选框的实现示例
2020/08/18 HTML / CSS
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
口头翻译求职人自荐信
2013/12/07 职场文书
司机工作自我鉴定
2014/09/19 职场文书
学习党的群众路线剖析材料
2014/10/09 职场文书
鉴史问廉观后感
2015/06/10 职场文书
文艺演出主持词
2015/07/01 职场文书
健康教育主题班会
2015/08/14 职场文书
Python实现拼音转换
2021/06/07 Python