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 基础学习教程
Feb 08 Python
Python 文件和输入输出小结
Oct 09 Python
python清除字符串里非字母字符的方法
Jul 02 Python
用python写个自动SSH登录远程服务器的小工具(实例)
Jun 17 Python
基于Python和Scikit-Learn的机器学习探索
Oct 16 Python
Python设计模式之门面模式简单示例
Jan 09 Python
Centos 升级到python3后pip 无法使用的解决方法
Jun 12 Python
PyQT实现菜单中的复制,全选和清空的功能的方法
Jun 17 Python
Python3 操作 MySQL 插入一条数据并返回主键 id的实例
Mar 02 Python
深入浅析python 中的self和cls的区别
Jun 20 Python
python计算auc的方法
Sep 09 Python
如何Python使用re模块实现okenizer
Apr 30 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
phpize的深入理解
2013/06/03 PHP
PHP编程中尝试程序并发的几种方式总结
2016/03/21 PHP
jQuery实现带动画效果的二级下拉导航方法
2015/03/11 Javascript
JS模拟Dialog弹出浮动框效果代码
2015/10/16 Javascript
JS运动相关知识点小结(附弹性运动示例)
2016/01/08 Javascript
30分钟快速掌握Bootstrap框架
2016/05/24 Javascript
Wireshark基本介绍和学习TCP三次握手
2016/08/15 Javascript
js基础之DOM中document对象的常用属性方法详解
2016/10/28 Javascript
JS常用倒计时代码实例总结
2017/02/07 Javascript
Angular2自定义分页组件
2017/04/19 Javascript
xmlplus组件设计系列之树(Tree)(9)
2017/05/02 Javascript
jQuery Position方法使用和兼容性
2017/08/23 jQuery
JS随机数产生代码分享
2018/02/24 Javascript
详解小程序循环require之坑
2019/03/08 Javascript
解决vue 单文件组件中样式加载问题
2019/04/24 Javascript
JS实现拼图游戏
2021/01/29 Javascript
vue图片上传组件使用详解
2019/12/23 Javascript
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
Django框架下在URLconf中指定视图缓存的方法
2015/07/23 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
Django实现celery定时任务过程解析
2020/04/21 Python
django model 条件过滤 queryset.filter(**condtions)用法详解
2020/05/20 Python
css3圆角边框和边框阴影示例
2014/05/05 HTML / CSS
HTML5 Canvas——用路径描画线条实例介绍
2013/06/09 HTML / CSS
原装进口全世界:天猫国际
2016/08/03 全球购物
如何删除一个表里面的重复行
2013/07/13 面试题
Internal修饰符有什么含义
2013/07/10 面试题
报关简历自我评价怎么写
2013/09/19 职场文书
学生打架检讨书大全
2014/01/23 职场文书
员工考核评语大全
2014/04/26 职场文书
高考励志标语
2014/06/05 职场文书
客户答谢会活动方案
2014/08/31 职场文书
个人违纪检讨书
2014/09/15 职场文书
常务副县长“四风”个人对照检查材料思想汇报
2014/10/02 职场文书
2015年宣传思想工作总结
2015/05/22 职场文书
深入理解MySQL中MVCC与BufferPool缓存机制
2022/05/25 MySQL