ホームページ  >  記事  >  バックエンド開発  >  例外が発生した場合のリトライの解決策

例外が発生した場合のリトライの解決策

Y2J
Y2Jオリジナル
2017-05-13 14:00:232426ブラウズ

この記事では、Python での異常な再試行の解決策を主に紹介します。この記事は、Python を学習したり使用したりする人にとって、一定の参考になると思います。見る。

はじめに

誰もがデータキャプチャを行うとき、ネットワークの問題によりプログラムの保存に遭遇することがよくありますが、以前はエラー内容を記録し、エラー内容を後処理するだけでした。

元のプロセス:


def crawl_page(url):
 pass
 
def log_error(url):
 pass
 
url = ""
try:
 crawl_page(url)
except:
 log_error(url)

改善されたプロセス:


attempts = 0
success = False
while attempts < 3 and not success:
 try:
  crawl_page(url)
  success = True
 except:
  attempts += 1
  if attempts == 3:
   break

最近発見された新しい解決策: 再試行

ing は Python が重いです。テスト パッケージは次の目的で使用できます。失敗する可能性のある一部のプログラムセグメントを自動的に再試行します。 retrying は、デコレータ 関数

retry を提供します。装飾された関数は、失敗した場合に再実行されます。デフォルトでは、エラーが報告されるまで再試行が続けられます。 retrying提供一个装饰器函数retry,被装饰的函数就会在运行失败的条件下重新执行,默认只要一直报错就会不断重试。


import random
from retrying import retry
 
@retry
def do_something_unreliable():
 if random.randint(0, 10) > 1:
  raise IOError("Broken sauce, everything is hosed!!!111one")
 else:
  return "Awesome sauce!"
 
print do_something_unreliable()

如果我们运行have_a_try函数,那么直到random.randint返回5,它才会执行结束,否则会一直重新执行。

retry还可以接受一些参数,这个从源码中Retrying类的初始化函数可以看到可选的参数:

  • s<a href="http://www.php.cn/wiki/904.html" target="_blank">top</a>_max_attempt_number:用来设定最大的尝试次数,超过该次数就停止重试

  •  stop_max_delay:比如设置成10000,那么从被装饰的函数开始执行的时间点开始,到函数成功运行结束或者失败报错中止的时间点,只要这段时间超过10秒,函数就不会再执行了

  • wait_fixed:设置在两次retrying之间的停留时间

  • wait_random_min和wait_random_max:用随机的方式产生两次retrying之间的停留时间

  • wait_exponential_multiplier和wait_exponential_max:以指数的形式产生两次retrying之间的停留时间,产生的值为2^previous_attempt_number * wait_exponential_multiplierprevious_attempt_number是前面已经retry的次数,如果产生的这个值超过了wait_exponential_max的大小,那么之后两个retrying之间的停留值都为wait_exponential_max。这个设计迎合了exponential backoff算法,可以减轻阻塞的情况。

  • 我们可以指定要在出现哪些异常的时候再去retry,这个要用retry_on_<a href="http://www.php.cn/wiki/265.html" target="_blank">exception</a>传入一个函数对象


def retry_if_io_error(exception):
 return isinstance(exception, IOError)
 
@retry(retry_on_exception=retry_if_io_error)
def read_a_file():
 with open("file", "r") as f:
  return f.read()

在执行read_a_file函数的过程中,如果报出异常,那么这个异常会以形参exception传入retry_if_io_error函数中,如果exceptionIOError那么就进行retry,如果不是就停止运行并抛出异常

我们还可以指定要在得到哪些结果的时候去retry,这个要用retry_on_result传入一个函数对象:


def retry_if_result_none(result):
 return result is None
 
@retry(retry_on_result=retry_if_result_none)
def get_result():
 return None

在执行get_result成功后,会将函数的返回值通过形参result的形式传入retry_if_result_none函数中,如果返回值是None那么就进行retry

rrreee have_a_try 関数を実行すると、random.randint が 5 を返すまで終了しません。それ以外の場合は再実行されます。

retry はいくつかのパラメーターを受け入れることもできます。オプションのパラメーターは、ソース コードの Retrying クラスの初期化関数で確認できます。

  • stop_max_attempt_number: 最大試行回数を設定するために使用されます。を超えると停止します。 Retry

  • stop_max_delivery: たとえば、10000 に設定すると、装飾された関数の実行が開始される時刻から開始されます。関数は正常に終了するか、エラーで失敗します。この期間が 10 秒を超えると、関数は実行されなくなります
  • wait_fixed: 2 つの間の滞留時間を設定します。 再試行時間
  • wait_random_minとwait_random_max: 2つの再試行間の滞留時間をランダムに生成します
  • wait_exponential_multiplier および wait_exponential_max: 2 つの retrying 間の滞留時間を指数形式で生成します。生成される値は 2^previous_attempt_number * wait_exponential_multiplierです。 >、previous_attempt_number は、以前に retry が行われた回数です。生成された値が wait_exponential_max のサイズを超える場合、その間の滞在値です。 2 回の再試行は wait_exponential_max です。この設計は、ブロック状況を軽減できる 指数バックオフ アルゴリズムに対応しています。
  • 例外が発生したときに再試行する例外を指定するには、retry_on_<a href="http://www.php.cn/wiki/265" .html target="_blank">例外<p></p></a>関数オブジェクト を渡します: li>
rrreee read_a_file 関数の実行中に例外が報告された場合、その例外は仮パラメータ Exception として <code> >retry_if_io_error 関数では、例外IOError の場合は retry を実行し、そうでない場合は実行を停止し、 例外 をスローします。

どの結果を retry に送信するかを指定することもできます。これには、retry_on_result を使用して関数オブジェクトを渡す必要があります: rrreee

実行中get_result が成功すると、関数の戻り値が正式な関数に渡されます。パラメータ result の形式は retry_if_result_none 関数に渡されます。戻り値が None の場合、retry は次のようになります。それ以外の場合は関数が終了し、値が返されます。 🎜🎜🎜🎜概要🎜🎜🎜🎜🎜[関連推奨事項]🎜🎜🎜🎜1. 🎜🎜特別な推奨事項🎜🎜: 🎜🎜「phpプログラマツールボックス」V0.1バージョンのダウンロード🎜🎜🎜🎜🎜 🎜2. 🎜 🎜パイソン無料のビデオチュートリアル🎜🎜🎜🎜🎜🎜3. 🎜🎜Pythonの基本入門チュートリアル🎜🎜🎜🎜

以上が例外が発生した場合のリトライの解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。