📌 도입 배경All:Chive 서비스에 태그, 아카이빙 제목을 바탕으로 검색하는 부분이 있다.네이버나 구글 등에서 검색할 때, 검색어의 일부분을 입력할 경우, 제안된 검색어 목록이 실시간으로 나타나는 자동 완성 기능이 있다.All:Chive 서비스에도 이를 도입하고 싶었다.그래서 시작했다. 📌 DB 선택이 서비스를 구현함에 있어서 색인(?) 관련 데이터를 저장해야 했다.나는 총 3개의 DB를 고려했다.아래는 내가 왜 이 DB를 선택 혹은 선택하지 않은 이유이다. 🔵 Elastic Search데이터 저장, 검색에 있어서 뛰어난 성능을 가지고 있다고 알려진 DB이다.이것을 사용하기 위해선 새로운 시스템을 도입해야 했다.프로젝트를 진행하는 서버 개발자가 1명인 상황에서, 관리 포인트를 하나 늘리는 것이 ..
📌 분산락 도입 배경jmeter로 여러 유저가 동시에 같은 아키이빙에 스크랩하도록 해봤다.하지만 count 업데이트가 이상했다.분명히 유저 10명이 스크랩했는데, 스크랩 수는 10이 아니라 1이었다. 동시성 문제가 발생한 것이다.이로 인해 데이터 정합성이 깨지게 되었다.이에 필자는 분산락을 도입해 이를 해결하고자 했다. 📌 동시성 문제🔵 동시성동시성은 여러 작업이 겹쳐서 실행되는 것을 말한다.이때, 실제로 작업이 동시에 실행된다는 뜻은 아니다.쉬운 예시로 CPU의 작업 방식을 들 수 있다. CPU의 코어에서는 특정 시점에 하나의 작업만 수행 가능하다.하지만 CPU가 작업 간 전환을 빠르게 하기 때문에, 작업이 거의 동시에 실행되는 것처럼 보일 뿐이다. 🔵 동시성 문제2명의 유저가 있고, 재고 감소..
공통 에러 핸들러 구현하기" data-og-description="📌 스프링 에러 처리 방법 스프링은 프로그램 작동 중 여러 에러를 발생시킨다. 이에 에러를 처리할 수 있는 방법이 존재한다. 🔹 try-catch try { Jwts.parserBuilder().setSigningKey(getSecretKey()).build().parseCl" data-og-host="wtg1026.tistory.com" data-og-source-url="https://wtg1026.tistory.com/2" data-og-url="https://wtg1026.tistory.com/2" data-og-image="https://scrap.kakaocdn.net/dn/tdtKC/hySwSBMwOB/eCxwnElzUM9..
📌 HttpServletRequest🔵 HttpServletRequest란?Extends the javax.servlet.ServletRequest interface to provide request information for HTTP servlets. The servlet container creates an HttpServletRequest object and passes it as an argument to the servlet's service methods쉽게 말해서 HTTP 요청과 관련된 데이터를 저장하고, 이를 이용할 수 있는 메서드를 제공한다. 🔵 왜 값이 사라질까?서블릿의 HttpServletRequest는 body 데이터를 stream으로 제공한다.내용을 가져오기 위해 getIn..
📌이걸 왜?서버를 배포하게 되면 로그를 켜보지 않는 이상 에러 발생 여부에 관해 알기 힘들다로그를 보는 것보다 더 편하게 알 수 있는 방법이 있을까?에러를 슬랙이나 디스코드 알림처럼 볼 수 있으면 어떨까?에러가 발생하면 슬랙 알람이 오도록 구현해 보도록 하자 📌 알림 구현하기🔵 어떤 방식으로 구현했나?Global Exception Handler에서 500번대 에러를 처리하는 곳에 slack 메시지를 보내는 로직을 추가했다.이를 통해 500번대 error가 발생하면, 에러 내용과 request 정보에 관해 slack 메시지로 보내지도록 했다.또한 dev와 prod를 구분했다. 사실 실 서버에서만 작동하도록 구현해도 된다.하지만 개발 상황에서도 500번 에러를 발견하기 어렵다고 생각해서, 두 상황을 구..
📌 기존 프로젝트 프로젝트에서 커스텀 리스폰스를 이용하여 API response를 보내주기로 했었다. @GetMapping(value = "") @Operation(summary = "팀플 상세 정보 조회", description = "팀플 상세 정보 조회 API 입니다.") public CommonResponse getTeamDetail(@AuthUser User authUser, @Valid @RequestParam("teamId") Long teamId) { log.info("[api-get] 팀 상세 정보 가져오기"); GetTeamDetailDto teamDetail = teamsService.getTeamDetail(authUser, teamId); return CommonResponse.on..
📌 스프링 에러 처리 방법 스프링은 프로그램 작동 중 여러 에러를 발생시킨다. 이에 에러를 처리할 수 있는 방법이 존재한다. 🔹 try-catch try { Jwts.parserBuilder().setSigningKey(getSecretKey()).build().parseClaimsJws(token); return true; } catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) { log.info("Invalid JWT Token", e); } 단순한 try-catch를 사용한 예외처리이다. 이를 사용한다면 에러를 처리할 수 있으나, 코드의 중복이 많이 발생할 것이다. 🔹 @ControllerAdvice 위 어노테이션..
📌 슬랙 연결 방법 선택 구현할 기능이 메세지 전송이기 때문에 위 방법 중에서, Web API 혹은 Webhook을 사용할 수 있다. Slack API: Slack에서 제공하는 다양한 기능(메세지, 채널 관리, 파일 업로드, 유저 정보)을 사용할 수 있는 인터페이스이다. Slack API를 사용하는 경우 API 토큰이 필요하며, 해당 토큰을 사용하여 인증 및 권한 부여를 받아야 한다. Slack Incoming Webhook: Slack Incoming Webhook은 새로운 메시지를 특정 채널에 자동으로 게시할 수 있는 방법이다. Incoming Webhook을 생성한 후 Webhook URL을 사용하여 새로운 메시지를 게시할 수 있다. Webhook URL은 인증 및 권한 부여가 필요하지 않으며, 누..