11

フラスコアプリケーションを書きました。リモートサーバーにデプロイしたとき、非常に遅いことがわかりました。それで、私はそれを使っていくつかのプロファイリングの練習をしました。以下の写真をご覧ください。

プロファイリングに使用するコードは次のとおりです。

#coding: utf-8
from werkzeug.contrib.profiler import ProfilerMiddleware
from app import app

app.config['PROFILE'] = True
app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions = [30])
app.run(debug = True)

写真1

リモート サーバーでのプロファイリング。多分ボトルネックは_socket.getaddrinfo

ここに画像の説明を入力

写真2

ローカル マシンでのプロファイリング。ボトルネックは見つかりませんでした。

ここに画像の説明を入力

写真3

場合によっては、リモートサーバーでもボトルネックが見つからないことがあります。見つかりません_socket.getaddrinfo。変! ここに画像の説明を入力

リモートサーバーのpythonシェルでもプロファイリングを行いましたcProfile. これを見てください:


In [10]: cProfile.run("socket.getaddrinfo('easylib.gdufslib.org', 80, 0, 0, socket.SOL_TCP)")
         3 function calls in 8.014 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    8.014    8.014 :1()
        1    8.014    8.014    8.014    8.014 {_socket.getaddrinfo}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}



In [11]: cProfile.run("socket.getaddrinfo('easylib.gdufslib.org', 80, 0, 0, socket.SOL_TCP)")
         3 function calls in 8.009 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    8.009    8.009 :1()
        1    8.009    8.009    8.009    8.009 {_socket.getaddrinfo}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


たぶん、仕事をするのに時間がかかるという事実があり、それをdns resolve自分で変えることはできません。

誰でも教えてもらえますか: なぜ_socket.getaddrinfo呼び出され、なぜ呼び出されないことがありますか? 呼ばれないようにする方法_socket.getaddrinfoは?それは悲しいことに私を失望させた私のウェブサイトを遅くするからです.

4

3 に答える 3

7

Digital Oceanの専用ボックスで実行されているFlaskアプリで自分自身でこれに遭遇したので、将来誰かがこれに遭遇した場合に備えて解決策を投稿します.

数日前、GitHub への API リクエストが非常に遅く、10 秒から 20 秒かかることもあることに気付きまし。しかし、アプリをローカルで実行しても問題はありませんでした。私は自分のアプリをプロファイリングしましたsocket.getaddrinfoが、実際に犯人でした:

1 15058.431 15058.4310 15058.431 15058.4310 {_socket.getaddrinfo}
1 26.545 26.5450 26.545 26.5450 {_ssl.sslwrap}
1 23.246 23.2460 23.246 23.2460 {built-in method do_handshake}
4 22.387 5.5968 22.387 5.5968 {built-in method read}
1 7.632 7.6320 7.632 7.6320 {method 'connect' of '_socket.socket' objects}
103 4.995 0.0485 7.131 0.0692 <s/werkzeug/urls.py:374(url_quote)>
2 2.459 1.2295 2.578 1.2890 <ssl.py:294(close)>
36 1.495 0.0415 10.548 0.2930 <s/werkzeug/routing.py:707(build)>
859 1.442 0.0017 1.693 0.0020 {isinstance}
.... etc.

Digital Ocean のサポートと協力し、何らかの形で DNS の問題であると疑ったため、有効な解決策は変更することでした (in /etc/resolv.conf)

nameserver 4.2.2.2
nameserver 8.8.8.8

nameserver 8.8.4.4
nameserver 8.8.8.8

何らかの理由で4.2.2.2(Level3 が運営) は私を嫌っていると判断しましたが、当分の間、私と Google の DNS はクールです。

更新: 同僚の Karl は、ローカルの DNS キャッシング サーバーをバインドしてセットアップし、Google の DNS が私を嫌うのを防ぐよう提案してくれました。このリンクは非常に役に立ちました。

于 2014-08-25T19:33:12.720 に答える
1

私は近い過去に同じ問題を抱えていました。遅さの原因を確認するために、どのエンドポイントがより多く要求され、どのエンドポイントがボトルネックであるかを確認することにしました。この目的のために、リクエストを分析するツールを作成しました。それもあなたを助けるかもしれません、それを見てください https://github.com/muatik/flask-profiler

于 2015-10-26T13:41:24.380 に答える
1

これは、リモート ホストが DNS ルックアップをキャッシュしていないか、IPv6 の問題により getaddrinfo が遅いことが原因であると考えられます。

これを (数回) 試して、ネームサーバーがキャッシュしているように見えるかどうかをテストします。

$ time host easylib.gdufslib.org

また、IPv4 のみを強制した場合にルックアップが高速かどうかをテストするには、次のようにします。

import socket
socket.getaddrinfo("easylib.gdufslib.org", 80, socket.AF_INET, 0, socket.SOL_TCP)

最初のネームサーバーが原因である場合は、ローカル キャッシュ ネームサーバーをインストールするか、既存のネームサーバーがキャッシュされるように修正することができます。後者が原因である場合は、コードとライブラリで修正するか、使用しない場合はホストで IPv6 を無効にすることができます。

于 2013-08-01T08:26:41.567 に答える