목록Server application/Spring (9)
ecsimsw
롤백에 의해 정합성이 깨지는 문제아래 update()에선 id에 해당하는 person의 이름을 수정한다. DB에서 person을 조회하고, Transaction이 종료되며 업데이트 쿼리를 수행하고, Cache를 업데이트하게 된다. @Transactional@CachePut(key = "#id", value = "person")public Person update(Long id, String newName) { var person = personRepository.findById(id).orElseThrow(); person.setName(newName); return person;} 만약 이 update를 감싼 트랜잭션이 실패하게 되면 어떻게 될까. @Transactionalpublic ..
k8s Rolling update 배포 Down time 문제서버가 운영되는 도중 배포시 Down time 이 발생하고 있다. 배포는 Kubernetes deployment rolling update로, 새 버전의 파드가 생성되고 기존 버전의 파드가 다운되길 반복한다. 서비스 운영 중 파드가 생성되고 제거되며 발생할 수 있는 Down time을 확인하고 해결한다. 문제 여지 1 : 이미 삭제된 Pod에 요청이 전달되는 경우 파드가 삭제되면 Kublet은 Container를 종료하고, 동시에 Endpoint controller (KubeProxy)는 IpTable routing rule 에서 해당 파드를 제거한다. 만약 IpTable이 업데이트되기 이전에 Container가 먼저 삭제되면, 요청을 처리할 ..
통합 테스트 환경 구성0. 유닛테스트와 통합테스트 PicUp에선 가급적 Test를 위한 Application context 를 지양했다. 유닛 테스트로 테스트 환경을 구성하는 시간을 줄이고 각 테스트를 짧게 하려고 노력했던 것 같다. 예를 들면 Controller는 standalone mock mvc로 api 의 요청, 응답 형태만 확인했고, Service Unit test는 테스트 외의 Service를 Mocking 하여 의도한 흐름대로 메서드가 호출되는지 정도만 확인했다. 통합테스트를 최대한 지양했지만 역설적으로 가장 크게 안정감을 얻고 있는 테스트는 통합테스트다. 특히 트랜잭션 처리가 의도한대로 동작하는지, 예외 처리 끝에 데이터가 어떻게 남는지 확인하는 등 가장 헷갈리고 놓치기 쉬운 포인트는 결..
배경 발명소 프로젝트 중이었다. 발명소는 신뢰도 있는 프로젝트에서 '변수명', '메서드명', '클래스명' 등 개발자의 작명이 얼마나 보편적으로 사용되는지를 검색할 수 있는 서비스이다. 개발자는 본인의 작명이 얼마나 빈번하게 사용되고, 어떤 상황에서 어떻게 사용되는지 확인할 수 있다. 시운영에서는 백만개를 넘는 코드 파일이 있었고, 테스트에서 가장 많았던 변수명(i) 또는 코드 내 단순 단어 검색은 그 검색 결과가 만개를 훌쩍 넘었다. 우리 팀은 페이지네이션을 적용했고, 그 페이지 수를 프론트 앱에서 결정할 수 있도록 했다. 서버에 보내는 요청 예시는 아래와 같다. i가 변수명으로 사용된 코드 부분을 검색하는데 한 페이지 안에 30개의 검색 결과를 갖는다고 할 때, 두 번째 페이지를 반환해줘. // ex)..
외부 디렉토리 동적 파일 참조 스프링부트에서 파일을 응답하는 법을 정리하려고 한다. 다만 보통 resouces/static에 넣어 사용하는 정적 컨텐츠가 아닌, 실행 도중 동적으로 생성하거나, 관리하는 파일을 다루는 방법을 고민해보았다. 요구 사항 1. 사용자가 실행 도중 업로드한 파일을 저장한다. 2. 저장된 파일의 물리적인 경로를 숨기면서 요청 -> 응답할 수 있도록 하고자 한다. 3. 즉 실제 파일 물리 경로인 card-photos/** 과 달리, 클라이언트의 요청은 /images/cards/** 처럼 명확한 path로 요청할 수 있도록 하고자 한다 방법 위 같은 요구 사항은 다음처럼 ResourceHandler를 사용하면 간단히 해결할 수 있다. 아래처럼 WebMvcConfigurer를 구현하고,..
Blocked by CORS policy 클라이언트 어플리케이션에서 서버로 요청을 보낼 때 만난 문제이다. CORS 정책에 의해서 요청이 제한되었다는데 CORS가 무엇인지, 어떻게 해결했는지 설명하려고 한다. Access to XMLHttpRequest at 'http://localhost:8080/members/login' from origin 'http://localhost:3000' has been blocked by CORS policy : Response to preflight request doesn't pass access control check : No 'Access-Control-Allow-Origin' header is present on the requested resource. 에..
HandlerMapping과 HandlerAdapter (@포모) 같이 공부하는 친구가 HandlerMapping과 HandlerAdapter의 차이를 질문해주었다. 내가 모호하게 알고 있었다는 것을 펜을 들고 설명하는 순간 알게 되었다. 혼자 머릿속에서 정리하는 것과 말로 설명할 수 있는 것은 정말 차이가 큰 것 같다. 질문을 받는 것은 정말 감사한 일이다. 아 그리고 부끄럽지만 영어 철자를 좀 제대로 봐야겠다. 안다고 생각했던 단어였는데 칠판에 쓰고 설명하려니 철자가 버벅인 경우도 많았다. 웃어 넘겼지만 평소에 조금 더 신경써서 봐야겠다. HandlerMapping FrontController 패턴으로 모든 요청을 DispatcherServlet이 처리한다. DispatcherServlet은 사용자의..
1. Static Resource 사용하기스프링 부트에서는 /resources/static의 파일을 url 요청으로 접근할 수 있다. resources/static/file/hello.html을 접근한다면 /localhost:8080/file/hello.html 기본 리소스 맵핑은 "/**"이지만, spring.mvc.static-path-pattern을 설정해서, url에 접근 경로를 지정할 수 있다. static path pattern은 application.yml에서 설정한다. spring.mvc.static-path-pattern: /static/** 위의 예시처럼 /static/**으로 설정한다면, 이후로는 정적 리소를 localhost:port/static/ 아래에서 접근하는 것이다. res..