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 threading多线程编程实例
Sep 18 Python
Python获取当前页面内所有链接的四种方法对比分析
Aug 19 Python
使用python存储网页上的图片实例
May 22 Python
10个Python小技巧你值得拥有
Sep 29 Python
python opencv读mp4视频的实例
Dec 07 Python
python实现一行输入多个值和一行输出多个值的例子
Jul 16 Python
python 进程的几种创建方式详解
Aug 29 Python
python 命令行传入参数实现解析
Aug 30 Python
python 生成任意形状的凸包图代码
Apr 16 Python
python 爬取天气网卫星图片
Jun 07 Python
关于Python OS模块常用文件/目录函数详解
Jul 01 Python
Python多线程实用方法以及共享变量资源竞争问题
Apr 12 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中文汉字验证码
2007/04/08 PHP
一个简洁的PHP可逆加密函数(分享)
2013/06/06 PHP
php简单实现屏蔽指定ip段用户的访问
2015/04/29 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
用js模拟JQuery的show与hide动画函数代码
2010/09/20 Javascript
js最简单的拖拽效果实现代码
2010/09/24 Javascript
纯js简单日历实现代码
2013/10/05 Javascript
js 用CreateElement动态创建标签示例
2013/11/20 Javascript
javascript自定义的addClass()方法
2014/05/28 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
深入理解JavaScript系列(43):设计模式之状态模式详解
2015/03/04 Javascript
js+css实现select的美化效果
2016/03/24 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
url传递的参数值中包含&amp;时,url自动截断问题的解决方法
2016/08/02 Javascript
bootstrap datetimepicker2.3.11时间插件使用
2016/11/19 Javascript
JS二叉树的简单实现方法示例
2017/04/05 Javascript
es6学习笔记之Async函数基本教程
2017/05/11 Javascript
基于Vue实例对象的数据选项
2017/08/09 Javascript
node express使用HTML模板的方法示例
2019/08/22 Javascript
JavaScript中变量提升机制示例详解
2019/12/27 Javascript
JS实现可控制的进度条
2020/03/25 Javascript
vue 使用微信jssdk,调用微信相册上传图片功能
2020/11/13 Javascript
微信小程序实现点赞业务
2021/02/10 Javascript
python有证书的加密解密实现方法
2014/11/19 Python
Python笔记之代理模式
2019/11/20 Python
利用PyQt中的QThread类实现多线程
2020/02/18 Python
通过实例简单了解python yield使用方法
2020/08/06 Python
python 实现音频叠加的示例
2020/10/29 Python
Python实现一个论文下载器的过程
2021/01/18 Python
前端canvas动画如何转成mp4视频的方法
2019/06/17 HTML / CSS
Abe’s of Maine:自1979以来销售相机和电子产品
2016/11/21 全球购物
伦敦一家西班牙童装精品店:La Coqueta
2018/02/02 全球购物
2014年妇幼保健工作总结
2014/12/08 职场文书
运动会闭幕词
2015/01/28 职场文书
写作技巧:优秀文案必备的3种结构
2019/08/19 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书