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中的Numeric包和Numarray包使用教程
Apr 13 Python
PyMongo安装使用笔记
Apr 27 Python
Python抽象类的新写法
Jun 18 Python
Python类的动态修改的实例方法
Mar 24 Python
Python IDLE入门简介
Dec 08 Python
Python 实现异步调用函数的示例讲解
Oct 14 Python
Django 路由控制的实现代码
Nov 08 Python
Flask框架踩坑之ajax跨域请求实现
Feb 22 Python
python生成随机红包的实例写法
Sep 02 Python
利用PyQt中的QThread类实现多线程
Feb 18 Python
Python脚本如何在bilibili中查找弹幕发送者
Jun 04 Python
面向新手解析python Beautiful Soup基本用法
Jul 11 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
肝肠寸断了解下!盘点史上最伤心的十大动漫
2020/03/04 日漫
PHP file_exists问题杂谈
2012/05/07 PHP
通过table标签,PHP输出EXCEL的实现方法
2013/07/24 PHP
php获取淘宝分类id示例
2014/01/16 PHP
PHP编写daemon process详解及实例代码
2016/09/30 PHP
php curl优化下载微信头像的方法总结
2018/09/07 PHP
WordPress 插件——CoolCode使用方法与下载
2007/07/02 Javascript
jQuery中delegate与on的用法与区别示例介绍
2013/12/20 Javascript
更快的异步执行(setTimeout多浏览器)
2014/08/12 Javascript
使用javascript实现监控视频播放并打印日志
2015/01/05 Javascript
Javascript实现图片轮播效果(一)让图片跳动起来
2016/02/17 Javascript
利用jQuery.Validate异步验证用户名是否存在(推荐)
2016/12/09 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
利用node.js搭建简单web服务器的方法教程
2017/02/20 Javascript
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
vue.js 获取select中的value实例
2018/03/01 Javascript
vue中Element-ui 输入银行账号每四位加一个空格的实现代码
2018/09/14 Javascript
前端Vue项目详解--初始化及导航栏
2019/06/24 Javascript
使用vue实现各类弹出框组件
2019/07/03 Javascript
基于layPage插件实现两种分页方式浅析
2019/07/27 Javascript
JS面向对象之多选框实现
2020/01/17 Javascript
[50:11]2018DOTA2亚洲邀请赛 4.7总决赛 LGD vs Mineski 第三场
2018/04/09 DOTA
Django项目中用JS实现加载子页面并传值的方法
2018/05/28 Python
python通过tcp发送xml报文的方法
2018/12/28 Python
详解Python self 参数
2019/08/30 Python
python实现xlwt xlrd 指定条件给excel行添加颜色
2020/07/14 Python
Docker如何部署Python项目的实现详解
2020/10/26 Python
Myprotein亚太地区:欧洲第一在线运动营养品牌
2020/12/20 全球购物
什么是"引用"?申明和使用"引用"要注意哪些问题?
2016/03/03 面试题
考试作弊检讨书大全
2014/02/18 职场文书
公司年会搞笑主持词
2014/03/24 职场文书
乡镇消防工作实施方案
2014/03/27 职场文书
党校个人自我鉴定范文
2014/03/28 职场文书
社区文化建设方案
2014/05/02 职场文书
python 通过使用Yolact训练数据集
2021/04/06 Python
zabbix自定义监控nginx状态实现过程
2021/11/01 Servers