From 71c83e48bdee9e0c5930aeed0e86145080f4f0be Mon Sep 17 00:00:00 2001 From: "Zhang Rong(Jon)" Date: Mon, 17 Jan 2022 21:16:24 +0800 Subject: [PATCH] Fix: INF-253 o2 api failed after too many queries 1. Add load test scripts base on locust 2. Fix the DB pool size, extend to 200 Issue-ID: INF-253 Signed-off-by: Zhang Rong(Jon) Change-Id: I7d86c700e79f252e2ae0c5e08fa136d0cd13e52e --- o2app/adapter/unit_of_work.py | 14 ++++++++++---- o2app/bootstrap.py | 1 + tests/locust/README.md | 45 +++++++++++++++++++++++++++++++++++++++++++ tests/locust/ocloud.py | 35 +++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 tests/locust/README.md create mode 100644 tests/locust/ocloud.py diff --git a/o2app/adapter/unit_of_work.py b/o2app/adapter/unit_of_work.py index 000d181..732216e 100644 --- a/o2app/adapter/unit_of_work.py +++ b/o2app/adapter/unit_of_work.py @@ -27,15 +27,21 @@ from o2dms.adapter import dms_repository from o2common.helper import o2logging logger = o2logging.get_logger(__name__) + +engine = create_engine( + config.get_postgres_uri(), + isolation_level="REPEATABLE READ", + pool_size=200, max_overflow=0, + pool_recycle=3600 +) + DEFAULT_SESSION_FACTORY = sessionmaker( - bind=create_engine( - config.get_postgres_uri(), - isolation_level="REPEATABLE READ", - ) + autocommit=False, autoflush=False, bind=engine ) class SqlAlchemyUnitOfWork(AbstractUnitOfWork): + def __init__(self, session_factory=DEFAULT_SESSION_FACTORY): self.session_factory = session_factory diff --git a/o2app/bootstrap.py b/o2app/bootstrap.py index 6c5b276..329d9e2 100644 --- a/o2app/bootstrap.py +++ b/o2app/bootstrap.py @@ -54,6 +54,7 @@ def bootstrap( with uow: # get default engine if uow is by default engine = uow.session.get_bind() + wait_for_db_ready(engine) o2ims_orm.start_o2ims_mappers(engine) o2dms_orm.start_o2dms_mappers(engine) diff --git a/tests/locust/README.md b/tests/locust/README.md new file mode 100644 index 0000000..90ba3fb --- /dev/null +++ b/tests/locust/README.md @@ -0,0 +1,45 @@ +# locust for load testing + +## Start procedure + +Here is the sample command to run one master worker with 7 sub worker + +```bash +# main worker: +locust -f ocloud.py -H http://128.224.115.34:30205 --master + +# worker_1: +locust -f ocloud.py --worker +#worker_2: +locust -f ocloud.py --worker +#worker_3: +locust -f ocloud.py --worker +#worker_4: +locust -f ocloud.py --worker +#worker_5: +locust -f ocloud.py --worker +#worker_6: +locust -f ocloud.py --worker +#worker_7: +locust -f ocloud.py --worker +``` + +If you can use goreman to run [goreman](github.com/mattn/goreman), feel free to use it. + +```bash +cat Procfile<< +ocloud: locust -f ocloud.py -H http://128.224.115.34:30205 --master +ocloud_1: locust -f ocloud.py --worker +ocloud_2: locust -f ocloud.py --worker +ocloud_3: locust -f ocloud.py --worker +ocloud_4: locust -f ocloud.py --worker +ocloud_5: locust -f ocloud.py --worker +ocloud_6: locust -f ocloud.py --worker +ocloud_7: locust -f ocloud.py --worker +>>EOF +``` + +Run locust with 7 sub workers through goreman +```bash +goreman -f Procfile start +``` \ No newline at end of file diff --git a/tests/locust/ocloud.py b/tests/locust/ocloud.py new file mode 100644 index 0000000..3aa58c1 --- /dev/null +++ b/tests/locust/ocloud.py @@ -0,0 +1,35 @@ +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from locust import HttpUser, task, constant + + +class QuickstartUser(HttpUser): + wait_time = constant(0) + + @task + def ocloud(self): + self.client.get("/o2ims_infrastructureInventory/v1/") + + @task + def resource(self): + resp = self.client.get( + "/o2ims_infrastructureInventory/v1/resourcePools") + json_resp_dict = resp.json() + self.client.get( + "/o2ims_infrastructureInventory/v1/resourcePools/%s/resources" % + json_resp_dict[0]['resourcePoolId']) + + def on_start(self): + pass -- 2.16.6