Python bottleフレームワークを使用してますがメモリがどんどん溜まっていきます

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 220

Kyojiro

score 4

現在、Bottleフレームワークを使用して、WEBサーバーとして(具体的には、appd.pyを)バックグラウンドでデーモンとして使用しております。処理が実行されるたび、appd.pyを経由して処理されますが、メモリがその都度どんどん増えていきます。
運用として、appd.pyのプロセスを終了させることができませんが、増えていくメモリを開放したいです。

感じたことは
・自動的にガベージコレクトがされないかもしれません
・明示的に ガベージコレクトや del を使用して開放したいのですが、最終 bottle.template に変数を連携するため、それも叶っておりません。

このことから、以下の方法について質問させてください。

質問1) bottle.template を使用していてもどこかでガベージコレクトやdel をする処理を挿入することができるかどうか?

質問2) python側で未使用のメモリを調査・抽出して、開放(削除)する方法があるのでしょうか?

質問3) サーバーの構成をWSGIなどを導入して、この問題を回避することができるのでしょうか?

今回pythonを使用してWEB環境を構築したのが初めてなもので、お力をお貸し頂けたらと思います。

■コマンドにつきまして(起動)

$ cd /var/www/htdocs/contents/
$ python appd.py

■appd.pyの主要なコードを記述します

from bottle import (route, template, error, response,
                    request, HTTPError, HTTPResponse, TEMPLATE_PATH,
                    abort, run, redirect, debug, Bottle, static_file)
from beaker.middleware import SessionMiddleware
from paste import httpserver as web

import os
import sys
import time
import math
from datetime import datetime, timedelta
import re
session_timeout = 3600000
session_opts = {
            'session.type': 'file',
            'session.timeout': session_timeout,
            'session.cookie_expires': True,
            'session.data_dir': './data',
            'session.auto': True,
            'save_accessed_time': False
             }

app = Bottle()
apps = SessionMiddleware(app, session_opts) 
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_PATH.append(BASE_DIR + "/views")

@app.route('/view_page/', method='GET')
def view_page():
    check_login()
    #user_id = int(request.forms.user_id)

    import c_database

    login = request.environ.get('beaker.session')
    session_user_id=login.get('user_id')

    db = c_database.connect_database()
    connect = db[0]
    cur = db[1]

    sql = "SELECT uri, domain FROM user_domains WHERE user_id = %s"
    cur.execute(sql,  (session_user_id, ))
    rows = cur.fetchone()
    if isinstance(rows, type(None)) :
        raise HTTPError(status=401, body="データは存在しません。")
    else :
        db_uri = rows[0]
        db_domain = rows[1]

    c_database.close_database(connect, cur)

    return template('view_page', tp=BASE_DIR + "/views/", page_name='ページ表示',
        uri=db_uri,
        domain=db_domain)


def daemon_serv():
    pid = os.fork()
    try:
     if pid != 0:
          fd = open('./bottle.pid','w')
          fd.write(str(pid) + '\n')
          fd.close()
          sys.exit()

    except OSError as e:
          sys.stderr.write("BottleFork: Failed: %d (%s)\n" % (e.errno, e.strerror))
          sys.exit(1)

    while 1:
        web.serve(apps, host='localhost', port=8000,daemon_threads=False,threadpool_workers=10,use_threadpool=100)


if __name__ == "__main__":
  daemon_serv()


■WEBからのアクセス
http://localhost:8000/view_page

※コードは主要部分だけに加工しました

■メモリについてはMonitという追加モジュールでプロセス管理をしておりまして、
Process 欄のメモリについて
memory                       0.3% [101.9 MB]
memory total                 0.3% [101.9 MB]

処理ごとにmemory とmemory totalが 数十MBずつ増えていきます

以上、宜しくお願い致します

▼ 2019/05/18
現在メモリを調査しておりまして、こちらの検証結果について改めてご連絡させて頂きます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mather

    2019/05/15 11:10

    ・起動方法をコマンドで具体的に示してください
    ・書いたコードを示してください。
    ・「使用メモリが増える」と検出した方法と具体的な数値を書いてください。

    キャンセル

  • この投稿は削除されました

  • この投稿は削除されました

回答 1

+2

bottleを使っている割にプロセスフォークしたり別のWebサーバーを立てたりと色々やっているようですが、
何かを参考にして or 何かの理由があって複雑な構成になっているのでしょうか。

まずはシンプルにbottleフレームワークを使ってみてはどうでしょうか。

公式サイトの安定版 0.12 - https://bottlepy.org/docs/0.12/

公式サイトのHello, world!サンプルを引用します。

from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)

run(host='localhost', port=8080)

これだけでシンプルなWebサーバーが起動するはずですよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/16 19:45

    アドバイス有難うございます!

    シンプルにいちからBottleを構築してみました
    $ python appd_test.py
    で起動して、メモリを消費するような作業を数回実施し、メモリの使用量を3回確認してみたところ、どんどん増えていっていることがわかります。

    # USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    #user 8048 0.7 0.1 317140 37248 pts/0 S 19:28 0:10 python appd_test.py
    #user 8048 1.2 0.1 341732 56200 pts/0 S 19:28 0:10 python appd_test.py
    #user 8048 1.9 0.3 986784 113564 pts/0 S 19:28 0:10 python appd_test.py

    そもそもBottleのメモリ管理がどうなっているか、どう運用されているかなどご教示頂けましたら幸いです。

    宜しくお願い致します

    キャンセル

  • 2019/05/16 19:52

    いや複数プロセスが発生している事自体がおかしいのです。
    どんなコードを書いてどうやって起動しているのか質問を編集して追記してください。

    キャンセル

  • 2019/05/16 22:01 編集

    誤解を与えるような変な書き方で申し訳ございません。
    時系列に書いてしまいました。おっしゃる通り、プロセスは1つ(PID=8048)です。
    # USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    #user 8048 0.7 0.1 317140 37248 pts/0 S 19:28 0:10 python appd_test.py →1回目の$ ps コマンド
    #user 8048 1.2 0.1 341732 56200 pts/0 S 19:28 0:10 python appd_test.py →2回目の$ ps コマンド
    #user 8048 1.9 0.3 986784 113564 pts/0 S 19:28 0:10 python appd_test.py →3回目の$ ps コマンド

    現在メモリを調査しておりまして、こちらの検証結果についても改めてご連絡させて頂きます。

    キャンセル

  • 2019/05/17 10:48

    現在の appd_test.py の内容を質問に追記してください。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる