24년 11월을 돌아보며

Published
November 30, 2024
Last updated
Last updated December 13, 2024
Tistory
Category

Week 44(1028-1101)

241101(Fri)

  • 장고 로그와 CloudWatch 관련 공부
    • 다소 비용이 비싸다는 느낌. S3에 비교하면. 저장용보다는 말그대로 로그에 최적화된 기능. 저장 기간도 1개월이 기본이니
  • mypy 사용해보기
    • 파이썬 객체지향 책을 읽으며 알게 되었는데, 괜찮은 느낌. 몇개의 오류 발생 가능 지점을 발견했음.
  • 크롤링 관련
    • 인증을 요하는 크롤링시 csrf 토큰 처리해보기
      • 장고 앱에서는 헤더의 쿠키 그리고 폼에 csrfmiddlewaretoken를 요구한다.
      • referrer 설정도 필요하다는 말이 있는데, 이건 안해도 가능했음.
  • 기존 추상화된 코드에 대한 고민
    • 인증 코드에서 세션인증/토큰인증등에 따라서 분리하고 재사용이 용이하게 구현을 했었다.
    • 그러나 실제 사용했을 때 세션-csrf-장고폼-인증 이런식으로 실제 인증 문제는 복잡하고 구체화 된 구현이 필요했음.
    • 각각 과정을 나누어 템플릿 메서드 패턴등을 사용해보아도 되겠지만, 억지 추상화라는 느낌이 들었다. 결국 인증도 개별 도메인에 종속된 경우가 많았음.
    • 그래서 차라리 개별 도메인별 ~Auth 클래스를 만들고, 디비에서 single table 전략으로 구성된 테이블에서 나온 객체를 기반으로 팩토리? 패턴으로 ~Auth 객체를 가져올 수 있게 해서 DB와의 연동을 편하게 하자고 생각했다.
    • 기존의 파일 구조도 Auth, Fetcher 등으로 나누었는데, 도메인별로 파일을 분리하기로 수정. 차라리 도메인별로 응집도를 높이는게 좋다고 느껴졌다.

Week45(1104-1110)

241104(Mon)

  • 장고 개발
    • single table 전략을 이용해 복잡한 요구 사항 구현하기
    • 실제 구현과 기존 예상의 괴리가 있어 추상화 줄이기
    • 로깅 설정
      • 로거와 핸들러중 우선 로거에서 로그를 수집
      • 이때 앱 이름이 포함되어야 함. django는 장고 자체 로그들
      • 아니면 loggers 하위에 앱이름 대신 그냥 loggers 레벨에 root라는 이름으로 만들면 전체 적용됨.
      • 로거에 핸들러 이름을 설정에서 이걸 핸들러로 보냄
      • 핸들러는 이걸 받음. 이때 로거와 핸들러 둘다 level설정이 있는데, 높은게 적용. 즉 로거에서 한번 거르고 핸들러에서 한번 거르는 용도임.
      • 핸들러에서는 필터와 포매터 적용 가능
    • 테스트 코드 작성, MagicMock을 써보았다
      • 객체 지향적 코드를 짜야하는건 테스트를 위함이 아닐까… 하는 생각. Spring DI가 이런건 편했는데

241105(Tue)

  • 솔리드 커넥션 웹 개발
    • App Router 전환
    • 일단 먼저 use client 대부분 적용해 react와 다름없는 수준으로 마이그레이션하고
    • 바뀐 useRouter등만 우선 전환해주기
    • 어짜피 인증이 필요한 페이지가 많아 ssr 적용할 곳이 크게 많지는 않음. 급한것도 아니고
    • 우선 빨리 전환하고 네이밍도 바꾸고 리팩토링하는게 우선으로 보임
  • 장고 개발
    • difflib.SequenceMatcher, get_close_matches를 사용해 이름 오타시에도 자연스럽게 진행되게 하는 기능 추가
    • ruff 린터 사용해보기
    • mptt라는 모델 트리구조 라이브러리를 알게 됨
    • 어드민 페이지 검색 필드등 커스터마이징 할 수 있는 것을 알게 됨

