2023年9月15日金曜日

質問と回答案02

質問 

【具体的な相談内容】

Python+FastAPI+UvicornでのAPIサーバーのレスポンスが良くなく、Uvicornやその他サーバー設定の変更により改善できないかサポートいただきたいです。

Python+FastAPI+Uvicornの経験のある方にお願いできますと幸いです。

【現在の設定やアクセス状況など】

下記のコマンドでuvicornを立ち上げています。

nohup uvicorn main:app --port=80 --host=0.0.0.0 --workers=9

(ネットでworkersの数値はコア数×2+1が適正という情報を見かけたのでそのようにしています)

APIリクエストは別サーバーのバッチ処理からのみなので、同時リクエストは常時8以下程度になるようコントロールしているのですが、遅い時にはAPIレスポンスに30秒ほどがかかっています。

同じ処理内容のpyファイルを実行すると毎回1秒前後でレスポンスが返ってくるので、uvicornもしくはサーバー側の設定に問題があるものと考えています。

【サーバー環境】

エックスサーバーVPS(vCPU4コア・メモリ4GB)

OS:Ubuntu 20.04

Python 3.8.10

回答

FastAPIとUvicornを使用したAPIサーバーのレスポンスが遅い問題を解決するためのアドバイスを提供します。以下のステップを試してみてください。

1.Uvicorn Workersの調整:

--workersフラグを調整することは、サーバーのパフォーマンスに影響を与えることがあります。一般的なガイドラインは、コア数×2+1ですが、この値はサーバーのスペックや負荷によって異なります。試しにワーカーの数を増減させて、最適な設定を見つけてみてください。たとえば、もし4コアのCPUを持っている場合、ワーカーの数を9から8に減らすことも考えられます。

nohup uvicorn main:app --port=80 --host=0.0.0.0 --workers=8

2.ASGIサーバーの変更:

UvicornはASGIサーバーの一つですが、他にも多くのASGIサーバーがあります。一部のプロジェクトでは、Uvicornよりも性能が良いとされるサーバーもあります。代替のASGIサーバーを試してみることを検討してください。例えば、HypercornやDaphneを試すことができます。

3.非同期コードの最適化:

FastAPIとUvicornは非同期処理に対応しており、遅いレスポンスの原因が非同期処理の最適化にあるかもしれません。コード内で非同期処理を効果的に利用しているか確認し、遅延を引き起こす部分を最適化してみてください。

4.リクエスト処理のプロファイリング:

レスポンスが遅い場合、どの部分が遅いのかを特定するためにリクエスト処理をプロファイリングすることが役立つことがあります。PythonのcProfileモジュールやプロファイリングツールを使用して、処理時間のかかる部分を特定し、最適化の手がかりを得ることができます。

5.サーバーリソースのモニタリング:

サーバーのリソース使用状況(CPU、メモリ、ディスクIOなど)を監視し、問題がリソース不足に起因している可能性を確認してください。リソースが不足している場合は、サーバーのスペックをアップグレードするか、アプリケーションのリソース使用効率を向上させるために最適化を行う必要があります。

6.キャッシュの導入:

レスポンスの一部が頻繁に変更されない場合、キャッシュを導入してレスポンスの返却を高速化することができます。FastAPIはキャッシュライブラリをサポートしています。

7.データベースの最適化:

データベースクエリがボトルネックになる場合、データベースクエリの最適化を検討してみてください。インデックスの追加やクエリのチューニングなどが役立つかもしれません。


これらのステップを試して、APIサーバーのパフォーマンスを向上させる手助けとなるでしょう。問題が解決しない場合は、詳細なプロファイリングやロギングを行い、具体的な問題点を特定することが重要です。

回答の追加

提供された情報から、APIサーバーが同時接続数が多くなる理由は明確にはわかりませんが、いくつかの一般的な理由が考えられます。同時接続数が多い場合、サーバーのリソースや処理能力に関連する問題が影響を及ぼす可能性があります。以下は考えられる理由です:

1.バッチ処理の要求が多い:

APIリクエストが別のバッチ処理から送信されていると記述されています。もしバッチ処理が瞬間的に多数のリクエストをサーバーに送信している場合、同時接続数が急増することがあります。

2.処理時間の長いリクエスト:

APIのリクエストによって、処理に時間がかかる場合、リクエストが待機状態になり、同時接続数が増加する可能性があります。この場合、非同期処理を活用してリクエストを非ブロッキングにすることで、同時接続数の制御が改善できます。

3.リクエストのポリングや長時間の接続:

バッチ処理がサーバーに対して長時間の接続を保持し、ポリングを行っている場合、同時接続数が増加することがあります。この場合、WebSocketなどのプッシュ通知の仕組みを検討して、リアルタイム通信を改善できるかもしれません。

4.サーバーのリソース不足:

サーバーのスペック(CPU、メモリ)が同時接続数を処理するには不足している可能性があります。サーバーのスペックをアップグレードすることで、同時接続数を増やすことができます。

5.スロークライアントやネットワークの問題:

一部のクライアントがリクエストを送信し続けることがあり、これが同時接続数を増やす要因となることがあります。また、ネットワークの問題や遅延も同時接続数に影響を及ぼす可能性があります。


同時接続数が問題となる場合、まずは何が同時接続数を増加させているのかを特定し、その要因に対処する必要があります。リクエストのパターンや処理時間を監視し、適切な対策を講じることで、同時接続数の制御とサーバーパフォーマンスの向上が可能です。