Python을 이용해서 웹 프로그래밍을 하는 경우 일반적으로 gunicorn과 같은 WSGI(Web Server Gateway Interface) 프로그램을 사용하게된다. 그리고 웹 서비스를 이용하는 많은 요청(request)들의 응답 시간을 개선하기 위해 요청을 처리하는 worker process를 둘 이상 사용하는 경우가 흔하다.
아래는 3개의 worker process를 사용하는 옵션의 예이다.
$> gunicorn -w 3 -b :8000 run:app
위의 예와 같은 다중 프로세스 환경에서는 각 worker 프로세스는 run 스크립트의 app 모듈을 복사해서 사용하게된다. 만약 다중 프로세스 환경에서 app 모듈 안에서 사용되는 자원의 관리가 엄격하게 이루어지지 않는다면 각 프로세스가 서로 다른 시점의 데이터를 사용하게 되는 불일치 문제(data inconsistency problem)가 발생한다.
예를 들어 DB를 사용하는 경우 DB의 connection을 획득했으면 반드시 반납(close)해 주어야 한다. 아래는 DB를 사용하고 connection의 반납이 정상적으로 이루어지지 않은 경우다.
conn = pymysql.connect(host='localhost', user=cfg.DB_USER, password=cfg.DB_PASSWORD, \
db=cfg.DB, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
with conn.cursor() as cursor:
sql = 'INSERT INTO products (productNo, price, quantity) VALUES(%s, %s, %s)'
cursor.execute(sql, (productId, price, quantity))
conn.commit()
위의 예와 같이 DB의 connection 자원을 반납(close)하지 않으면 각 프로세스(worker)들은 DB의 복사된 내용을 cache처럼 가지고 있으면서 계속 사용하게 된다. 즉, 어떤 한 프로세스에 의해 데이터가 바뀌거나 삭제되어도 다른 프로세스는 그 사실을 알지 못하게된다. 따라서 다중 프로세스 환경에서는 모든 프로세스가 공동으로 사용하는 자원은 사용이 끝나면 아래 예와 같이 반드시 반납해주어야 한다.
conn = pymysql.connect(host='localhost', user=cfg.DB_USER, password=cfg.DB_PASSWORD, \
db=cfg.DB, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
with conn:
with conn.cursor() as cursor:
sql = 'INSERT INTO products (productNo, price, quantity) VALUES(%s, %s, %s)'
cursor.execute(sql, (productId, price, quantity))
conn.commit()
■
'프로그래밍 언어 | 컴퓨터 관련' 카테고리의 다른 글
비대칭 키 암호화 구조 (0) | 2021.10.22 |
---|---|
[React] 커링(Currying) (0) | 2021.09.13 |
[React] 화살표 함수에 대한 고찰 (0) | 2021.07.28 |
[정규표현식] .*? 패턴의 의미 (0) | 2021.07.23 |
[JavaScript] async, await 그리고 promise (0) | 2021.06.29 |
댓글