FalconでのREST APIの作成

Shane BouldenによるFalconとRHSCLを使用したスケーラブルなREST API作成の翻訳。

この記事では、Python Falconフレームワークに基づいてREST APIを作成し、パフォーマンスをテストして、負荷に対応するようにスケーリングを試みます。

APIを実装してテストするには、次のコンポーネントが必要です。


ファルコンを選ぶ理由


FalconはWeb APIを構築するための最小限のWebフレームワークであり、Falconのサイトによると、Flaskよりも最大10倍高速です。 ファルコンは速い!

開始する


PostgreSQLが既にインストールされていることを前提としています(これがなければPostgreSQLはインストールされません)。 orgdbデータベースとorguserユーザーを作成する必要があります。

このユーザーは、 pg_hba.confファイルのPostgreSQL設定で新しく作成されたデータベースへのパスワードアクセスを登録し、すべての権限を付与する必要があります。

データベース構成が完了しました。 Falconアプリケーションの作成に移りましょう。

APIの作成


このアプリケーションでは、Python3.5を使用します。

virtualenvを作成し、必要なライブラリをインストールします。

$ virtualenv ~/falconenv $ source ~/falconenv/bin/activate $ pip install peewee falcon gunicorn 

ファイル「app.py」を作成します。

 import falcon from models import * from playhouse.shortcuts import model_to_dict import json class UserIdResource(): def on_get(self, req, resp, user_id): try: user = OrgUser.get(OrgUser.id == user_id) resp.body = json.dumps(model_to_dict(user)) except OrgUser.DoesNotExist: resp.status = falcon.HTTP_404 class UserResource(): def on_get(self, req, resp): users = OrgUser.select().order_by(OrgUser.id) resp.body = json.dumps([model_to_dict(u) for u in users]) api = falcon.API() users = UserResource() users_id = UserIdResource() api.add_route('/users/', users) api.add_route('/users/{user_id}', users_id) 

ファイル 'models.py'のモデルについて説明します。

 from peewee import * import uuid psql_db = PostgresqlDatabase( 'orgdb', user='orguser', password='123456', host='127.0.0.1') def init_tables(): psql_db.create_tables([OrgUser], safe=True) def generate_users(num_users): for i in range(num_users): user_name = str(uuid.uuid4())[0:8] OrgUser(username=user_name).save() class BaseModel(Model): class Meta: database = psql_db class OrgUser(BaseModel): username = CharField(unique=True) 

アプリケーション 'init_tables'および 'generate_users'を構成する2つのヘルパーメソッドを作成しました。 それらを実行してアプリケーションを初期化します。

 $ python Python 3.5.1 (default, Sep 15 2016, 08:30:32) Type "help", "copyright", "credits" or "license" for more information. >>> from app import * >>> init_tables() >>> generate_users(20) 

orgdbデータベースにアクセスすると、作成されたユーザーがorguserテーブルに表示されます。

これで、APIをテストできます。

 $ gunicorn app:api -b 0.0.0.0:8000 [2017-12-11 23:19:40 +1100] [23493] [INFO] Starting gunicorn 19.7.1 [2017-12-11 23:19:40 +1100] [23493] [INFO] Listening at: http://0.0.0.0:8000 (23493) [2017-12-11 23:19:40 +1100] [23493] [INFO] Using worker: sync [2017-12-11 23:19:40 +1100] [23496] [INFO] Booting worker with pid: 23496 $ curl http://localhost:8000/users [{"username": "e60202a4", "id": 1}, {"username": "e780bdd4", "id": 2}, {"username": "cb29132d", "id": 3}, {"username": "4016c71b", "id": 4}, {"username": "e0d5deba", "id": 5}, {"username": "e835ae28", "id": 6}, {"username": "952ba94f", "id": 7}, {"username": "8b03499e", "id": 8}, {"username": "b72a0e55", "id": 9}, {"username": "ad782bb8", "id": 10}, {"username": "ec832c5f", "id": 11}, {"username": "f59f2dec", "id": 12}, {"username": "82d7149d", "id": 13}, {"username": "870f486d", "id": 14}, {"username": "6cdb6651", "id": 15}, {"username": "45a09079", "id": 16}, {"username": "612397f6", "id": 17}, {"username": "901c2ab6", "id": 18}, {"username": "59d86f87", "id": 19}, {"username": "1bbbae00", "id": 20}] 

テストAPI


Taurusを使用してAPIのパフォーマンスを評価しましょう。 可能であれば、別のマシンにTaurusをデプロイします。

仮想環境にTaurusをインストールします。

 $ pip install bzt 

これで、テスト用のスクリプトを作成できます。 次の内容でbzt-config.ymlファイル作成します(正しいIPアドレスを指定することを忘れないでください)。

 execution: concurrency: 100 hold-for: 2m30s ramp-up: 1m scenario: requests: - url: http://ip-addr:8000/users/ method: GET label: api timeout: 3s 

このテストでは、100人のユーザーからのWebトラフィックを1分以内に数を増やしながらシミュレートし、負荷を2分30秒保持します。

1つのワーカーでAPIを実行します。

 $ gunicorn --workers 1 app:api -b 0.0.0.0:8000 

これでおうし座を実行できます。 最初の起動時に、必要な依存関係をダウンロードします。

 $ bzt bzt-config.yml -report 

依存関係をインストールすると、コンソールにテストの進行状況が表示されます。



-reportオプションを使用して結果をBlazeMeterにアップロードし、Webレポートを生成します。

私たちのAPIは100人のユーザーで素晴らしい仕事をしています。 エラーがなく、平均応答時間は0.1秒で、1秒あたり約1000リクエストのスループットに達しました。



さて、500人のユーザーがいる場合はどうなりますか? bzt-config.ymlファイル並行性パラメーターを500に変更し、Taurusを再度実行します。



ふむ 私たちの孤独な労働者は負荷に対処しなかったようです。 エラーの40%はそうではありません。

労働者の数を増やしてみましょう。

 gunicorn --workers 20 app:api -b 0.0.0.0:8000 



良く見えます。 エラーはまだありますが、スループットは1500リクエスト/秒まで増加し、平均応答時間は270ミリ秒まで減少しました。 このようなAPIはすでに使用できます。

さらなるパフォーマンスの最適化


PgTuneを使用して、PostgreSQLをハードウェア用に構成できます。

今日は以上です。 読んでくれてありがとう!

Source: https://habr.com/ru/post/J347064/


All Articles