일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- boj
- 알고리즘
- 시뮬레이션
- Priority Queue
- GitHub
- 코테
- gpdb
- SQL
- Bruth Force
- aws
- 알고리듬
- Python
- DFS
- spring boot
- hash table
- 구현
- django
- Linked list
- Vue.js
- programmers
- Algorithm
- SWEA
- 모의SW역량테스트
- CSV
- Trie
- Back tracking
- BFS
- 코딩테스트
- JavaScript
- Data Structure
- Today
- Total
hotamul의 개발 이야기
[Flask] (psycopg2.OperationalError) server closed the connection unexpectedly. This probably means the server terminated abnormally before or while processing the request. 본문
[Flask] (psycopg2.OperationalError) server closed the connection unexpectedly. This probably means the server terminated abnormally before or while processing the request.
hotamul 2022. 8. 12. 20:24Flask를 사용해서 API 서버를 구축하게 되었는데 local에서는 발생하지 않았다가 운영 서버에 배포하고 나서부터 발생했던 psycopg2.OperationError
해결 방법을 공유하고자 한다.
psycopg2.OperationError
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/sql/elements.py", line 287, in _execute_on_connection
Return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/engine/base.py", line 1107, in _execute_clauseelement
Distilled_params,
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/engine/base.py", line 1248, in _execute_context
e, statement, parameters, cursor, context
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/engine/base.py", line 1466, in _handle_dbapi_exception
Util.raise_from_cause(sqlalchemy_exception, exc_info)
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/util/compat.py", line 383, in raise_from_cause
Reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/engine/base.py", line 1244, in _execute_context
Cursor, statement, parameters, context
File "/usr/local/lib/python3.8.9/site-packages/sqlalchemy/engine/default.py", line 552, in do_execute
Cursor.execute(statement, parameters)
OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
배포를 마치고 퇴근한 뒤 아침에 서버에서 잘 실행되고 있나 확인하기 위해서 GET, POST 등등 여러 request를 실행해보니 Internal Server Error
가 발생하는 것을 확인했다.
그래서 해당 운영서버에 로그를 뒤져보니 위와 같은 에러가 발생한 것을 확인할 수 있었다.
뭐가 잘못된 걸까하고 SQLAlchemy
의 연결이 언제 끊어지는지 찾아보던 중 SQLAlchemy의 연결 풀링 이해하기 해당 글을 보게 되었고 해결책을 찾을 수 있었다.
문제는 SQLAlchemy
의 QueuePool
생애주기
큐 풀이 처음부터 연결을 미리 만드는 것은 아닙니다. 일단 0개로 시작합니다.
오랜 시간 동안 요청이 없게 되면 SQLAlchemy
QueuePool
이 연결이 없어지게 되고 새로 request가 발생하면 첫 번째 request에서는 위와 같은 psycopg2.OperationError
가 발생하게 되는 것이었다.
해결방법은 여러가지가 있을 수 있겠지만 (정책적으로 Connection refresh 주기 설정, Connection Pool minimun 설정 등등...) 해당 문제는 서버 운영에 Critical한 문제라고 생각해 조금은 보수적인 방법을 선택했다. (SQLAlchemy
공식 문서에서는 Pessimistic하다고 하던데 같은 의미인지는 잘 모르겠다.)
(참고: SQLAlchemy - disconnect handling) SQLAlchemy
engine_option
에서 pool_pre_ping
옵션을 True
로 설정하면 문제를 해결할 수 있다.
"Pre ping" 기능은 일반적으로 풀에서 연결이 체크아웃될 때마다 "SELECT 1"에 해당하는 SQL을 내보냅니다. "연결 해제" 상황으로 감지된 오류가 발생하면 연결이 즉시 재활용되고 현재 시간보다 오래된 다른 풀링된 연결은 모두 무효화되어 다음에 체크아웃할 때도 재활용됩니다. 사용하기 전에.
(참고: Flask-SQLAlchemy Configuration) SQLALCHEMY_ENGINE_OPTIONS
을 아래와 같이 key value 값으로 설정해 주면 된다.
class Config:
...
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_pre_ping": True
}
SQLALCHEMY_TRACK_MODIFICATIONS = False
...
}
'Dev. > Flask' 카테고리의 다른 글
[Flask] Flask란? (feat. uWSGI, WSGI) (0) | 2022.08.18 |
---|---|
[Flask] Github Action CI (Flask & Docker) (0) | 2022.08.12 |
[Flask] Flask & docker-compose wait for db (0) | 2022.08.10 |
[Flask] Flask & Docker (Dockerfile 작성 방법) (0) | 2022.07.30 |