24년 10월을 돌아보며

Category
Published
October 31, 2024
Last updated
Last updated November 3, 2024
Tags

Week 40(0930-1006)

241001(Wed)

  • 공부
    • React Suspense, Lazy

241002(Thu)

    241003(Fri)

    241005(Sat)

    • 솔리드 커넥션 웹 개발
      • App Router 전환중

    241006(Sun)

    Week 41(1007-1013)

    241007(Mon)

    • 솔리드 커넥션
      • 데이터 추가
      • 서버 배포, 오류 해결
    • DRF 테스트 코드에서 json 리턴에서 나올 수 없는 decimal 타입이 나오는 것을 확인
      • DRF 테스트에서 res.data는 완전 외부 테스트 느낌이 아닌 어느정도 의존성이 있다는 것을 확인
      • 그나마 줄이려면 res.content를 직접 json 변환해도 될듯
      • 아니면 request 기반의 APIClient도 있는 것 같다
    • 그리고 204 status code일때 body를 검증해주지 못하는 문제?
      • 이것은 원래 204일때는 body를 포함한것을 상정하지 않아서 그런듯. HTTP 표준은 아니지만… GET 요청에 body 없는것도 표준은 아니니
      • 이걸 해결하려면 res.data로 response body를 직접 다시 검증해줘야 하는것이 일단 대안
    • 장고 프록시 모델과 django-lifecycle 관련 강의 수강

    241008(Tue)

    • 솔리드 커넥션 기능 수정 DB 고안
    • FastAPI 학습
    • 세션 관련 학습
    • ERD 그려보며 DB 설계

    241009(Wed)

    • 솔리드 커넥션 웹 개발

    241010(Thu)

    • 솔리드 커넥션 웹 개발
      • 기존 공통 컴포넌트 리팩토링
    • 미식록 서버 개발
      • 데이터 수정

    241011(Fri)

    • FastAPI 학습
    • mqtt 학습
      • QoS
      • Clean session
    • Gmap Tiles API 관련 코드 리팩토링

    241012(Sat)

    • Topcit 시험
      • 복기
        • SQL 권한 주기 GRANT TO 회수는 REVOKE FROM
        • VARCHAR2: 오라클에서 쓰는 개선판 VARCHAR
        • 테이블 필드 추가: alter table 테이블 add 컬럼 varchar(100) not null

    241013(Sun)

    Week 42(1014-1020)

    241014(Mon)

    • Gmap Tiles 를 이용한 지도 생성

    241015(Tue)

    • react-router-dom
      • <RouterProvider />, createBrowserRouter()
        • path, element, errorElement
      • <Outlet />
      • <Link />
      • dynamic segment
    • styled-component

    241016(Wed)

    • MySQL 트랜잭션 격리수준
      • READ UNCOMMITED
        • 커밋되지 않은 값도 읽을 수 있음
        • Dirty read: 트랜잭션이 완료되지 않아도 다른 트랜잭션에서 확인할 수 있는 현상
        • 즉 롤백했는데 유효한 데이터라 착각 할 수 있다
      • READ COMMITED(대부분 기본 트랜잭션 격리 레벨)
        • 커밋전에는 Undo table의 값을 읽어오기에 커밋이 완료된 값만 읽을 수 있음
        • Non repeatable read: 같은 트랜잭션 내에서 값을 두번 읽을 때 서로 다른 값이 들어올 수 있다
      • REPEATABLE READ(기본 트랜잭션 격리 레벨?)
        • MySQL에서는 트랜잭션이 생성된 순서로 번호를 부여한다
        • 이런 동일한 레코드에 대해 여러 버전이 존재하는 관리 방식을 MVCC(Multi Version Concurrency Control)이라 한다.
      • SERIALIZABLE
        • SELECT FOR SHARE/UPDATE가 아닌 순수한 SELECT(Non-locking consistent read) 작업시에도 공유락(다른 트랜잭션에서 읽기 가능, 수정 불가능)을 설정한다
        • 그렇기에 가장 안전하지만, 가장 성능이 떨어진다.
    • 미식록 서버 버그 수정
      • 데이터 양이 늘어남에 따라 어드민 페이지에서 로딩이 느려지는 문제
      • 다만, SQL자체는 빨리 끝나나 CPU time이 매우 높게 잡힘
      • 관련된 리소스 전체 목록을 보여주는게 아닌, raw_id_fields를 적용하여 해결
        • 3000ms → 200ms
    • 엑셀 → 파이썬 변환
      • openpyxl 보다는 pandas를 바로 쓰는게 편한듯
    • 장고 프로젝트 DB 설계

    241017(Thu)

    • 장고 커스텀 유저 모델 설계
    • API 개발

    241018(Fri)

    • svg 구조 학습
    • API 개발
      • 개발하며 느낀점. 서비스 로직이 있는게 아닌 조회라면, 조금 복잡한 조회라도 최대한 DRF generics를 쓰는게 좋은듯
      • serializerMethodField를 쓰더라도 차라리 로직을 그쪽에 넣어두는게 좋은 느낌
      • 좀 복잡하더라도 related 된걸 좀 가져오거나, 어느정도 계산을 할 뿐이니

    241019(Sat)

    241020(Sun)

    • 미식록 데이터 추가

    Week 43(1021-1027)

    241021(Mon)

    • 장고 개발
      • 깔끔한 조회 api 코드 작성하기
    • svg로 지도에 마커 추가, 마커 클러스터링
      • 클러스터링: 주변 마커 탐색 알고리즘과, 좌표 기반 방식으로

    241022(Tue)

    • 장고 개발
      • test 코드에서 unittest.mock patch 사용해보기
      • 파이썬 린팅 관련
        • isort 추가, black formatter 규칙 추가
      • swagger 적용
      • 장고 모델 제약조건 관련 학습
        • 4가지의 검증 단계가 있고 full_clean()으로 모두 실행 가능
        • 이중 모델 Meta에 추가한 constraint만 DB 제약으로 들어가고 나머지는 모두 Django 어플리케이션단 검증
      • 모델 설계

    241023(Wed)

    • 장고 개발
      • API 개발, Subquery, OuterRef와 annotate를 이용해 n+1 문제 방지
      • 장고 고급 쿼리문 작성 관련 학습
        • 신기했던 점: 이런 Q, F, Sum, Subquery등 어떻게 구현했는지 신기했던 것을 내부적으로 보니 각 객체에 정의된 template의 규칙에 따라 그냥 작동하고 있었 다는 것

    241024(Thu)

    • 미식록 서버 개발
      • 프랜차이즈 추가, 프랜차이즈 메뉴 - 식당 메뉴 연결
    • 장고 개발
      • API 파싱/데이터 크롤링 코드 작성
      • 다양한 서비스에 대응 가능하게 추상적으로 작성
        • 인터페이스, 인증에서는 전략 패턴을 사용해서 재활용이 용이하게 작성
        • 응집도를 고려한 설계
      • 정해진 API 파싱 코드 작성
        • 변경이 적은 API에 미래에도 사용할 수 있게, TypeDict를 이용해 반환값 정리
        • API 공통 부분을 통합하여 사용하게 쉽게 하고, 빌더 패턴? cascading을 이용해 쉽게 API 사용/확인이 가능하게 코드 작성
      • 모델 수정
    • CSRF 체감상 50번째 재학습
      • CSRF는 확실히 Cookie의 Samesite와 관련이 많다고 느껴짐

    241025(Fri)

    • Celery 학습

    241026(Sat)

    241027(Sun)

    Week 44(1028-1101)

    241028(Mon)

    • Workflow 개발을 위한 공부와 고민
      • Airflow 살펴보기
        • 사용하지 않더라도 DAG 구조는 응용해서 무한 반복 문제등을 방지할 수 있을 듯
      • Celery 사용해보기

    241029(Tue)

    • 솔리드 커넥션 웹 개발
      • 스피너 개발
    • django-celery-results 사용
      • Celery 결과 저장을 위해 Django 백엔드를 사용하게 도와주는 라이브러리
    • django-celery-beat 사용
      • 일정 주기 또는 cron으로 태스크를 실행해주는 것을 도와주는 라이브러리
      • 재밌었던 건 일출 같은것도 조건으로 걸 수 있었다는 것.
    • Django 로그 기록법 공부
      • 일자별 로그 파일에 기록 방법
      • AWS CloudWatch를 사용할 수도 있다는 것을 알다
        • 비용적으로 보았을때 단기적으로 저장하고 alert등이 필요한 중요 로그는 CloudWatch를 사용해도, 오래 저장할 중요도 낮은 로그는 S3등에 보존하는 것이 괜찮을지도.
        • Django 로그의 ERROR - WARNING - INFO 등급등을 활용하는 방식으로
      • 다만 Celery는 별도 프로세스라 장고 logger를 이용해도 기록되지 않는 것을 확인. 별도의 로깅 설정이 필요할듯
    • nested many 필드가 있을때 수정 API 엔드포인트 구현에 대한 고민
      • /groups/21/users/32 같은 느낌으로 세부 내역에 대한 수정/삭제를 해도 될듯
      • 삭제를 할때 번호가 줄어들어 이후 요청에 문제가 생길 수 있는 것을 주의 해야할 듯(API 사용측에서)
      • 또한 순서 변경이라면 이 방식은 사용하기 어려움
      • json patch라는 json 수정을 위한 표준을 알게됨.
    • celery task 결과에 한글 유니코드 인코딩이 적용되지 않는 문제
      • 오류라고 생각했는데, 잘 검토해보니 애초에 인코딩이 적용될 이유가 없었음.
      • 왜냐하면 json형식의 결과라 일단 눈으로 읽을 수는 있는데, 이걸 잘 읽을 수 있게 보장할 필요는 사실 없음. 이건 알아서 인코딩해서 읽어야할 문제니깐.
      • 즉 json 형식이 아닌 pickle 등의 형식으로 serialzie 하면 애초에 읽을 수도 없는데, json이라서 그나마 영어는 제대로 볼 수 있는 것에 감사해야한다는 느낌?
      • 즉 읽어야 한다면 그때그때 json.load()로 처리해서 읽자.

    241030(Wed)

    • 파이썬 test coverage 라이브러리인 coverage를 알고 사용해봄
      • 그닥 유용하지 않다 느껴져 도입은 안할 듯
    • single table strategy에 대해 알아보고 적용할지 고민

    241031(Thu)

    • 스프링 빈 생명주기 학습
      • InitializingBean, DisposableBean 인터페이스
        • afterPropertiesSet(), destroy() 를 오버라이드 해서 사용
        • 스프링 전용 인터페이스에 의존, 코드를 변경할 수 없는 외부 라이브러리에 적용하기 힘듦
      • 빈에 초기화, 소멸 메서드 지정
        • @Bean(initMethod = "init", destroyMethod = "close") 과 같은 방식
        • 메서드 이름 자유롭게 지정 가능, 스프링 코드에 의존하지 않음, 외부 라이브러리에도 적용 가능
        • 또한 destroyMethod 에는 추론 기능이 있어 자동으로 close()shutdown()이라는 이름의 메서드를 자동으로 찾는다. 싫다면 destoryMethod="" 로 지정
      • @PostConstruct, @PreDestroy 어노테이션 사용(권장)
        • 그냥 메서드 위에 붙여주면 되서 편리
        • 스프링에 종속적이지 않은 자바 표준 기술임 javax.annotation.PostConstruct
        • 외부 라이브러리에 적용하기는 힘듦
    • 빈 스코프 학습
    • ACC Inha 세션
      • 캐시와 Redis
    • Celery cron job(beat) 실험
      • 동시에 많이 실행되더라도 task 실행에 0.12~0.2초밖에 걸리지 않음. 이것도 대부분 네트워크와 DB단의 병목일 것
      • 문제가 될 수 있는 점은 외부 API서버에서 시간 간격당 API 요청횟수 제한을 걸어둔다면 문제가 될 수도. 이를 위해 오류 발생시에도 자동 복구를 할 수 있는 구조를 설계하는 것이 중요.
    • 비밀번호 평문 저장에 대한 조사
      • 모든 비밀번호를 환경변수에 저장할 수는 없으니, 디비에 저장한다면 양방향 암호화-복호화 가능한 키를 사용하고 해당 키만 환경변수에 저장하는 것이 좋을 듯