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实现Windows下的鼠标键盘模拟的实例代码
Jul 13 Python
Python基于递归算法实现的走迷宫问题
Aug 04 Python
Python SqlAlchemy动态添加数据表字段实例解析
Feb 07 Python
Python列表推导式与生成器表达式用法示例
Feb 08 Python
TensorFlow实现RNN循环神经网络
Feb 28 Python
python3中os.path模块下常用的用法总结【推荐】
Sep 16 Python
详解Python基础random模块随机数的生成
Mar 23 Python
75条笑死人的知乎神回复,用60行代码就爬完了
May 06 Python
postman传递当前时间戳实例详解
Sep 14 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
Oct 24 Python
Python OrderedDict的使用案例解析
Oct 25 Python
python开发入门——列表生成式
Sep 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
全国FM电台频率大全 - 28 甘肃省
2020/03/11 无线电
php垃圾代码优化操作代码
2010/08/05 PHP
PHP遍历数组的几种方法
2012/03/22 PHP
Laravel 4 初级教程之安装及入门
2014/10/30 PHP
页面调用单个swf文件,嵌套出多个方法。
2011/11/21 Javascript
javascript动态加载三
2012/08/22 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
jquery的幻灯片图片切换效果代码分享
2015/09/07 Javascript
纯js实现瀑布流布局及ajax动态新增数据
2016/04/07 Javascript
javascript实现的猜数小游戏完整实例代码
2016/05/10 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
搭建Bootstrap离线文档的方法
2016/12/02 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
2017/01/12 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
jQuery代码优化方法总结
2018/01/29 jQuery
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
vue 解决addRoutes多次添加路由重复的操作
2020/08/04 Javascript
使用vue编写h5公众号跳转小程序的实现代码
2020/11/27 Vue.js
python根据文件大小打log日志
2014/10/09 Python
使用Python编写一个最基础的代码解释器的要点解析
2016/07/12 Python
python中pip的使用和修改下载源的方法
2019/07/08 Python
6行Python代码实现进度条效果(Progress、tqdm、alive-progress​​​​​​​和PySimpleGUI库)
2020/01/06 Python
python requests包的request()函数中的参数-params和data的区别介绍
2020/05/05 Python
Python 爬虫的原理
2020/07/30 Python
美国最大婚纱连锁店运营商:David’s Bridal
2019/03/12 全球购物
英国泽西岛植物:Jersey Plants Direct
2019/08/07 全球购物
Luxplus荷兰:以会员价购买美容产品等,独家优惠
2019/08/30 全球购物
领导接待方案
2014/03/13 职场文书
保险公司早会主持词
2014/03/22 职场文书
党员学习群众路线教育实践活动对照检查材料
2014/09/23 职场文书
班级光棍节联谊会策划书
2014/10/10 职场文书
部队2014年终工作总结
2014/11/27 职场文书
机械原理课程设计心得体会
2016/01/15 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
python for循环赋值问题
2021/06/03 Python
蓝牙耳机怎么连接电脑win11? Win11蓝牙耳机连接电脑的技巧
2023/01/09 数码科技