# My Projects 이민철 [TOC] ## Production #### *[매스프레소 (콴다) 2020.8 ~ Now]* ### S3 to GCS Migration *Go, MySQL* 2022.09 - 2022.11 - AWS to GCP 과정중 남아있는 S3 dependency 를 GCS 로 옮기고 서버에서 해당 부분을 GCS API를 사용하도록 변경 - API response 와 DB column 에서 전반적으로 uri 필드 마이그레이션 ### 검색 서비스 DB Migration *Go, DynamoDB, MySQL, Athena, SQS* 2022.07 - 2022.09 - AWS DynamoDB 에서 GCP CloudSQL 로 마이그레이션 및 스키마 변경 - 마이그레이션 대상 후보군을 선정하고 모든 후보군에 대해 production 환경과 비슷한 데이터에서 실제 트래픽을 미러링하여 벤치마크 진행 - 월 비용 약 63% 절감 (3년 RI 적용시 89% 절감) - DynamoDB 대비 약간의 latency 성능 향상 - 마이그레이션 과정을 개선하여 수천달러로 예상되는 sync 비용을 수백달러 수준으로 감소 ### thumbnail 서비스 및 파이프라인 개선 *Go, Python, GCS, CloudRun, GRPC* 2022.04 - 2022.08 - 여러군데 흩어져 있던 thumbnail bucket 을 한군데로 통합 - 모든 이미지 포맷에 대해 이미지 인코딩 실험을 진행하고 최적의 파라미터를 찾아내 78% 의 storage 용량 절약 - thumbnail 을 build 하는 파이프라인 전체 새로 개발 - AWS S3, Lambda 스택에서 GCP GCS, CloudRun 스택으로 마이그레이션 - expire time 이 있는 signed url 도입 ### 사내 Admin 서비스 API 개발 *Go, Echo, MySQL, JWT* 2022.02 - 2022.04 - user 와 authenticate 기능의 DB 설계 및 API, middleware 개발 - GCP 의 IAP(Identity-Aware Proxy) 도입 ### Protocol Buffers 및 GRPC package 모노레포 구축 *Protocol Buffers, Buf, Go, Python* 2022.01 - 2022.02 - Protocol Buffers 를 API DDL 로써 사용하여 사내 API 모노레포를 만들고 Buf 와 api linter 를 도입하여 사내 동료들이 편하게 개발하고 쉽게 GRPC 와 OpenAPI document 를 빌드할 수 있는 환경 구성 - 신규 기술을 적용하기 전 grpc, buf, bazel, twirp, grpc-gateway, openapiv2-generator 등 팀원들이 궁금해했던 기술들을 앞장서 테스트해보고 장단점을 비교하고 이를 공유하여 어떤게 팀 needs 에 적합한지 판별 ### OCR API 서버 및 인프라 재구축 *Go, Python, Gin, Flask* 2021.09 - 2022.01 - Python API 서버로 만들어진 서비스를 Go HTTP 서버로 전체 재작성 하여 비용을 대폭 절감하고 (월 $6000 정도의 비용 감소), 전반적인 서버 구조를 리팩터링 하여 더 쉬운 유지보수가 가능하도록 설계 - 추후 inference server 의 확장성을 위해 SQS worker 구조의 inference 방식에서 HTTP 방식의 worker 형태로 전환하고 효율적인 로드밸런싱 방법 고안 - ML 서빙을 쉽게 패키징 할 수 있는 사내 표준 ml serving framework 개발 -> 약 1년간 사내에서 표준으로 사용되다가 후에 BentoML 로 전환 - AI 모델 서버에 대하여 부하테스트를 진행하여 최적의 파라미터와 인스턴스 타입을 선택하여 약 37% 의 비용을 절감 ### 파트타임 직원이 사용하는 작업자/관리자 서버 API 개발 2021.07 - 2021.09 *Go, Echo, MySQL* - 이미지를 텍스트로 바꾸는 작업을 위한 서비스의 DB와 API 설계 및 개발 - pair 프로그래밍을 주도하여 서로간의 배움과 꼼꼼한 리뷰를 할 수 있어 많은 버그를 미연에 방지 ### N:M 관계의 질문 답변을 고려한 새로운 검색 로직 작성 2021.06 - 2021.07 *Go, DynamoDB* - 더 나은 답변을 찾을 수있는 구조를 만들기 위해 1:1 질문-답변 의 관계를 타파하고 N:M 관계의 질문-답변을 고려한 새로운 검색 로직을 만들고 배포 ### 유저간 질문 답변 기능 개발 2021.04 - 2021.06 *Go, Python, Gin, Django, MySQL* - 학년이 비슷한 다른 유저가 해결하지 못했던 문제를 보여주고 유저가 직접 답변을 제출 할 수 있도록 하는 기능의 API 개발 - 다른 유저의 질문이 있는지 확인하고, 유저의 답변을 받아서 검색 DB에 저장하는 백엔드를 담당 ### MLflow 배포 파이프라인 구축 *Python, Docker, MLflow, Jenkins* 2021.03 - 2021.04 - ML model 개발 특성상 코드 변경이 거의 없이 파라미터만 바꾸어 서버를 배포해야 하는 상황이 잦기때문에 mlflow 를 도입하고 손쉽게 mlflow 기반의 배포를 할 수 있도록 자동으로 docker image를 생성/빌드 하고 jenkins 를 호출하여 production 으로 배포할 수 있는 파이프라인을 구축 - MLflow 의 코드를 분석하여 production 용으로 쓰기 적절한 Dockerfile 이 생성될 수 있게 하고 jenkins 의 파이프라인 스크립트를 작성 ### OCR API 서버 개편 *Python, Django3* 2021.01 - 2021.02 - 비동기적으로 여러 AI 모델 worker 를 호출하고 전/후처리를 담당하는 서버 - Django3 의 async view 사용 - 두개의 서비스로 작동하던 레거시 OCR 서비스를 하나의 서비스로 통합 - 기존 서비스를 모두 파악하여 side effect 없이 기존 서버를 모두 교체 ### 페이지 검색 기능 개발 2020.11 - 2020.12 *Go, Python, Gin, SQS* - 여러 문제가 포함된 사진을 찍으면 각 문제의 layout 을 인식하여 각 문제의 풀이를 동시에 검색해주는 페이지 검색 기능 개발 - 동료가 개발한 ML 모델을 서빙할 수 있도록 추론 서버를 만들고, 다단 형식의 이미지 레이아웃 처리 기능을 개발하는 등의 전반적인 서버 API 설계 ### 영어 과목 판별 및 영단어 추천 API 개발 2020.10 - 2020.11 *Go, Python, Gin, AWS Lambda* - 비 영어권 국가 유저의 ocr text로 해당 문제가 영어 과목 문제인지 영어과목 문제가 아닌지 추론하고 번역 검색시 영어 지문에서 추천 영단어를 뽑아 같이 제공함으로써 유저의 공부에 도움이 될수 있도록 하는 기능 - 해당 feature 개발이 가능한지의 research 부터 서비스 개발까지 혼자서 개발 ---- #### *[데이터뱅크 2020.2 ~ 2020.6]* ### 토플뱅크 RESTful API 서버 개발 2020.2 - 2020.6 *Python, Django REST framework, MySQL, Redis, JWT* - 토플 모의 시험 기능, 학습강의 시청 기능, 유저 게시판 기능, 추천문제 기능 API 개발 - 꼬여있는 유저 데이터 정규화/마이그레이션 - jwt 기반 custom django auth model 개발 - redis 캐싱 도입 - 자동배포 환경 구축 --- #### *[헤렌 2016.02 ~ 2019.12]* ### 마케팅 서비스 백엔드 및 인프라 개발 2016.2 – 2019.12 *Python, Flask, RabbitMQ, MySQL, Redis, Celery, asyncio, aiohttp* - 하루 평균 약 80만 건의 background 작업 처리 - 유저의 API 요청을 받는 flask 서버, celery worker, 순수한 asyncio 기반의 daemon worker로 구성 - 약 4년간 혼자서 서비스의 모든 백엔드와 인프라 개발 ### 블로그 및 SNS 실시간 스크래핑 서버 개발 2017 - 2019.12 *Python, Sanic, MySQL, Gunicorn, HAProxy, Docker, Frida* - 특정 사용자의 네이버 블로그와 인스타그램의 각종 정보를 수집하기 위해 웹 페이지와 모바일 앱을 분석하여 비공개 API를 활용 - 모바일 앱에 대해서는 SSL Pinning을 해제하고 transparent proxy 서버를 구성하여 https 트래픽을 캡쳐한 것을 바탕으로 각종 암호화된 데이터를 해독하고 런타임 시에 직접 메모리를 dump 하여 무결성 검증 해싱(hmac)에 사용되는 signature key를 추출 - Python coroutine 비동기 기반 HTTP 서버 - 스크래핑 작업에 필요한 쿠키의 session pool을 미리 만들어 두는 방법으로 API 호출 시간을 500~800ms 단축 - 피크시에 약 700 RPS 정도의 트래픽 ### 여러 Public IP를 동시에 binding 가능한 forward proxy 서버 개발 2019.4 - 2019.6 *Go, net/http* - 하나의 Application 에서 동시에 여러 public ip에 binding 하여 각각의 ip 로 client 역할을 수행하는 proxy 서버 - 적은 리소스로 많은 동시성을 요구했기 때문에 go로 개발 - net/http 의 Transport 를 재정의 하여 proxy server 개발 ### TCP Relay Proxy 시스템 개발 2019.10 *Python, ZeroMQ* - 모든 inbound 가 제한된 환경에서 outbound 네트워킹만으로 서버를 열수 있도록 server, client, middleware server 개발 - 서버측에서 socket 의 accept 가 불가능 했기 때문에 별도의 브로커 없이 사용가능한 ZeroMQ의 pubsub 패턴을 이용하여 새로운 클라이언트를 수용하도록함 ### Dalvik VM 에서 실행 가능한 HTTP 서버 개발 2019.9 - 2019.10 *Java, Kotlin, Protocol Buffers* - android 에서 apk 설치 없이 단독으로 실행 가능한 http 서버 - 외부에서 동적으로 Dalvik JNI 바이너리 파일을 받아와 runtime 에서 라이브러리를 import 하고 그 결과를 http response 로 만드는 역할 ### SMTP 메일 서버 개발 2018.9 - 2018.9 *Pyhon, asyncio, MySQL, Redis* - KennethReitz 의 [inbox](https://github.com/billzhong/inbox.py) 라이브러리를 [asyncio 기반으로 재작성](https://github.com/2minchul/inbox3) 한 후에 그 위에 여러가지 비즈니스 로직을 올려서 메일 전송/수신 가능한 SMTP 서버 개발 - DB I/O 작업과 메일 수신 작업을 모두 비동기적으로 처리 ### 사내 admin 서버 개발 2018.7 - 2018.8 *Python, Flask, SQLAlchemy, MySQL, uWSGI, Nginx* - 일반적인 MVC 패턴의 웹 서버 - 사내 여러 서비스의 분산된 어드민 페이지간의 자주 조회되는 루틴을 파악해 이를 한 단계로 바로 조회할 수 있도록 하는 서버를 직접 제안하고 개발하여 CS(고객 만족)팀의 능률과 편의성을 크게 향상 <br/> ## Honors and Awards ### 우리동네 소상공인 공동구매 플랫폼 (AngelHack Seoul 2020) 2020.7 *Python, Django REST framework, drf-yasg, SQLite* - 공동구매 기능의 MVP를 빠르게 구현 - 팀원들에게 API Spec을 공유하기 위해 drf-yasg 를 이용하여 OpenAPI Document 를 작성 ### 슬라이드 퍼즐 게임 (Pycon 2019 스포카 코드 챌린지) 2019.8 *Python, Pygame* [Spoqa Blog](https://spoqa.github.io/2019/08/30/pycon-kr-code-challenge.html) <!-- ![](https://camo.githubusercontent.com/fc499271526fd3491a40a6681627a98194e8a914/68747470733a2f2f692e696d6775722e636f6d2f494a76624d74772e706e67) --> - `CONNECT THE PYTHONISTAS` 이미지를 활용한 슬라이드 퍼즐 게임 - Pygame 이용 - 퍼즐 random shuffle - 상하좌우 충돌 검사 및 교환 알고리즘 ### 통신 및 물리적 재난에 대비한 프라이빗 네트워크 앱 (AngelHack Seoul 2019) 2019.6 *Python, Sanic, SQLite* [Slide](https://docs.google.com/presentation/d/e/2PACX-1vSPpU81e65YPEDAd1WuFZqu4Kdj2z6IUyS6Yx5-DzxucG-BcdG2WBdR2MnmwsWOn0CFMNMV7EAb6EUn/pub?start=false&loop=false) | [Facebook](https://www.facebook.com/AH2020SEOUL/videos/2318161298510922) <!-- ![](https://i.imgur.com/NzT5xN8.jpg) --> - mesh 형태의 private network 환경을 가정한 채팅 및 상태공유 웹앱 - PubSub 패턴의 websocket 서버 개발 ### 남한말 vs 북한말 끝말잇기 (DMZ 해커톤) 2018.11 *Python, Django, MySQL* [Slide](https://docs.google.com/presentation/d/e/2PACX-1vQJF7-LqhMtDr5oXLu5ywOAjQTJ2LHYqmp25JcIqGANeVFCAjA55h2MrWiRjoW8MYMXRQ07GAOQ0C61/pub?start=false&loop=false) <!-- ![](https://i.imgur.com/hploqAP.png) --> - 남한말(player)과 북한말(computer)로 끝말잇기를 할 수 있는 간단한 웹 게임 - 국립국어원 표준국어대사전 스크래핑에 8시간 이상이 소요될 예정이었지만 블로킹 방식의 동기식 코드를 코루틴 비동기 방식으로 교체하여 6분 만에 모든 표제어 수집 - 각 낱말의 초성을 따로 인덱싱 하는 방식으로 computer의 끝말잇기 응답시간을 향상 ### 화장품 관리 앱 (두리톤 2017) 2017.5 *Python, flask, MongoDB* [Slide](https://www.slideshare.net/WonJunSong3/get-it-pouch) | [Video](https://www.youtube.com/watch?v=98aBhp8cB7I) <!-- ![](https://i.imgur.com/mNN1Faq.png) --> - 구매한 화장품의 바코드를 인식하여 내가 가진 화장품을 관리하는 모바일 파우치 앱 - 바코드로 인식한 고유 번호를 받아서 화장품의 정보를 검색하는 API 서버 개발 <br/> ## Hobby ### Titanium 기반 모바일 앱의 API 분석 2020.3 *Java, JS, Frida* - JS 베이스 모바일 앱 개발 프레임워크인 [Titanium](https://www.appcelerator.com/Titanium/) 으로 빌드된 앱에서 사용하고 있는 API 리버싱 - apk 안의 컴파일된 Java bytecode를 읽을 수 있는 수준으로 디컴파일 하고 일부 디컴파일이 불가능한 부분은 bytecode를 직접 해석 - runtime 에서 java 코드를 injection & hooking 하여 AES/CBC PKCS#5 암호화된 js 파일의 암호화키를 추출 한 후 원본 js 파일을 복호화 ### IOT 기기에 사용되는 ESP8266 기반 HTTPS 서버 개발 2020.2 *C++, NodeMCU(ESP8266)* - Wifi에 접속하여 각종 센서들의 값을 서빙하는 https 서버가 내장된 펌웨어 개발에 참여 - https 서버 부분 개발 ### 8\*8\*8 LED Cube 2015.2 *Arduino* [Video](https://drive.google.com/file/d/13-va8TAv71pMH2K0xIr3gRFmoiMSPTR1/view?usp=sharing) <!-- ![](https://i.imgur.com/RX91SBo.jpg) --> - 한정적인 개수의 GPIO 로 16\*8 개의 출력을 제어하기 위해 8bit shift register(74HC595) 로 mux 구현 - 다이나믹 구동방식의 led 제어 ### Youtube Downloader *Python, youtube-dl, Pyinstaller, FFmpeg* 2015.1 - 2015.12 [Blog](https://blog.naver.com/drminchul/220283642245) - 유튜브 동영상 다운로드 및 트랜스코딩 프로그램 - 동영상 페이지를 스크래핑 하여 metadata와 token을 추출한 뒤 일회용 video resource url을 조합 - 후에 youtube-dl 이용 - 1년동안 꾸준히 유지보수 함 <!-- ### 움직임 감지 실내 CCTV *RaspberryPI, Python, OpenCV* 2014. - 움직임이 감지되었을때에만 저장되는 --> <!-- ### 한글시계 2015.4 -->