Python 协程检测Kubernetes服务端口
一、需求分析
在上一篇文章,链接如下:
https://www.cnblogs.com/xiao987334176/p/10237551.html
已经得到了需要的数据,现在需要对这些端口做检测,判断端口是否正常!
实际情况是,有上百个端口需要检测。如果一个个检测,可能需要花费几分钟的时间,效率不够快!
那么首先想到的就是多进程,但是一个进程会消耗一个CPU。
在不影响性能的情况下,最快的办法,就是使用协程。它是异步的,遇到io会自动切换!
二、协程
介绍
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
关于 进程、线程和协程的理解,请参考链接:
https://www.cnblogs.com/guolei2570/p/8810536.html
这篇文章,有大量的图片解释,通俗易懂!
安装
使用协程,需要安装模块
pip3 install gevent
什么是猴子补丁(monkey patch)
monkey patch指的是在执行时动态替换,通常是在startup的时候.
用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all();把标准库中的thread/socket等给替换掉.这样我们在后面使用socket的时候能够跟寻常一样使用,无需改动不论什么代码,可是它变成非堵塞的了.
使用
导入模块时,必须要导入猴子补丁
from gevent import monkey; monkey.patch_all()
import gevent
示例
from gevent import monkey;monkey.patch_all()
# 它会把下面导入的所有的模块中的IO操作都打成一个包,gevent就能够认识这些IO了
import time
import gevent def eat():
print('eating1')
time.sleep(1) # 延时调用
print(time.time(),'eating2') def play():
print('playing1')
time.sleep(1) # 延时调用
print(time.time(),'playing2') g1 = gevent.spawn(eat) # 创建一个协程对象g1
g2 = gevent.spawn(play)
g1.join() # 等待g1结束
g2.join()
执行输出:
eating1
playing1
1546917759.6040378 eating2
1546917759.6040378 playing2
看时间戳,可以发现,即使睡眠了1秒,2个函数几乎是同时运行的
三、正式代码
#!/usr/bin/env python
# coding: utf-8
import os
import json
import time
import socket
from gevent import monkey;monkey.patch_all()
import gevent # data = ""
# with open('test.json') as f:
# data = json.loads(f.read()) # api整理好的json数据
data = {"voucher-center-master": [
{"server_port": 8012, "ip": "192.169.167.105", "pod_name": "voucher-center-rc-p20kk", "nodeName": "job-node149",
"beejob_port": 3011},
{"server_port": 8012, "ip": "192.169.183.26", "pod_name": "voucher-center-rc-vknkt", "nodeName": "job-node137",
"beejob_port": 3011},
{"server_port": 8012, "ip": "192.169.242.29", "pod_name": "voucher-center-rc-0x482", "nodeName": "job-node145",
"beejob_port": 3011},
{"server_port": 8012, "ip": "192.169.76.159", "pod_name": "voucher-center-rc-xtxfb", "nodeName": "job-node151",
"beejob_port": 3011},
{"server_port": 8012, "ip": "192.169.98.159", "pod_name": "voucher-center-rc-n9wkl", "nodeName": "job-node147",
"beejob_port": 3011}]} class CheckServer(object): # 检查服务端口
def __init__(self):
self.process_list = [] # 进程列表 def check_tcp(self, ip, port, timeout=1):
"""
检测tcp端口
:param ip: ip地址
:param port: 端口号
:param timeout: 超时时间
:return: bool
"""
flag = False
try:
socket.setdefaulttimeout(timeout) # 整个socket层设置超时时间
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = (str(ip), int(port))
status = cs.connect_ex((address)) # 开始连接
cs.settimeout(timeout) if not status:
flag = True return flag
except Exception as e:
print("error:%s" % e)
return flag def write_log(self, content):
"""
写入日志文件
:param content: 写入内容
:return:
"""
path = "output.log" # 日志文件
with open(path, mode='a+', encoding='utf-8') as f:
content = time.strftime('%Y-%m-%d %H:%M:%S') + ' ' + content + "\n"
print(content)
f.write(content) def run(self, name, ip, port, category):
"""
运行程序
:param name: 名称
:param ip: ip
:param port: 端口
:param category: 类别
:return:
"""
self.write_log("name:{} {}_ip:{} 检查端口: {} 状态:{}".format(name, category, ip, port, self.check_tcp(ip, port))) def main(self):
for i in data: # 遍历字典
# print("name",i)
for j in data[i]: # 遍历节点数据
if j.get('server_port'): # 获取server_port
if j.get('ip'):
ip = j['ip']
port = j['server_port']
# 添加到进程列表中
self.process_list.append(gevent.spawn(self.run, i, ip, port, 'server')) if j.get('beejob_port'): # 获取beejob_port
if j.get('ip'):
ip = j['ip']
port = j['beejob_port']
# 添加到进程列表中
self.process_list.append(gevent.spawn(self.run, i, ip, port, 'beejob')) return self.process_list if __name__ == '__main__':
startime = time.time() # 开始时间
process_list = CheckServer().main()
gevent.joinall(process_list) # 使用协程执行所有协程 endtime = time.time()
take_time = endtime - startime if take_time < 1: # 判断不足1秒时
take_time = 1 # 设置为1秒
# 计算花费时间
m, s = divmod(take_time, 60)
h, m = divmod(m, 60) print("本次花费时间 %02d:%02d:%02d" % (h, m, s))
执行输出:
2019-01-08 11:27:54 name:voucher-center-master server_ip:192.169.167.105 检查端口: 8012 状态:False 2019-01-08 11:27:54 name:voucher-center-master beejob_ip:192.169.167.105 检查端口: 3011 状态:False 2019-01-08 11:27:54 name:voucher-center-master server_ip:192.169.183.26 检查端口: 8012 状态:False 2019-01-08 11:27:54 name:voucher-center-master beejob_ip:192.169.183.26 检查端口: 3011 状态:False 2019-01-08 11:27:54 name:voucher-center-master server_ip:192.169.242.29 检查端口: 8012 状态:False 2019-01-08 11:27:54 name:voucher-center-master beejob_ip:192.169.242.29 检查端口: 3011 状态:False 2019-01-08 11:27:54 name:voucher-center-master server_ip:192.169.76.159 检查端口: 8012 状态:False 2019-01-08 11:27:54 name:voucher-center-master beejob_ip:192.169.76.159 检查端口: 3011 状态:False 2019-01-08 11:27:54 name:voucher-center-master server_ip:192.169.98.159 检查端口: 8012 状态:False 2019-01-08 11:27:54 name:voucher-center-master beejob_ip:192.169.98.159 检查端口: 3011 状态:False 本次花费时间 00:00:01
可以发现,即使有那么多端口,1秒钟就完成了,使用协程非常的高效!
Python 协程检测Kubernetes服务端口的更多相关文章
- Python协程与Go协程的区别二
写在前面 世界是复杂的,每一种思想都是为了解决某些现实问题而简化成的模型,想解决就得先面对,面对就需要选择角度,角度决定了模型的质量, 喜欢此UP主汤质看本质的哲学科普,其中简洁又不失细节的介绍了人类 ...
- day-5 python协程与I/O编程深入浅出
基于python编程语言环境,重新学习了一遍操作系统IO编程基本知识,同时也学习了什么是协程,通过实际编程,了解进程+协程的优势. 一.python协程编程实现 1. 什么是协程(以下内容来自维基百 ...
- python 协程与go协程的区别
进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...
- 进程池与线程池、协程、协程实现TCP服务端并发、IO模型
进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...
- 5分钟完全掌握Python协程
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 1. 协程相关的概念 1.1 进程和线程 进程(Process)是应用程序启动的实例,拥有代码.数据 ...
- Python协程与JavaScript协程的对比
前言 以前没怎么接触前端对JavaScript 的异步操作不了解,现在有了点了解一查,发现 python 和 JavaScript 的协程发展史简直就是一毛一样! 这里大致做下横向对比和总结,便于对这 ...
- Python 协程总结
Python 协程总结 理解 协程,又称为微线程,看上去像是子程序,但是它和子程序又不太一样,它在执行的过程中,可以在中断当前的子程序后去执行别的子程序,再返回来执行之前的子程序,但是它的相关信息还是 ...
- 终结python协程----从yield到actor模型的实现
把应用程序的代码分为多个代码块,正常情况代码自上而下顺序执行.如果代码块A运行过程中,能够切换执行代码块B,又能够从代码块B再切换回去继续执行代码块A,这就实现了协程 我们知道线程的调度(线程上下文切 ...
- 从yield 到yield from再到python协程
yield 关键字 def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b yield 是在:PEP 255 -- Simple Generator ...
随机推荐
- 【设计模式】——工厂方法FactoryMethod
前言:[模式总览]——————————by xingoo 模式意图 工厂方法在MVC中应用的很广泛. 工厂方法意在分离产品与创建的两个层次,使用户在一个工厂池中可以选择自己想要使用的产品,而忽略其创建 ...
- Again Prime? No Time. UVA - 10780(质因子分解)
m^k就是让m的每个质因子个数都增加了k倍 求m的质因子 在n!中增加了多少倍就好了,因为m^k 表示每一个质因子增加相同的倍数k 所以我们需要找到增加倍数最小的那个..短板效应 其它质因子多增加 ...
- 【BZOJ4500】矩阵(差分约束)
[BZOJ4500]矩阵(差分约束) 题面 BZOJ 然而权限题 题解 显然拆分行和列.不妨设这一行/列总共加减的值是\(p\),那么每一个限制就是两个数的和为一个特定的数.这样子不好做,反正是一个二 ...
- COCI 2018/2019 CONTEST #2 Solution
Problem1 Preokret 第一题一定不是什么难题. 第一个问题在读入的时候判断当前时间是不是在1440及以前就行 第二个问题考虑离线处理,由于每个时刻只能最多发生1个事件那么就弄个桶记录每一 ...
- Problem C: 多线程 解题报告
Problem C: 多线程 Description 多线程是一种常见的加速手段,利用多个线程同时处理不同的任务可以一定程度上减少总耗时,达到提高效率的目的.然而,多个线程间的执行顺序是完全不可控的, ...
- MyEclipse创建WebService服务端和客户端
1.新建立一个javaWeb项目,一个java类,如图: 2.接下来我们就要将项目中的TestService的这个类生成WebService服务端,选择new Web Service,如图: Next ...
- ubuntu,centor 安装apache bench
ab全称为:apache bench. 是apache自带的压力测试工具.ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试.比如nginx.to ...
- C语言复习---选择法排序
选择排序也是一种简单直观的排序算法 它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列:然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾. ...
- jquery的json对象与字符串之间转换
json对象----- >>字符串 JSON.stringify(obj) json字符串------>>json对象 JSON.parse(string) 公众号 欢迎关注我 ...
- 基于JWT(Json Web Token)的ASP.NET Web API授权方式
token应用流程 初次登录:用户初次登录,输入用户名密码 密码验证:服务器从数据库取出用户名和密码进行验证 生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT 返还JWT ...