現在、Bottleフレームワークを使用して、WEBサーバーとして(具体的には、appd.pyを)バックグラウンドでデーモンとして使用しております。処理が実行されるたび、appd.pyを経由して処理されますが、メモリがその都度どんどん増えていきます。
運用として、appd.pyのプロセスを終了させることができませんが、増えていくメモリを開放したいです。
感じたことは
・自動的にガベージコレクトがされないかもしれません
・明示的に ガベージコレクトや del を使用して開放したいのですが、最終 bottle.template に変数を連携するため、それも叶っておりません。
このことから、以下の方法について質問させてください。
質問1) bottle.template を使用していてもどこかでガベージコレクトやdel をする処理を挿入することができるかどうか?
質問2) python側で未使用のメモリを調査・抽出して、開放(削除)する方法があるのでしょうか?
質問3) サーバーの構成をWSGIなどを導入して、この問題を回避することができるのでしょうか?
今回pythonを使用してWEB環境を構築したのが初めてなもので、お力をお貸し頂けたらと思います。
■コマンドにつきまして(起動)
sh
1$ cd /var/www/htdocs/contents/ 2$ python appd.py
■appd.pyの主要なコードを記述します
Python
1from bottle import (route, template, error, response, 2 request, HTTPError, HTTPResponse, TEMPLATE_PATH, 3 abort, run, redirect, debug, Bottle, static_file) 4from beaker.middleware import SessionMiddleware 5from paste import httpserver as web 6 7import os 8import sys 9import time 10import math 11from datetime import datetime, timedelta 12import re 13session_timeout = 3600000 14session_opts = { 15 'session.type': 'file', 16 'session.timeout': session_timeout, 17 'session.cookie_expires': True, 18 'session.data_dir': './data', 19 'session.auto': True, 20 'save_accessed_time': False 21 } 22 23app = Bottle() 24apps = SessionMiddleware(app, session_opts) 25BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 26TEMPLATE_PATH.append(BASE_DIR + "/views") 27 28@app.route('/view_page/', method='GET') 29def view_page(): 30 check_login() 31 #user_id = int(request.forms.user_id) 32 33 import c_database 34 35 login = request.environ.get('beaker.session') 36 session_user_id=login.get('user_id') 37 38 db = c_database.connect_database() 39 connect = db[0] 40 cur = db[1] 41 42 sql = "SELECT uri, domain FROM user_domains WHERE user_id = %s" 43 cur.execute(sql, (session_user_id, )) 44 rows = cur.fetchone() 45 if isinstance(rows, type(None)) : 46 raise HTTPError(status=401, body="データは存在しません。") 47 else : 48 db_uri = rows[0] 49 db_domain = rows[1] 50 51 c_database.close_database(connect, cur) 52 53 return template('view_page', tp=BASE_DIR + "/views/", page_name='ページ表示', 54 uri=db_uri, 55 domain=db_domain) 56 57 58def daemon_serv(): 59 pid = os.fork() 60 try: 61 if pid != 0: 62 fd = open('./bottle.pid','w') 63 fd.write(str(pid) + '\n') 64 fd.close() 65 sys.exit() 66 67 except OSError as e: 68 sys.stderr.write("BottleFork: Failed: %d (%s)\n" % (e.errno, e.strerror)) 69 sys.exit(1) 70 71 while 1: 72 web.serve(apps, host='localhost', port=8000,daemon_threads=False,threadpool_workers=10,use_threadpool=100) 73 74 75if __name__ == "__main__": 76 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
現在メモリを調査しておりまして、こちらの検証結果について改めてご連絡させて頂きます。