241106(Wed)

  • 솔리드 커넥션 웹 개발
    • 메인 화면 App Router 전환
    • 폰트 최적화

241107(Thu)

  • 솔리드 커넥션 웹 개발
    • App router 이전 작업
    • Lint 오류 수정

241108(Fri)

  • 장고 기존 코드 수정 작업
    • 문제: dbeaver로 데이터 덤프딸때 초기 부분과 insert 부분 sql이 잘리는 문제
      • dbeaver 실행 명령어 그대로 실행했을 때는 괜찮은거보니 dbeaver 버그인듯. 메모리 문제일지도
    • 문제: 장고 db_comment해도 특정 필드는 적용이 안되는 문제
      • 안되는 필드는 그냥 DB에 직접 적용해주는걸로…
    • 이전 버전과 신규 버전 동일 api 동일 response 체크
      • 대부분 수작업으로 했는데, 자동화 될듯. 이미 솔루션도 많을지도

241109(Sat)

  • 솔리드 커넥션 서버 DB 이전

241110(Sun)

Week46(1111-1117)

241111(Mon)

  • 인턴십: 내부망에 DB 마이그레이션, 서버 코드 변경 작업

241112(Tue)

241113(Wed)

  • 솔리드 커넥션 서버 인증서 갱신
    • standalone 방식은 nginx 관련 문제인지 안되서 dns 레코드 변경 방식으로 성공
  • 인턴십: nginx 리버시 프록시 이용해 한 서버에서 프론트/백엔드 동시 배포 작업
    • 그냥 내부 포트 8001번으로 열고 8000에서 프록시

241114(Thu)

  • ACC Inha 발표: 메시지 큐와 SQS

241115(Fri)

  • 인턴십: 데이터 수집 celery task, command 작성 작업

241116(Sat)

241117(Sun)

Week47(1118-1124)

241118(Mon)

  • 인턴십: api 개발, 테스트코드 작성
    • selector 레이어 사용, 중복 쿼리 일부 통합해서 최적화
    • 일단 1차 배포~

241120(Wed)

  • 인턴십
    • swagger 오류 수정 → 요청하는 url의 포트 문제. 임의 지정해줌
    • sql 쿼리 최적화
    • 프론트엔드 api endpoint 연결작업

