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爬虫技巧汇总
Sep 28 Python
python3中set(集合)的语法总结分享
Mar 24 Python
Python 文件处理注意事项总结
Apr 10 Python
python+pyqt实现12306图片验证效果
Oct 25 Python
Python内置函数—vars的具体使用方法
Dec 04 Python
flask入门之文件上传与邮件发送示例
Jul 18 Python
win10下tensorflow和matplotlib安装教程
Sep 19 Python
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
Apr 12 Python
Tensorflow实现神经网络拟合线性回归
Jul 19 Python
python爬虫开发之使用Python爬虫库requests多线程抓取猫眼电影TOP100实例
Mar 10 Python
Python pymysql模块安装并操作过程解析
Oct 13 Python
基于OpenCV的网络实时视频流传输的实现
Nov 15 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无限分类代码,支持数组格式化、直接输出菜单两种方式
2011/05/18 PHP
php缩放图片(根据宽高的等比例缩放)实例介绍
2013/06/09 PHP
php中的filesystem文件系统函数介绍及使用示例
2014/02/13 PHP
PHP CURL采集百度搜寻结果图片不显示问题的解决方法
2017/02/03 PHP
javascript之卸载鼠标事件的代码
2007/05/14 Javascript
fckeditor 获取文本框值的实现代码
2009/02/09 Javascript
再论Javascript下字符串连接的性能
2011/03/05 Javascript
js如何判断不同系统的浏览器类型
2013/10/28 Javascript
JavaScript保存并运算页面中数字类型变量的写法
2015/07/06 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
javascript显示倒计时控制按钮的简单实现
2016/06/07 Javascript
vue2.0 keep-alive最佳实践
2017/07/06 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
JS兼容所有浏览器的DOMContentLoaded事件
2018/01/12 Javascript
快速了解vue-cli 3.0 新特性
2018/02/28 Javascript
JQuery 实现文件下载的常用方法分析
2019/10/29 jQuery
Vue项目打包压缩的实现(让页面更快响应)
2020/03/10 Javascript
详解微信小程序入门从这里出发(登录注册、开发工具、文件及结构介绍)
2020/07/21 Javascript
python实现搜索指定目录下文件及文件内搜索指定关键词的方法
2015/06/28 Python
详解python 注释、变量、类型
2018/08/10 Python
Python利用requests模块下载图片实例代码
2019/08/12 Python
python实现凯撒密码、凯撒加解密算法
2020/06/11 Python
python 基于opencv 绘制图像轮廓
2020/12/11 Python
TripAdvisor瑞典:全球领先的旅游网站
2017/12/11 全球购物
End Clothing美国站:英国男士潮牌商城
2018/04/20 全球购物
String和StringBuffer的区别
2015/08/13 面试题
物流仓储实习自我鉴定
2013/09/25 职场文书
平面设计岗位职责
2013/12/14 职场文书
8和9的加减法教学反思
2014/05/01 职场文书
教师学期个人总结
2015/02/11 职场文书
硕士论文致谢范文
2015/05/14 职场文书
大学生受助感言
2015/08/01 职场文书
创业计划书之酒吧
2019/12/02 职场文书
一文搞懂redux在react中的初步用法
2021/06/09 Javascript
关于python pygame游戏进行声音添加的技巧
2021/10/24 Python
十大最强岩石系宝可梦,怪颚龙实力最强,第七破坏力很强
2022/03/18 日漫