spring
[우아한 테크 캠프 팀 프로젝트] 파일 이동 및 삭제 My-Storage(3)
다음은 파일 이동과 삭제에 대한 내용이다. 데이터 무결성에 과하게 집중했는데, 시간이 지나서 문제가 될 수 있음을 깨달았다. 당시에는 도메인 지식이 부족해서 더 폭넓게 생각하지 못한 것 같아 아쉬움이 있는 부분이다. 당시 구현할 때, 파일 이동과 삭제에 있어서 중요한 것은 폴더의 하위 파일 및 폴더들이 동시에 이동하고 삭제되어야 한다는 부분에 집중했다. 현재 DB 상에 구현된 파일 트리 구조는 pk를 기반으로 parent를 찾아가기 때문에 이동의 경우 해당 파일이나 폴더의 Parent ID 값만 바꿔주면 됐다. 삭제의 경우 하위 파일들을 모두 찾아서 한 번에 삭제해야 했다. 이때 락을 걸지 않으면, 삭제 중인 폴더에 어떤 파일을 추가할 수 있고, 타이밍이 맞지 않아서 새로 추가된 파일은 삭제되지 않는 문..
[우아한 테크 캠프 팀 프로젝트] File Upload 구현하기. 효율적인 I/O처리를 위한 InputStream과 OutputStream의 분리 My-Storage(1)
우아한 테크 캠프에서 3주 동안 진행하는 팀 프로젝트를 시작하게 되었다. 3주라는 짧은 시간 안에 아이디어를 내고 기능 구현도 하고 발표까지 해야 했다. 팀은 제비 뽑기로 결정했다. 제비 뽑기로 할 줄은 생각도 안 해서 나처럼 CS 공부가 중요하다고 생각하는 분과 팀을 하기로 했었고, 어떤 주제를 할지 미리 정했었다. 조작한 것처럼 제비 뽑기에서 그 분과 한 팀이 되었고 다른 팀원들에게 해당 주제와 대략적인 기능들을 설명해 주었는데 긍정적인 반응이라서 시작하게 되었다.주제와 주제 선택 이유주제는 네이버의 MyBOX, 구글의 Google Drive와 같은 클라우드 스토리지 서비스이다.이 주제를 선택한 이유는 클라우드 스토리지도 일종의 파일 시스템이고, 그렇다면 CS를 많이 활용할 수 있지 않을까?라는 생각..
Github Action CommunicationsException: Communications link failure, profile 설정과 @SpringBootTest 동작 방식 이해로 해결하기 - MiniPay(2)
문제 로컬 환경에서 테스트하고 빌드까지 잘 되는 것을 확인했지만, github action을 사용한 build에서 데이터베이스와 연결이 안 된다는 에러가 발생했다. 해결 과정 1. Github Actino에서 MySQL을 사용하기 Github Action 환경이 어떻게 되어 있는지 간단하게 살펴 보았다. 이벤트를 발생시키면 Runner에서 동작하는 원리였는데 얘가 컨테이너 내부에서 작업을 실행한다. 해당 컨테이너 환경에 MySQL이 없어서 발생하는 에러였고, MySQL을 사용할 수 있는 설정을 포함해서 해결할 수는 있었다. 하지만 그러면 전체 작업 수행 시간이 늘어나는 문제가 있어서 다른 방법을 고민해 보았다. 만약 이 방법을 사용할 것이라면 아래처럼 작업을 추가해 주면 된다 services: mysql..
프로젝트 설계, 이체 시 동시성과 DB Isolation Level 고민 및 적용 - MiniPay(1)
프로젝트 소개 최근 좋은 기회를 얻어서 작은 스터디를 시작하게 됐다. 스터디 운영하시는 분께서 너무 감사하게도 평소 프로젝트를 할 땐 신경 쓰지 않았던 부분들을 고민할 수 있는 주제로 프로젝트 아이디어를 제공해 주셨다.(동시성 문제, 성능 문제 등) 최근 CS의 중요성을 깨닫고 이걸 프로젝트에 어떻게 적용할지 고민이 많았는데 제공해준 프로젝트를 진행하면서 이런 고민을 해결할 수 있었다. 4개의 주제 중 페이 서비스를 만드는 것이 마음에 들었다. 평소 CRUD만 했던 DB를 Isolation Level과 락을 어떻게 걸지 고민하며 적용해 보는 것이 좋은 경험이 될 것이라고 생각했다. 또한 트랜잭션을 학습할 때 항상 이체를 예시로 들었는데 공부할 땐 예시만 보고 그렇구나~ 했던 것을 어떻게 해결할 것인지 고..
[리팩토링 3] 쿼리 수정 및 최적화와 JMeter를 사용한 비교-게시판 만들기(16)
쿼리 수정 기존에는 QueryDSL을 사용하며 DTO조회를 사용하고 있다. 이를 최대한 Entity객체를 반환하도록 수정할 것이다. 그리고 만약 수정이 힘들더라도 QueryDSL에서 조회하는 DTO와 Service단에서 응답을 위해 사용하는 DTO는 구분하여 처리할 것이다. 의존 관계를 떨어뜨리기 위함이다! 게시글 상세 정보 조회의 쿼리를 최적화하면서 내가 수정한 방법이 정말 최적화가 됐는지 테스트를 해보고 어떤 것이 더 괜찮은지 고민해 볼 것이다. QueryDSL DTO조회를 Entity조회로 바꾸기 우선 내가 이렇게 조회 방식을 바꾸는 이유는 재사용성을 높일 수 있기 때문이다. 만약 같은 게시글 조회 쿼리라도 화면에서 보여줄 내용이 다르다면 DTO조회의 경우 새로운 DTO를 사용한 메서드를 만들어야 ..
[리팩토링 1] nGrinder삽질 + JMeter 부하 테스트 해보기 - 게시판 만들기(14)
로그인 기능 이후 게시글과 댓글 기능까지 만들었다. 리팩토링 하기 전에 부하 테스트를 해보고 성능에 문제가 있는 것을 한 번에 리팩토링하면 좋을 것 같아 시도해 보았다. nGrinder 삽질 아래는 nGrinder 오픈소스 링크이다. 여기서 알맞은 버전을 다운로드하여 사용해야 한다. https://github.com/naver/ngrinder/releases 내가 그냥 최신버전 했다가 삽질을 엄청 했는데 현재 내 환경은 macOS Ventura 13.4.1 java openjdk8 을 사용했다. openjdk8을 사용한 이유는 8 버전이 가장 잘 된다고 한다. 11도 되는 것 같지만 시도해보지 않았다. 우선 이 환경에서 nGrinder 3.5.8 버전이 되지 않아서 3.5.6 버전을 다운로드하여서 실행하..
Spring Security + JWT 적용하기(3) - 게시판 만들기(12)
로그인 구현 마지막 기능으로 로그아웃과 내 개인적인 보안 강화?를 적용해 보겠다. 우선 내 로그인 로직은 클라이언트가 로그인을 한다. 로그인 성공하면 accessToken, refreshToken을 건네준다. accessToken이 만료되면 로그인 유지를 위해 refreshToken으로 재발급 요청을 보낸다. refreshToken이 유효하면 accessToken을 발급한다. refreshToken이 유효하지 않다면 토큰을 만료시키고 강제 로그아웃 처리를 한다. 크게 이런 흐름이다. 내가 생각한 나름의 보안 강화는 4번에 적용시켰고, refreshToken이 유효해도 accessToken이 유효하지 않다면 비정상적인 접근으로 판단하여 강제 로그아웃 처리를 하였다. 이후 해당 accessToken은 따로 ..
Spring Security + JWT 적용하기(2) - 게시판 만들기(11)
Spring Security에 JWT를 붙이기 전에 JWT를 먼저 발급해 보겠다. 로그인 시 JWT 발급하기 먼저 JWT에 대한 작업을 할 클래스를 하나 생성한다. Security와 같은 모듈에서 utils 패키지를 만들어 관리를 할 것이다. 그러기 전에 먼저 의존성을 추가해 준다. build.gradle (common-authentication 모듈) dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' //Spring Security implementation 'io.jsonwebtoken:jjwt:0.9.1' } jjwt 가 java json web. token이라고 한다. utils/JwtUtil ..