개발
-
[수정 예정] (OCP)개방 폐쇄 원칙 위배를 극복한 전략 패턴 적용 사례개발/Spring Boot 2024. 7. 12. 14:39
public interface PhotoProvider { String crawlingImageURL(String page_url); byte[] getImageBytes(String image_url); String getHostname();}public abstract class AbstractPhotoProvider implements PhotoProvider { @Override public byte[] getImageBytes(String image_url) { return ConnectionAction.getImage(getHostname(), image_url); }}@Componentpublic class HaruFilm extends Abstr..
-
[수정 예정] 사진을 더 안전하게 저장하기 - AES 알고리즘 적용개발/Spring Boot 2024. 5. 27. 10:35
암호화를 하게 된 배경우리 서버 애플리케이션이 동아리 공용 서버에서 작동하게 될 예정이다. 동아리 공용 서버는 여러 동아리원들이 공유하는 서버로 다양한 사용자와 관리자들이 접근할 수 있다. 이러한 환경에서는 여러 사람이 서버에 접근할 수 있어, 보안에 취약할 가능성이 높다.특히, 서버의 파일 시스템은 여러 프로젝트의 파일을 저장하고 관리하기 때문에 제3자가 파일에 접근할 위험이 존재한다.이와 같은 이유로, 중요한 사용자 데이터인 사진 파일을 보호하기 위해서는 암호화가 필수적이라고 판단했다. 암호화를 통해 파일을 안전하게 보호하면, 설령 제3자가 서버에 접근하더라도 암호화된 파일을 해독하지 못해 데이터의 기밀성을 유지할 수 있을 것이라 생각했다.AES 알고리즘이란?AES(Advanced Encryption..
-
Redis Cache를 통해 이미지 조회 성능 개선하기개발/Spring Boot 2024. 5. 24. 23:52
기존의 이미지 조회 방식에서는 DB에 직접 접근하여 이미지를 가져오는 방식이었다. 우리 서버는 이미지를 조회할 때 항상 Snappy를 통해 압축 해제를 해야 했는데, Snappy의 성능이 아무리 좋아도 항상 일정한 오버헤드를 가진다는 문제가 있었다. 이로 인해 일반 DB 조회보다 더 많은 리소스를 소모하게 되어 성능 저하가 발생했다. 이러한 문제를 해결하기 위해 Image Cache를 구현해야 했다. 캐시를 통해 빈번하게 조회되는 이미지를 메모리에 저장하면, 데이터베이스에 직접 접근하는 빈도를 줄 일 수 있어 조회 성능이 크게 향상될 수 있다. 특히, Redis는 인 메모리 데이터 저장소로 매우 빠른 조회 속도를 제공하여 이미지 조회 성능을 극대화시킬 수 있다. Redis를 이용하여 Image Cache..
-
이미지 압축, 해제 성능 개선하기 - Snappy 도입을 통하여개발/Spring Boot 2024. 5. 24. 17:10
nGrinder를 사용하여 이미지 로드 API를 테스트하는 동안 서버가 다운되는 문제가 발생했다.초기에는 서버가 정상적으로 응답했지만, 가상 사용자가 점차 증가하면서 서버의 응답 속도가 느려지기 시작했다. 결국 사용자가 일정 수를 넘어서자 서버가 더 이상 요청에 응답하지 않고 다운되었다. 서버 로그를 확인해 보니 이미지 로드 API를 호출하는 중 문제가 발생하는 것을 확인할 수 있었고, 문제의 원인이 ImageUtil 클래스 내의 decompressImage 메서드를 호출하면서 발생함을 알게 되었다. 문제를 찾기 위해서는 먼저, 원래 서버에서 이미지 압축과 해제가 어떻게 이루어졌는지 다시 확인하는 과정이 필요하다. 서버에서는 Deflater와 Inflater를 사용하여 이미지 압축 및 해제를 수행한다. ..
-
유지보수가 용이하도록 아키텍처 구성하기개발/Spring Boot 2024. 5. 24. 10:35
여러 게시판을 만들어야 하는 프로젝트를 진행하면서, 유지보수가 용이한 구성에 대해 고민하게 되었다.여러 게시판을 효과적으로 관리하고 향후 발생할 수 있는 문제들을 최소화하기 위해어떤 방법을 사용했는지 블로그에 공유하겠다.모든 게시판 엔티티의 공통 부모 클래스인 추상 Board 클래스를 정의하여, 모든 Board Entity가 이 추상클래스를 상속받도록 했다. Board를 굳이 추상 클래스로 정의한 이유는 Board 자체를 인스턴스화할 수 없도록 하기 위해서이다. Board들을 위와 같이 구성함으로써 제네릭을 사용해 Repository 코드를 아래와 같이 단순화할 수 있었다.public interface BoardRepository extends JpaRepository {} BoardService에서 ..
-
아키텍처 개선에 대한 고민개발/Spring Boot 2024. 5. 23. 17:30
원래 아키텍처는 위와 같은 모습이었다.첫번째 개선에서는 다음과 같은 일을 했다. 서비스 간 의존 결합도를 줄이기 위해 인터페이스 도입각 서비스가 인터페이스를 통해 상호 참조될 수 있도록 하여 결합도를 낮췄다. 이를 통해 서비스 간의 결합도를 낮추고 유연성을 높였다.PhotoService의 재사용성을 높이기 위해 역할 분리PhotoService의 재사용성을 높이기 위해 EncryptionService에 의존적이었던 메소드를 삭제하고, Encryption 관련 역할과 책임을 PhotoService에서 분리했다. 이를 통해 PhotoService는 더욱 독립적이고 재사용 가능하게 만들었다.EncryptionService의 역할 재정의암호화 역할을 명확히 하기 위해 Encryption을 Service에서 Com..
-
내 인생 첫 인턴을 마무리 하며개발/그 외 2024. 2. 24. 17:12
우당탕탕 모베란에서의 2개월간의 동계 방학 인턴이 마무리되었다. 벌써 2개월이 지났다니! 빠르게 지나간 시간이 믿기지 않는다. 주말마다 그 주에 뭘 배웠는지 복습해 보는 간단한 글을 적으려고 했는데 그건 너무 힘들어서 적지 못했다... 그래도 마무리 글은 꼭 적어야 할 것 같아 이렇게 글을 적어본다. 무엇을 했나? 회사에서 진행 중인 모 프로젝트에 백엔드 개발자로 참여하여 프로젝트의 관리자 부분을 제작하는 것을 도왔다. 무엇을 배웠나? "나만 알아볼 수 있는 코드는 의미가 없다"라는 것을 배웠다. 코틀린을 이용해서 스프링 부트 프로젝트를 해본 적이 없어서 모르는 것이 참 많았다. 마음 같아서는 사수님께 "처음부터 하나씩 설명해 주세요"라고 하고 싶었지만, 많이 바쁘시기도 했고 "이 정도는 내가 혼자 해야..
-
졸업작품을 만들며개발/그 외 2024. 1. 31. 15:25
들어가며 졸업작품을 만들면서 겪었던 일들과 그때마다 느꼈던 감정을 기록해두기 위해 이 글을 작성했다. 우리 운동앱 만들까? 우리들은 방학기간 동안 졸업작품을 위한 기획을 미리 정하기 위해 몇 차례 모여 회의를 진행했다. 우리에게 주어진 시간이 그렇게 많지 않았기 때에, 빠르게 주제를 정하기 위해서 가장 주목받는 키워드를 찾고 거기서 발전시켜 나가는 형태로 브레인스토밍을 진행했다. 그렇게 회의를 진행하던 중 2020년 이후 급 부상한 개인 운동 시장에 대한 이야기가 나왔고 이러한 시장을 겨냥한 앱을 만드는 것으로 의견이 모아졌다. 우리가 만들 앱은 주변 헬스장, 헬스장의 시설정보, 헬스장의 트레이너 목록을 간편하게 보여주고 또 트레이너와 매칭시켜 주는 기능을 포함하는 앱이었다 근데 재미가 없다... 기획하..