TECH ARTICLE

JENNIFER Python 첫 버전을 내놓으며…

근래 데이터 프로세싱 분야에서 두각을 나타낸 Python 언어는 개발자로 하여금 그 개발 경험을 자연스럽게 웹으로 확장시켰고, 이와 함께 Django나 Flask 같은 웹 프레임워크를 이용한 서비스가 엔터프라이즈 환경에서도 마이크로서비스의 일환으로 안착하기 시작했습니다.

이러한 변화를 따라 제니퍼소프트는 Python 환경에 대한 모니터링 지원을 추가한 첫 번째 버전을 릴리스했습니다. 이 문서에서는 JENNIFER Python 에이전트만의 특징과 동작 방식을 설명합니다.

제니퍼 파이썬 무료 설치 프로모션: https://jennifersoft.com/ko/blog/event-blog/2022-06-13/

지원환경

Python 언어는 플랫폼 독립적이라고 익히 잘 알려져 있습니다. 하지만 Python 언어 스펙의 활발한 발전과 그것을 둘러싼 런타임 환경으로 인해 APM 제품 입장에서는 자바/닷넷 등의 환경보다 제약이 더 심하다는 특징을 가집니다.

리눅스만 지원

엄밀히 Django/Flask와 같은 프레임워크는 플랫폼에 무관하게 실행할 수 있습니다. 하지만 대부분의 서비스 환경에서는 uwsgi 또는 gunicorn 등의 WSGI 인터페이스를 지원하는 전용 웹 애플리케이션을 통해 호스팅하는데, 여기서 문제는 해당 응용 프로그램이 오직 리눅스만을 지원한다는 점입니다.

이것의 근본적인 원인은, Python 인터프리터가 갖는 “GIL(Global Interpreter Lock)”이라고 알려진 전역 잠금 때문입니다. GIL을 획득한 하나의 스레드만이 Python의 바이트 코드를 처리할 수 있는데 일반적인 환경이라면 이것이 큰 문제가 되지 않지만 다중 요청을 스레드에 기반해 처리하는 웹 애플리케이션 환경의 경우 GIL로 인해 심각한 성능 저하가 발생합니다.

이를 우회하기 위해 Python을 위한 WSGI 웹 애플리케이션(uwsgi, gunicorn 등)은 스레드의 사용 대신 fork로 프로세스를 나누는 방법을 선택했습니다. 따라서 Django/Flask 자체는 윈도우 환경에서도 실행할 수 있지만 그것을 호스팅하는 uwsgi/gunicorn은 (fork의 사용으로 인해) 윈도우를 지원하지 못하므로 JENNIFER Python도 현재 리눅스 환경의 모니터링만 지원합니다.

특정 Python 런타임 및 패키지의 버전 지원

Python 언어는 버전 업그레이드에 따른 하위 호환성이 좋지 않습니다. 프로세스 내에 함께 올라오는 JENNIFER Python 모듈도 결국 내부적으로는 Python 언어를 사용하므로 동일하게 런타임의 제약을 받아 하위 호환성에 영향을 받습니다.

이러한 문제는 Python 런타임뿐만 아니라 패키지에도 적용됩니다. 대부분의 패키지가 하위 호환성이 없는데다 APM 제품의 특성상 대상 패키지의 내부 코드에 밀접하게 연동할 수밖에 없어 패키지 버전별로 지원을 추가해야 하는 문제가 있습니다.

결국 고객 사이트에서 운영하는 Python 웹 애플리케이션이 JENNIFER Python 제품에서 지원하는 런타임 및 패키지의 버전 조건에 부합해야만 원하는 수준의 모니터링이 가능합니다. 만약 그렇지 않다면 아직 지원하지 않는 패키지나 그에 따른 버전에 대해 미리 사전 협의를 통해 JENNIFER Python에 기능 추가를 하는 등의 시간이 요구됩니다.

동작구조

이전에 설명했듯이 Python 웹 응용 프로그램을 호스팅하는 uwsgi나 gunicorn 등은 기본적으로 동작 방식이 fork를 기반으로 합니다. 따라서 단일 프로세스에서 활성화되는 기존 자바/닷넷 에이전트와는 다른 구조를 채택할 수밖에 없습니다.

즉, fork되는 프로세스마다 제니퍼 모듈이 로드돼 동작해야 하지만, 그 프로세스 한 개마다 제니퍼 뷰에서 인스턴스 하나로 인식시킬 수는 없습니다. 따라서 하나의 응용 프로그램을 대표하면서도 fork 프로세스와 통신을 하는 별도의 프로세스가 필요합니다. 이를 반영해 JENNIFER Python은 다음과 같은 구조로 활성화됩니다.

그림 1 : 웹 응용 프로그램 1개를 위한 JENNIFER Python 동작 구조

Proxy 프로세스는 JENNIFER 데이터 서버와 단일 TCP 연결로 통신하며, 내부의 fork 프로세스와는 UNIX Socket을 이용해 통신합니다.

이러한 구조 덕분에 제니퍼 콘솔에서 보이는 모니터링 화면은 기존의 자바/닷넷과 비교해 크게 다르지 않습니다.

설치 및 제거

Python 생태계에는 PyPI라는 잘 조직된 패키지 저장소가 있습니다. JENNIFER Python도 이곳에 배포돼 있으며 현재 다음의 주소에서 열람할 수 있습니다.

