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 相关文章推荐
pygame学习笔记(1):矩形、圆型画图实例
Apr 15 Python
Python安装使用命令行交互模块pexpect的基础教程
May 12 Python
Python Django使用forms来实现评论功能
Aug 17 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
Python使用selenium + headless chrome获取网页内容的方法示例
Oct 16 Python
python3.8 微信发送服务器监控报警消息代码实现
Nov 05 Python
利用Python的sympy包求解一元三次方程示例
Nov 22 Python
python实现回旋矩阵方式(旋转矩阵)
Dec 04 Python
python能在浏览器能运行吗
Jun 17 Python
Python collections.deque双边队列原理详解
Oct 05 Python
python中24小时制转换为12小时制的方法
Jun 18 Python
Python NumPy灰度图像的压缩原理讲解
Aug 04 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
建立动态的WML站点(二)
2006/10/09 PHP
PHP获取网卡地址的代码
2008/04/09 PHP
php下通过伪造http头破解防盗链的代码
2010/07/03 PHP
关于Aptana Studio生成自动备份文件的解决办法
2009/12/23 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
JavaScript的strict模式与with关键字介绍
2014/02/08 Javascript
jquery的live使用注意事项
2014/02/18 Javascript
运用JQuery的toggle实现网页加载完成自动弹窗
2014/03/18 Javascript
基于JavaScript怎么实现让歌词滚动播放
2015/11/03 Javascript
js去字符串前后空格的实现方法
2016/02/26 Javascript
BootStrap智能表单demo示例详解
2016/06/13 Javascript
Bootstrap table的使用方法
2016/11/02 Javascript
jquery实现提示语淡入效果
2017/05/05 jQuery
js轮播图的插件化封装详解
2017/07/17 Javascript
最全vue的vue-amap使用高德地图插件画多边形范围的示例代码
2020/07/17 Javascript
在Vuex中Mutations修改状态操作
2020/07/24 Javascript
在vue中实现给每个页面顶部设置title
2020/07/29 Javascript
在Django的视图中使用数据库查询的方法
2015/07/16 Python
解决python xx.py文件点击完之后一闪而过的问题
2019/06/24 Python
浅谈matplotlib中FigureCanvasXAgg的用法
2020/06/16 Python
python sleep和wait对比总结
2021/02/03 Python
大学生四个方面的自我评价
2013/09/19 职场文书
《永远的白衣战士》教学反思
2014/04/25 职场文书
应届毕业生自荐书
2014/06/18 职场文书
党员“四风”方面存在问题及整改措施
2014/09/24 职场文书
小学向国旗敬礼活动方案
2014/09/27 职场文书
2015年幼儿园元旦游艺活动策划书
2014/12/09 职场文书
初中成绩单评语
2014/12/29 职场文书
辞职信范文大全
2015/03/02 职场文书
大学生求职信怎么写
2015/03/19 职场文书
大学生军训心得体会5篇
2019/08/15 职场文书
导游词之峨眉山
2019/12/16 职场文书
Pytest中conftest.py的用法
2021/06/27 Python
SpringBoot实现异步事件驱动的方法
2021/06/28 Java/Android
MySQL数据库表约束讲解
2022/06/21 MySQL
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS