需求背景:在执行一个函数时可能该函数会卡住导致整个程序无法执行,这时候就需要函数超时处理了;举一个具体的例子:python在进行kafka消费数据是通常会取一批数据(例如100个)进行多线程或者多进程处理,但是kafka可能会只剩余20个数据了,这时候就会一直在等待kafka的新数据,而这20条数不会被消费,就会造成延时处理的问题。
处理思路:在kafka那里加一个超时处理机制,如果一定时间内返回不了数据,就退出该函数并把获取到的数据返回给调用方。
一、timeout_decorator (pip3 installtimeout_decorator)
import time import timeout_decorator @timeout_decorator.timeout(8) # 这里写限制的时间 def mytest(): print("Start") list_data = [] try: for i in range(10): list_data.append(i) time.sleep(1) return list_data except Exception as e: print(e) return list_data def main(): result = mytest() print(result) if __name__ == '__main__': main()
二、stopit (pip3 install stopit)
import stopit import time @stopit.threading_timeoutable() # 该库没有报错信息 def mytest(): list_data = [] try: for i in range(10): print(i) list_data.append(i) time.sleep(1) return list_data except Exception as e: print(e) # 该方法不会出现报错信息 return list_data def main(): result = mytest(timeout=4) # 这里写限制的时间 print(result) if __name__ == '__main__': main()
结论:第一种会把"Timed Out"这个错误报出来,第二种不会报这个错误;如果函数有错误会报出来的。
参考:https://www.houyunbo.com/python%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0%E8%B6%85%E6%97%B6%E8%AE%BE%E7%BD%AE.html,https://blog.csdn.net/weixin_32673065/article/details/112083276
from kafka import KafkaConsumer, KafkaProducer import json, time import timeout_decorator @timeout_decorator.timeout(500) def demo(consumer): list_data = [] try: for i in consumer: list_data.append(i) data = i.value.decode("utf-8") print(data, type(json.loads(data))) if len(list_data) > 20: break return list_data except Exception as e: print(e) return list_data def main(): hosts = ['127.0.0.1:9092', '0.0.0.0:9092'] topic = "Coupon_Update_Access_V1" group_id = "qly_test0001" consumer = KafkaConsumer(topic, bootstrap_servers=hosts, group_id=group_id, auto_offset_reset="earliest") while True: result = demo(consumer) print(len(result)) time.sleep(5) if __name__ == '__main__': main()