jennifer-python: https://pypi.org/project/jennifer-python/

따라서 설치는 기존의 파이썬 패키지들과 다름없이 pip를 이용합니다.

$ pip install jennifer-python

설치 후, 가장 먼저 해야 할 작업은 “제니퍼 데이터 서버”로의 연결 정보를 담은 INI 설정 파일을 만드는 것입니다. 이 파일은 수작업으로도 작성이 가능하지만 “jennifer-python” 패키지와 함께 설치되는 “jennifer-admin” 명령어를 통해 다음과 같이 간편하게 기본 INI 파일을 생성할 수 있습니다.

$ jennifer-admin generate-config

그럼 해당 명령어를 실행한 디렉터리를 기준으로 “jennifer.ini” 파일이 다음의 내용으로 생성이 됩니다.

[JENNIFER]

server_address = 127.0.0.1
server_port = 5000
domain_id = 1000
inst_id = -1
log_path = /tmp/jennifer-python-agent.log

이후 편집기를 통해 각각의 필드에 대한 값을 다음의 기준에 맞게 설정합니다.

필드 설명
server_address 제니퍼 Data Server의 IP
server_port 제니퍼 Data Server의 Port (기본값 5000)
domain_id 도메인 ID (Data Server에 구성한 ID, 기본값 1000)
inst_id 모니터링 되는 Python 응용 프로그램의 식별자 (int16 범위의 숫자) -1을 설정하면 제니퍼 Data Server 측에서 자동으로 결정
log_path log 파일의 경로

jennifer.ini 파일은 하나의 Python 응용 프로그램마다 생성해야 하고, 이때 inst_id 값만 다르게 하면 됩니다.

이후 해당 INI 파일 설정으로 모니터링 대상이 되는 Python 응용 프로그램을 jennifer-python 모듈을 연결해 실행시켜야 합니다. 이때 INI 파일 경로를 환경 변수를 통해 함께 설정하는 방법을 이용하면 다음과 같은 형식으로 Python 웹 응용 프로그램을 실행할 수 있습니다.

$ JENNIFER_CONFIG_FILE=<설정 파일경로> jennifer-admin run <기존 python 실행 코드>

만약 여러분들의 응용 프로그램을 기존에 “uwsgi -i uwsgi.ini”로 실행했고, 만들어 둔 jennifer.ini 파일의 경로가 /home/user/jennifer.ini라고 한다면 아래와 같이 실행할 수 있습니다.

$ JENNIFER_CONFIG_FILE=/home/user/jennifer.ini jennifer-admin run uwsgi -i uwsgi.ini

모든 설정이 올바르다면 uwsgi의 실행 화면에는 다음과 같은 로그 메시지가 함께 출력되는 것을 확인할 수 있습니다.

…[생략]…
---------------- [App Initialized] ----------------------
MachineName =  TESTPC
Is64BitProcess =  ('64bit', 'ELF')
Python Version =  3.8.10
Jennifer Python Agent Install Path =  /usr/local/lib/python3.8/site-packages/jennifer
Jennifer Python Agent Domain ID =  2790
Jennifer Python Agent Inst ID =  601
Jennifer Python Agent Pid =  4925
---------------------------------------------------------
…[생략]…

반면 에이전트를 웹 응용 프로그램에서 내리고 싶다면 “jennifer-admin”을 경유하지 않고 기존 방식처럼 실행하기만 하면 됩니다. 또한 JENNIFER Python 바이너리 자체를 삭제하고 싶다면 마찬가지로 pip을 이용해 제거할 수 있습니다.

$ pip uninstall jennifer-python

지원기능

제니퍼 콘솔 화면에서 보이는 모니터링은 Active Service 뷰와 X-View 프로파일을 만족시키므로 기본적인 수준에서는 기존의 JENNIFER 자바/닷넷과 유사한 경험으로 모니터링을 할 수 있습니다.

[그림 2 : Python 에이전트를 설치한 3개의 인스턴스]
[그림 3 : X-View 상세보기를 통한 프로파일 확인]

프로파일 대상은 현재 이 글을 쓰는 시점(2022-05-20)을 기준으로 다음과 같은 HTTP 및 DB 호출을 지원합니다.

  • urllib, requests
  • mysql, redis, mongo db, sqlite3

그 외에 아직 초기 버전이어서 기존의 JENNIFER Java/.NET 제품에서 제공하는 많은 기능들을 구현하지 못했지만 차차 기능을 보완할 예정이니 기대해 주시기 바랍니다.

Next

Contact Us

안녕하세요? 제니퍼소프트입니다.
기술 문의의 경우 질문자의 회사/이름/연락처를 본문에 기술해 주셔야만 원할한 지원이 가능합니다.
보내주신 문의 사항을 검토하여 빠른 시일 내에 답변해 드리겠습니다.

  • Chris
  • Irene

메일을 보냈습니다.

메일 전송이 완료되었습니다.
빠른 시일 내에 답변드리겠습니다.
감사합니다.
제니퍼소프트 웹사이트는 쿠키를 사용합니다. 쿠키에 대한 자세한 정보 및 삭제 방법은 제니퍼소프트의 개인정보처리방침을 참고하시기 바라며 본 사이트를 계속해서 이용하는 것은 제니퍼소프트의 쿠키 사용에 동의함을 의미합니다.