python 쓰레드를 uWSGI로 서비스시 문제점

최근 python thread로 타이머를 구현, 이를 uWSGI로 서비스 하는 과정에서 thread가 동작하지 않아 관련 내용을 정리함.

예제코드는 아래와 같음.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import time
import threading
from flask import Flask

i = 0

def thread_run():
    global i
    while True:
        i += 1
        time.sleep(3)

app = Flask(__name__)
th = threading.Thread(target=thread_run)
th.start()

@app.route('/')
def index():
    return str(i)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888)

위 코드를 아래의 명령어로 uWSGI로 실행

1
2
3
sudo uwsgi --socket 0.0.0.0:8888 --protocol=http -w test --callable app --master --enable-threads

sudo uwsgi --socket 0.0.0.0:8888 --protocol=http -w test --callable app --master

위 명령어들로 각 각 80번 포트로 접근하면 모두 쓰레드가 동작하지 않음을 확인. 다시 아래 코드로 실행.

1
sudo uwsgi --socket 0.0.0.0:8888 --protocol=http -w test --callable app

잘 동작함! 이유는 --master 옵션에 있는 것으로 확인. 관련 내용은 아래 링크에 잘 정리되어 있음. https://stackoverflow.com/questions/32059634/python3-threading-with-uwsgi

그럼 쓰레드를 동작시킬 방법은? 코드를 아래와 같이 수정.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import time
import uwsgidecorators
from flask import Flask

i = 0

@uwsgidecorators.postfork
@uwsgidecorators.thread
def thread_run():
    global i
    while True:
        i += 1
        time.sleep(3)

app = Flask(__name__)

@app.route('/')
def index():
    return str(i)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888)

그리고 아래 명령어로 실행.

1
sudo uwsgi --socket 0.0.0.0:8888 --protocol=http -w test --callable app --master --enable-threads

uWSGI가 master 모드로 동작하며 쓰레드도 잘 동작함을 확인할 수 있음.
uWSGI decorators에 괜찮은 기능이 많다. 상세내용은 아래 링크를 참조.

https://uwsgi-docs.readthedocs.io/en/latest/PythonDecorators.html#module-uwsgidecorators https://pythonise.com/series/learning-flask/exploring-uwsgi-decorators

Hugo로 만듦
Jimmy의 Stack 테마 사용 중