241121(Thu)

  • 솔리드 커넥션 웹 개발
    • 버그 해결. 빌드가 vercel에서만 안되는 문제
    • tab.tsx → Tab.tsx로 이름 변경했는데 git에서 못잡아서 반영이 안됨. 그리고 import만 바뀌어서 모듈을 못찾는 문제였음
    • 이를 해결하기 위해 git config core.ignorecase false
  • JS 병렬 fetch
    • Promise.allSettled()
      • Promise.all()는 요청중 하나라도 오류가 발생하면 모두 오류가 발생한다
      • 즉 서로 연관된 작업을 수행하기에 좋음
      • Promise.allSettled()는 서로의 성공여부에 관계 없이 비동기 작업을 수행한다
 
  • 스프링 빈 스코프
    • 스코프: 빈이 존재할 수 있는 범위
    • 종류
      • 싱글톤: 스프링 컨테이너의 시작 ~ 끝 까지
      • 프로토타입: 스프링 컨테이너는 생성, DI만 해주고 더이상 관리 x
        • 즉 이후 관리 책임이 없어 @PreDestroy 호출되지 않음
      • 웹 관련 request, session, application(웹의 서블릿 컨텍스트와 같은 범위)등
        • 활용법: 로거등에 사용해서 웹 요청 시작 ~ 끝을 명확히 보이는데 사용 가능
    • 사용법: 빈 클래스 위에 @Scope(”prototype”) 로 자동 스캔
  • 싱글톤 빈 안의 프로토타입 빈
    • 싱글톤 빈 내에서 프로토타입 빈을 사용할때 해당 빈은 싱글톤 빈이 주입받을 때 생성된 것으로, 매번 다시 생성되지 않는다. 이에 주의
    • 그렇다면 매번 새롭게 생성하려면 어떻게 해야할까?
      • ApplicationContext ac, ac.getBean()을 사용하면 프로토타입 빈은 매번 새로 생성됨
      • 이렇게 DI를 받는게 아닌 직접 찾는걸 DL(Dependency Lookup)이라고 함
      • 문제는 이러면 스프링 컨테이너에 종속적인 코드가 된다
    • 그래서 다음 기술을 사용할 수도 있음
      • ObjectProvider<PrototypeBean> prototypeBeanProvider
      • prototypeBeanProvider.getObject()
      • 이것도 스프링에 의존적
    • 아니면 javax.inject.Provider 라는 자바 표준을 사용할 수도 있다
    • 느낀점: 이걸 쓸일이 과연 있을까? 억지로 mq를 써보는 느낌
  • 스프링 프록시
     
     
     
    • Inha ACC 발표 듣기
      • Serverless
      • CI/CD 핸즈온
     
    • 인턴십
      • 프론트엔드 api 연결 작업
      • same-site same-origin cors csrf 이것저것 많은 고민
      • 코드 리팩토링, 테스트 작성

    241122(Fri)

    • Postman alternative
      • Postman
        • brew monthly 11.3k downloaded
      • Insomnia
        • brew monthly 2.2k downloaded
        • Pricing
          • Hobby: Unlimited collaborators for 1 project
          • Pro(12$/M)
      • Hoppscotch
        • 브라우저에서 사용 가능
        • brew monthly 0.3k downloaded
      • soapUI
        • brew monthly 0.2k downloaded
    • 인턴십
      • cors, csrf 관련 문제 모두 해결. 할 수 있는것과 불가능것을 완전히 이해했다.
      • ImageField에 image.url 줘서 안되는 문제 수정… image를 줘야한다
      • react 로그인 상태에 따른 서비스 진입/로그인 화면 분기 처리
    • Influx DB 공부

    241123(Sat)

    241124(Sun)

    Week48(1118-1124)

    241125(Mon)

    • Celery 실패한 task 재시도 방법 고민
      • 동적 배열 크기 증가할때 2배씩 증가하는게 가장 효율적이라는 걸 본 기억으로 2배씩 증가할까 고민
      • 찾아본 결과 이를 Exponential Backoff 라 하고, Celery 5부터 아에 쉽게 사용할 수 있도록 지원한다는 것을 알게됨
      • 그리고 Jitter에 대해서도 알게 되었다. 이것도 한번에 open api서버에 요청할때 밴될까봐 고민했던 사항인데 AWS 블로그를 보고 효율적인 jitter 전략등을 알게 되었다.
      • 아무튼 구현하려 보니 task가 date 의존적이라 인자를 첫번째 시도의 것을 계속 가져가야 해서 Celery에서 편하게 사용할 수 있게 해둔것은 못쓰고, 자체 구현해서 사용했다.
      • Celery에서의 Exponential Backoff and Jitter 글 작성 시작
    • 장고 블루 그린 무중단 배포 구현
      • 겪은 많은 오류들… 대부분 gpt에 대한 과한 신뢰에서 나왔다
      • The workflow is not valid. .github/workflows/cd-prod.yml (Line: 79, Col: 13): A mapping was not expected
        • # ssh-action에서 ENV 지정을 다음 처럼해서 발생 - name: Deploy via SSH uses: appleboy/ssh-action@v0.1.5 with: env: REGISTRY: ${{ needs.build-and-push.outputs.REGISTRY }} REPOSITORY: ${{ secrets.ECR_REPOSITORY }} AWS_REGION: ${{ vars.AWS_REGION }} IMAGE_TAG: ${{ github.sha }} # 다른 방법이 있는진 몰라도, 공식문서상으론 다음처럼 예시가 되어있다 - name: Deploy via SSH uses: appleboy/ssh-action@v0.1.5 env: REGISTRY: ${{ needs.build-and-push.outputs.REGISTRY }} REPOSITORY: ${{ secrets.ECR_REPOSITORY }} AWS_REGION: ${{ vars.AWS_REGION }} IMAGE_TAG: ${{ github.sha }} with: envs: REGISTRY, REPOSITORY, AWS_REGION, IMAGE_TAG
      • scp 전송중 tar: empty archive
        • source: | ./docker-compose.yml ./deploy/nginx.conf.template ./deploy/deploy.sh
        • 위처럼 다중 source를 설정해서 발생한 문제. 원래 가능한 방식인지는 몰라도 안되서 모두 /deploy 폴더에 넣고 폴더채로 보냈다
      • error copy file to dest: ***, error message: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
        • gpt가 계속 scp-action@v0.1.1을 고집했는데 v0.1.7로 바꿔주니 해결됨. latest stable 버전을 쓰자고 고집하더니… o1-preview라 믿었는데 그냥 최신 정보 업데이트가 안된건지…
      • err: bash: line 6: ./deploy.sh: Permission denied
        • chmod +x 추가해줬다
      • deploy.sh 실행중 문제
        • err: Unable to locate credentials. You can configure credentials by running "aws configure". err: Error: Cannot perform an interactive login from a non TTY device
        • .env에 추가해주고 expose로 환경변수로 설정해줌
      • 아무튼 아무튼 배포 성공!

    241126(Tue)

    • 엑셀 파싱 코드 작성중, 오류가 발생
      • 엑셀파일 raw로 열어보니 오히려 html의 구조를 가진것을 보고 pandas read_html로 해결했다
    • S3를 안쓰고 파일 저장, 인가에 대한 고민
      • 장고에서 파일을 저장하고 다운로드 가능하게 해야하는데, S3는 못쓰고 nginx등으로 직접 서빙해야한다
      • s3에서는 잠깐만 접속 가능한 링크를 발급하는 방식이 있는걸로 아는데
      • 일단 찾아보니 nginx에 헤더를 바탕으로 인증 처리할 수 있는게 있다고 한다
      • 다만 생각해보니 인가가 필요하긴 하나 매우매우 엄격해야 하는 것은 아니고, url을 복잡하게 하는것 만으로 보안을 어느정도 지킬 수 있다고 생각이 되었다
      • 굳이 따지면 s3에서 임시 링크등을 발급받아도 잠깐동안은 누구나 접근 가능하지만, url을 쉽게 추측할 수 없는게 핵심이니깐
      • 그래서 uuid를 이용해서 해결 했다
        • uuid 버전은 목적상 완전 랜덤이 맞다고 보아 uuid4로 적용. timestamp등은 오히려 노출되면 안된다고 보았다.

    241127(Wed)

    • 엑셀 → fastapi → influxdb로 시계열 데이터 저장하는 것 구현
      • influxdb flux의 사용은 다소 어려웠다. 일반 field와 key의 차이를 크게 느꼈다
      • influxdb는 그래도 자체 대시보드가 있어서 좋은듯

    241128(Thu)

    • googlemaps/google-maps-services-python 를 참고하여 라이브러리를 만들어 보기로 했다
    • 데이터 보정 코드 구현하며 pandas의 melt()를 알게되었는데 신기한 느낌. 이런 데이터 라이브러리에는 자동으로 중간에 비어있는 값을 넣어주는 그런 함수도 있다는데 재밌는 것 같다.

    241129(Fri)

    • 일본 리전 rds가 접속이 안되는 문제
      • 문제상황을 듣고 대충 VPC나 WAF문제가 아닐까 생각
      • 일단 회사 네트워크 문제일 수 있으니(학교에서는 MySQL 포트가 막혀있는 경우가 있었다. 일본 IP가 막혀있거나 일본쪽에서 막고 있을 가능성도) 직접 파서 확인. 이상이 없었다
        • 특이점으로는 한국 rds는 핑 200ms대인데 일본은 1600ms로 확실히 차이가 났다
        • 커넥션 뚫는거라 느린 것 일수도? 커넥션 뚫어둔 후 일반 DB 쿼리는 이것보단 빠를거라 생각한다
      • 일단 계획으로는 VPC Flow Logs로 로그를 확인하거나
      • 정 안되면 EC2에서는 연결 되니 mysql_fdw 등으로 프록시를 만드는 것
      • 문제 해결을 위해 실제로 해보니 그냥 됐다… 뭔가 설정 문제가 있었던걸지도… 약간 허무한 결말

    241130(Sat)

    241201(Sun)