반응형
프로젝트 설명
편의점 할인 정보를 한 눈에 파악할 수 있는 프로젝트
- CU, GS, SEVEN, EMART24 데이터 크롤링
프로젝트를 통해 배운 점(기술)
- Jenkins와 Docker를 활용한 CI/CD
- Jenkins의 General Webhook Trigger를 이용해 브랜치별 파이프라인 구축
- Docker-compose 사용법
- nginx으로 정적 빌드파일을 어떻게 실행시킨다는 것인지 알 수 있었다.
nginx는 Apache Tomcat처럼 Web Server로써 React프로젝트 npm build 했을 때 나오는 정적 파일을 Web Server로 띄워주는 것 - 애매했던 WebServer(Nginx)와 WAS의 차이파악
Spring(WAS) : request에 따라 DB데이터를 가공해주거나 하는 역할 등 Service로직이 담김
React(Web Server) : 유저와 상호작용하며 데이터를 request 하는 주체 - Docker 컨테이너는 개별적인 IP를 가지고 있어서 어느 한 컨테이너에서 localhost를 요청하면 자기자신에게 요청하는 것
- Docker의 port 명령어와 expose 명령어 이해
- Blue Green 무중단 배포
- 프로젝트 기간내에 수행할 수 없어 주말을 이용해 완성한 후 블로그 업로드 할 것..
- MVC 패턴
- 지금까지 Entity 혹은 DB 테이블에 따라 Controller, Service, Repository를 한 번에 했는데 공통 때 처럼 순환 참조가 빈번히 발생했다. 생각해보니 기능 대분류 별로 Controller, Service를 구현하는거일텐데 바보
- CustomResponse, CustomException
- Java 자체에 다양한 Exception이 존재하지만 에러 메세지르
- 에러 메세지가 정확할 수록 취약점을 발견하기 쉽다는 단점이 있었지만, 발표전 자체 테스트 기간에 CustomErrorCode 덕분에 쉽게 문제를 해결할 수 있었다.
- GlobalExceptionHandler
- Exception이 발생했을 때, 공통적으로 처리하는 ExceptionHandler를 사용하니 좋더라. 예외가 발생하면 GlobalException가 뚝딱하고 클라이언트에게 예외를 전달해준다.
- Spring Security - HttpOnly 방식
- 팀원이 구현한 방식. 직접 JWT를 주고 받는 것이 아닌 HttpOnly Cookie에 담아 전송함으로써 4가지 이점을 챙길 수 있었다.
- XSS을 예방할 수 있다.
JavaScript에서 직접 Cookie에 접근할 수 없어 수정할 수 없음 - 스니핑 예방할 수 있다.(Https 적용 한정)
트래픽 캡쳐나 MITM같은 트래픽 조작으로 부터 안전하다. - CSRF을 예방할 수 있다.
같거나 허용된 사이트에서만 사용할 사용할 수 있기 때문이다. - Bearer없이 테스트할 수 있다.
쿠키에 넣어서 전송하기 때문에 AJAX 요청 헤더에 Bearer 토큰이 필요없다.
Filter가 HttpServletRequest 인스턴스에서 getCookie로 열어보면 된다.
- XSS을 예방할 수 있다.
- 팀원이 구현한 방식. 직접 JWT를 주고 받는 것이 아닌 HttpOnly Cookie에 담아 전송함으로써 4가지 이점을 챙길 수 있었다.
- Elastic Search
- nori-analyzerf를 통해 글자를 역색인화 한다. 그럼 일정한 Token단위로 글자가 나눠짐 -> 입력값을 넣으면 nori-analyzer에 의해 Token으로 쪼개지고 이것을 기반해 유사도 순으로 출력한다.
- SQL문과 차이점은 직접 입력값을 파싱하고 like 연산을 수행하면 유사도가 없는 것 부터, 글자가 포함되면 전부 출력되지만, ES는 유사도에 기반해 결과를 출력해줌으로써 보다 사용자 편의성이 확장된다.

- 편의점 상품을 검색할 때 정확한 상품명을 아는 경우가 적고, 편의점 별 상품 이름이 조금씩 차이나기 때문에
- 1개의 클러스터에 N개의 노드를 삽입했다. 그 중 1개는 Master Node로 직접 연산을 처리하고 나머지는 Sub Node지만, 모종의 이유로 Master Node가 사망했을 때, Sub Node중 하나가 Master를 승계함으로써 서비스가 지속될 수 있게 한다.

- Kibana는 Elsatic용 GUI 툴
- Static 활용해보기
- 상품 정보를 반환할 때, 3개의 테이블을 Join해서 결과를 반환하다보니 서비스별로 공통 로직(중복된 코드)가 너무 많았다.
- static 클래스와 메소드를 만들어서 전역에서 사용할 수 있게함으로써 보다 편하게 개발을 한 것 같다.
- 또 인스턴스가 아닌 클래스 그 자체로 사용해야한다는 것을 직접 배울 수 있었음
@Component
@Slf4j
public class ResponseUtil {
public static Map<String, Object> toResponseData(Object[] resultSet) {
Product pd = (Product) resultSet[0];
EventProduct ed = (EventProduct) resultSet[1];
MemberPickProd mpp = (MemberPickProd) resultSet[2];
Map<String, Object> response = new HashMap<>();
response.put("product", (pd != null) ? pd.toInfoDto() : ProductInfoDto.builder().build());
response.put("event", (ed != null) ? ed.toInfoDto() : EventInfoDto.builder().build());
response.put("userLike", (mpp != null) ? mpp.toInfoDto() : MemberPickProdInfoDto.builder().build());
return response;
}
public static Page<Map<String, Object>> getPageProducts(Page<Object[]> data) {
return data.map(ResponseUtil::toResponseData);
}
public static List<Map<String, Object>> getListProducts(List<Object[]> resultSets) {
return resultSets.stream()
.map(ResponseUtil::toResponseData)
.collect(Collectors.toList());
}
}
// 실제 사용코드
ResponseUtil.getListProducts(productRepository.findRecommandProductsByMemberId(PageRequest.of(0, 4), memberId))
프로젝트를 통해 배운 점(인성)
취업(자기소개서, 알고리즘 혹은 각자 해보고 싶은 기술 스택)을 위주로 했기에 프로젝트 규모와 수상에 대한 욕심은 적었지만 꽤나 즐겁게, 프로젝트에도 열과 성을 다한 것 같다.
사실 SSAFY하면서 취업을 준비한다는 것은 쉽지 않았으나.. 2마리 토기를 잡으려면 어중간하게 하는 것이 아닌 죽기 살기로 해야하는 것을 배울 수 있었다.
이제는 과정도 중요하지만 결과를 내야하지 않을까..라며 고민에 빠진 순간
또, 최종 발표 맡았지만 개인적으로 만족하지 못했다.
말을 자주 절고 너무 빨리 하는 것을 스스로 느꼈으면, 청충들은 오죽했을까? 그래도 기술에 대한 설명은 잘 진행했다는 피드백이 있어 다행이었다. 다른 팀으로부터 Elastic Search나 HttpOnly Cookie를 사용해 JWT를 Wrapping 한 이유 쉽게 설명해줘서 고맙다는 이야기를 들었기 때문
자율 때는 좀 더 여유를 가지고 전달하는 방법에 대해 고민을 많이 해봐야겠다. 더 많이 말을 해봐야 늘어나니까
프로젝트 URL
반응형