처음에 웹 소켓으로 채팅을 연결할 때 계속 이렇게 STOMP 연결이 없다고 떴다.여기서 withSockJs()를 빼버리면 웹 소켓에 연결돼서 정상 작동한다.그런데, 왜 이게 잘 작동하는지 그 이유를 모르겠다.우선, 로그가 어떻게 뜨는지 확인해보기로 했다.저것만으로는 어
이번에 Plaything의 Oranization에 있는 프라이빗 레포에서 CI/CD를 구축하는 과정에서 SSH Key를 등록해야 한다는 문구가 나왔다. 그 동안 잘만쓰던 깃헙액션 CI/CD 스크립트와 환경변수인데 왜 안된다는건지 하루종일 이것만 붙잡아서 해결했다.
이번에 Plaything을 만들면서채팅 내역에 대한 보안 이야기가 나왔다.아무래도 성인 데이팅 앱이다보니 대화 내용이 관리자한테도 보여지질 않았으면 좋겠다는요구사항이 나왔다.그래서, 이게 실제로 가능한지 Real MySQL 책을 보면서 테스트해보기로 했다.MySQL은
S3와 관련해서는 매번 기계적으로 코드를 작성했는데 이번에 한번 관련 내용들을 정리해본다. S3 경로는 왜 UUID로 해야할까? 처음에는 경로 뒤에 유저 닉네임+AUTO_INCREMENT 느낌으로 넣어줘도 되지 않나? 싶었다. 그런데, 만약에 서버가 여러개가 된다고
멤버 정보가 있고 프로필 정보가 있다. 이걸 분리하는 게 좋을까?우선, 현재 로직은 회원가입을 하고서 추가로 프로필을 등록하는 방식이다.참고: The best way to use one-to-one table relationships이 글을 보고 사용 용도를 확인했다.
User가 있고 Profile이 있다고 해보자. 이때 User가 주 테이블이고 Profile이 대상 테이블이다. 일대일 관계에서는 주 테이블과 대상 테이블 모두가 외래키를 가질 수 있다. 두 가지 상황을 비교해보자. profile에 외래키를 넣는다고 해보자. 한명의 회원이 프로필을 여러개 쓰는 걸로 요구사항이 바뀐다면? profile에 외래키가 있다면...
편하게 테스트를 진행하려고 @BeforeEach를 통해서 먼저 user를 테스트 DB에 넣어두었다.그런데, 테스트를 돌리면 유저가 없다는 예외(커스텀 예외)가 발생했다.원인을 확안하기 위해서 디버깅을 해봤다.테스트 시작 전에 @BeforeEach로 user를 db에 저
Plaything에서는 이렇게 반대되는 성향에 대해서 매칭을 해준다.그런데 테스트코드에서는 이렇게 매칭할 때 매칭되는 대상이 없다고 떴다.실제 서비스를 돌릴 때는 잘 되던게 테스트에서느 안 된다고 하니 또 트랜잭션의 문제인가 싶었다.테스트에서 저장한 User의 정보가
예전에 SQL 안티패턴에서 서브테이블과 관련된 안티패턴을 본 적이 있다. 캐시와 포인트를 하나의 테이블을 상속하는 서브 테이블로 만들어야 하나 고민을 했다. 근데 사실 이러한 모델링의 필요성을 느끼지 못하는 상황에서 처음 사용해보는 걸 도입하는 건 아니라고 생각했다
기획자분과 얘기를 하면서캐시 충전을 하고 Key를 얻을 때 중간에 어떤 에러가 발생하면 어떻게 할지를 이야기했다.이런 경우는 보통 트랜잭션을 롤백시키는 방식을 썼다.근데, 혹시 롤백이 실패하거나 어떤 예외의 상황이 있을 수 있겠다는 생각을 했다.그렇다면, Key에 스탬
외래키와 관련해서는 어떨까?Real MySQL3장에서는"외래키는 부모테이블이나 자식 테이블에 데이터가 있는지 체크하는 작업이 필요하므로 잠금이 여러 테이블로 전파되고, 그로인해 데드락이 발생할 수 있다. 그래서 실무에서는 잘 사용하지 않는다."이런 내용이 있다.외래키와
포인트나 유저가 가진 캐시(Plaything에서는 Key로 명명했다)는 유저들이 여러번에 걸쳐서 받거나, 충전을 한다. 10일전에 무료 키 1개를 받고 5일전에 1개를 받고... 이런 식이다. 그렇다면, 이걸 애플리케이션에서 사용할 때는 어떻게 해야할까? 내가 참
Plaything의 mvp 규모는 대략 1000명.목표로 하고 있는 인원수는 1~2만명 정도다.그래서 DB에 2만명 정도의 유저를 넣어놓고 Matching 알고리즘을 테스트해봤다.우선 지금은 일대일로 반대 성향 유저를 10명만 보여주는 구조다.기본적인 인덱스는 있지만
Plaything에서는 광고 시청, 매일 첫 로그인 마다 포인트를 제공하고 있다. 4시간마다 광고를 보면 포인트를 제공하는 방식이다. 그런데, 이 비즈니스 로직을 테스트하기가 어려웠다. 이런 메서드가 있다. 마지막으로 광고를 본 시간과 비교해야 할 시간은 서버에서
Real MySQL을 공부할 때 나왔던 내용 중 하나가 "트랜잭션을 길게 가져가지 않도록 해야 한다" 였다. 트랜잭션이 정말 필요한 부분에서만 트랜잭션을 걸어야 한다는 것이다. 생각해보면 1)더티체킹을 할 때 2)롤백을 할 때 이런 경우에 나는 트랜잭션을 썼다.
Plaything에서는 프로필 사진을 세개까지 올릴 수 있다.프로필 사진을 올릴 때 트랜잭션을 걸어서 롤백을 하게끔 했다.그런데, 롤백은 외부 API에 대해서는 처리를 해주지 못한다.외부 API로 알림을 보내거나, S3에 사진을 업로드하면이건 내가 직접 지워주어야 한다
체크 예외가 발생하더라도 롤백이 발생하게끔 설정을 해두었다. 그런데, 매번 내가 체크 예외를 발생시켜서 직접 확인해야 한다는 불편함이 있다. 테스트에서 강제로 체크 예외를 터뜨리게 하고서, 롤백이 작동하는지 확인할 수는 없을까? 체크 예외 롤백 테스트 우선 위 코
보통 동시성 문제는 선착순 쿠폰이나, 인기 상품의 재고를 차감할 때나 다룰 것이라고 생각했다. 그런데, 동시성 이유를 서치해보니 포인트 충전 및 사용에서도 동시성 이슈를 고려한다는 글들이 꽤 보였다. 동시성이 언제 발생하는데? 동시성이 발생할 수 있는 상황을 정리
레디스에서 장애가 발생하면 이는 Single Point Failure가 될 수 있다. 단일 장애 지점. 즉, 한 곳에서의 장애가 전체 시스템 장애로 이어지는 사례다.레디스 cli에서 shutdown을 해서 서버를 내려봤다.이 레디스 서버를 사용하는 api 요청이 어떻게
1)SldingWindowType 서킷브레이커의 동작을 결정할 때 바라볼 대상(요청)을 일부로 한정 시키는 개념 -->최근 데이터를 대상으로기본값 Count_base -->요청 개수를 기준으로Time_based -->시간을 기준으로 결정2)SldingWindowSize
레디스에서 장애가 발생하면 이는 Single Point Failure가 될 수 있다. 단일 장애 지점. 즉, 한 곳에서의 장애가 전체 시스템 장애로 이어지는 사례다.레디스 cli에서 shutdown을 해서 서버를 내려봤다.이 레디스 서버를 사용하는 api 요청이 어떻게
이번 테스트에서는 verify를 사용했다.이 메서드를 사용하려면 mock이거나 Spy여야 한다. Mokito가 mock을 생성할 때는 실제 인스턴스가 아니라, 객체의 타입만 보고 한다. 이 mock 객체가 다른 인스턴스와 상호작용하는 것만 보기 위해서 만들기 때문이다.
로컬레디스를 쓰면서 테스트를 하니까트랜잭션 롤백이 되지 않아서 자꾸 테스트간에 간섭이 있었다.이에 임베디드 레디스와 테스트 컨테이너 두가지 방법을 알게 됐다. 임베디드 버전은 업데이트가 너무 오랫동안 안됐다고 한다.테스트 컨테이너를 사용하면 실제 환경과 유사하게 테스트
이렇게 레디스 서버가 다운됐다고 해보자.그럴 때 요청이 가면 이런 식으로 1분이나 시간이 걸린다.이렇게 타임아웃 설정을 해줬는데도 그랬다.로그를 보면 계속 재연결을 하느라 시간이 오래 걸리는 것으로 보였다.그래서, 우선 자동연결 비활성화하고 재연결 실패 시 진행중인 명
지금까지는 서버오류를"어? 페이지가 작동을 안하네?"라는 문제를 인식하고 개발자도구에서 API가 어떤 응답을 주는지 확인하고서 인지해왔다.이런 걸 좀 자동화할 수는 없을까?특정한 예외가 반복해서 발생한다거나서버가 다운됐거나혹은 서킷브레이커가 오픈 상태로 변환됐을 때 현
레퍼런스를 보고서 이렇게 만들었는데 계속 레디스와 연결이 안된다고 뜬다.여러 해결책을 하나씩 적용해보면서 해결해보자.로그를 보면 계속 레디스와 연결이 안되는 것으로 보인다.리눅스 도커 레디스, 스프링 연결 문제. 부탁드립니다.이 글을 보면 레디스의 ip를 redis로
아무런 설정도 하지 않은 레디스인데 디스크 저장 관련 문제가 있나보다.레디스 서버에서도 이런 로그가 계속 떴다.\[입 개발] Redis 서버가 MISCONF Redis is configured to save RDB snapshots 에러를 내며 동작하지 않아요?이 글을
현재 위 API를 통해서 프로필 사진과 함께 어느 인덱스의 사진이 메인 프로필 사진인지를 함께 보내주고 있다.그런데, 스웨거에서 테스트를 해보니 415응답코드가 내려왔다. 뭐지? 하고 서버 로그를 보니 어떤 타입이 잘 안 맞았던 거 같다. 로컬에서 미리 확인을 안해보고
채팅방 구조는 아래와 같다. 이렇게 채팅방이 있고 채팅 내역들이 채팅방을 연관관계로 갖고 있다. 채팅방 조회 채팅내역을 조회하기 위해서는 먼저 사용자 두 명이 속한 채팅방을 조회한다(Plaything에서는 일대일 채팅만 지원하고 있다) mvp 규모를 1만명 정
Plaything에서는 채팅이 핵심 기능 중 하나다.그런데, 19금 서비스 특성상 문제가 될 법한 메시지가 전송되지 못하도록 막아야 한다는 문제가 있다.성적인 제안을 하거나 금전적인 거래가 오가는 걸 막아야 한다.굉장히 복잡하고 어려운 기능이지만.. 우선 만들어야 하기
우선 라이브러리를 추가해준다. 관련내용은 여기서 볼 수 있다. 이렇게 금칙어가 어디서부터 어디서까지 시작되는지를 확인할 수 있다. '돈까스'에 돈과 돈까스가 겹치는데, 이렇게 중복되는 걸 찾지 않으려면 ignoreOverlaps()를
우선, 메시지의 경우에는 여러 방식으로 우회를 할 수 있다. "계좌1번호" "돈@@ 보내줘" 이런식으로 우회하는 걸 막으려면 우선 정규표현식으로 우회하는 표현들을 다 지워줘여 한다.
이 참에 N+1 문제를 제대로 정리해보자. 위 쿼리는 채팅방 목록을 조회하는 쿼리다. 이때, 여러 테이블을 뒤져서 정보를 조회한다. 프로필, 프로필사진, 채팅 메시지(최신 메시지를 보여줘야 하기에) 이렇게 세개의 테이블을 조인해야 한다. 그런데 조회하는 채팅방마
이 쿼리를 봐보자.모든 레코드를 스캔했다고 돼 있다.뭔가 성능적으로 좋지는 않아 보인다.웬만해서는 Join과 or을 같이 쓰지 않는 ㅔㄱ 좋다고 한다. SQL 서버 최적화가 안되는 탓이다.인덱스를 타지 못하기 때문!\-> Filter: ((p1_0.is_deleted
이 사진은 현재 채팅방을 조회하는 최종본의 쿼리다.인덱스를 다 잘타고 있다.Inner Join과 Left Join의 차이이 글에서 언급했듯inner join은 교집합을 가져온다.Real MySQL2권을 보면서 개념적인 정리를 좀더 해보자.이너조인은 조인 대상 테이블에
RateLimiter는 단위 시간동안 얼마만큼의 실행을 허용할 것인지 제한할 수 있는 메커니즘을 말한다.채팅의 경우 메시지를 한번에 여러번 보낼 수 있다.이 경우 너무 많은 메시지를 보내면 스프리 서버, DB부하가 커질 수밖에 없다.지난번 CircuitBreaker 구
이번에 Cron으로 메모리 데이터를 지워주는 작업을 스케쥴링한다.채팅메시지에 대해서 rate limit 기능을 구현할 때각 유저마다 1초에 몇개의 메시지를 보냈는지를 map에 담아서 확인한다.사실 이것만으로 메모리를 많이 차지하지는 않을 거 같지만그래도 며칠간 로그인을
채팅을 만들면서 가장 불편했던 건 클라이언트가 없어서 실시간으로 잘 작동하는지 확인하기가 어렵다는것이다.채팅 개발 강의를 보면서 얻은 클라이언트 코드가 있긴 하지만이걸 내쪽에 맞춰서 쓰기가 쉽지 않았다.그런 와중에 알게 된 Stomp 테스트 사이트가 있다.참고:\[Pr
jwt 토큰을 바로 받을 수가 없어서 이렇게 토큰을 꺼내와야 했다.그런데, 찾아보니 interceptor를 쓸 수 있다고 한다.HandshakeInterceptor, ChannelInterceptor 이 두가지가 있는데 후자를 쓰면 된다.HandshakeIntercep
Stomp와 관련해서 인증 로직을 굉장히 복잡하게 작성했다. 실제 서버를 돌려서 작동하는 건 확인했지만... 역시 비즈니스 코드가 복잡해질 수록 느끼게 되는 고민 중 하나가 리팩토링이다... 리팩토링을 하고서 계속 서버를 돌리면서 로직이 정상적인지 확인해야 한다.
채팅 기능을 만들면서클라이언트에서 온 요청이 있다.웹 소켓 연결이 계속 끊길 수 있으니 에러 처리를 잘해주어야 한다.아직 본격적으로 클라이언트와 연결을 하진 않아서 이렇게 처리해야 할 상황이 어떤 것들이 있을까?우선, 웹소켓 연결이 disconnect됐지만 서버에서는
채팅을 보내는 코드다.그런데, 이 코드를 보면서 든 생각이 있다.트랜잭션이 정말 필요한가?보통 트랜잭션은 비즈니스 로직들을 원자적으로 관리하기 위해서 사용한다.비즈니스 로직이 a->b->c->d->e라고 할 때 d를 작업하다가 실패하면 앞에서 했던 db 저장/업데이트/
이제 누락된 메시지를 어떻게 전달할 수 있을지 봐보자.이를 위해선우선, 메시지가 누락됐는지 여부를 서버에서 체크해야 한다.이때 사용할 수 있는 방법이 sequence다. 채팅방마다 sequence를 부여하고, message에 이 sequence를 넣어서 저장하고 웹소켓
Plaything을 개발하면서 주간 회의 때 나온 말이"배포서버에 직접 접근이 안되면 저희 로컬에서 작업할 수 있게 해주세요. 도커로"였다.처음에는 그게 무슨 말인가 싶었다.문제 상황은 다음과 같다.배포 서버는 아직 HTTPS를 적용하지 않았다. 도메인 구메와 관련해서
지난번에 시퀀스를 사용해서 누락된 메시지를 전달하는 로직을 구현했다. 위 사진을 보면a와 b가 서로 메시지를 교환하다, b의 메시지 (4,5,6,7,8)이 db에 저장은 됐지만 전송이 안 됐다.a가 메시지를 보낼 때는 클라이언트가 갖고 있는 마지막 값 3이 있는데 채팅
현재 이런식으로 커스텀 예외를 만들어서 사용하고 있다. 그런데, 클라이언트에서 이렇게만 보내지말고 각각 일반적인 의미의 Http 상태코드로 내려달라는 요청을 했다. 이렇게 해본 적이 없어서 하나씩 공부하면서 상태코드를 맵핑하기로 했다. already exist는
이번에 S3 키가 의도치 않게 github에 공개되면서 보안에 정말 신경써야 한다는 점을 배우게 됐다. 다행이도 AWS에서 키가 공개되자마자 메일을 보내고 키를 비활성화해주었다. 이상하게 commit에 application.properties 정보가 들어가있었고 파
배포를 하고서 api를 다시 테스트해봤는데 갑자기 서킷브레이커 경고가 떴다.레디스에 문제가 있는 것으로 보인다.레디스를 연결해둔 ec2에서 레디스 클라이언트로 접속을 해봤다.레디스에 들어오는 요청에 대한 로그를 보려면 'monitor'를 입력하면 된다고 한다.서버에서
현재 보안과 관련해서 엔진엑스로 배드봇의 IP를 차단해야 한다는 이슈가 생겼다. 그런데, 엔진엑스를 붙이면 웹소켓과 관련된 설정들을 해줘야 한다.아직 배포서버에서는 HTTPS를 붙이지 못한 상태라 nginx 설정이 웹소켓과 잘 호환되는지 확인할 방법이 없다.그래서, 우
Rate Limiting with NGINX여기에 그 내용이 잘 설명돼 있다.이 기능을 사용하면 http 리퀘스트의 요청량을 조절할 수 있다. brute‑force password‑guessing attacks(무차별 대입 공격)을 막는데 주로 활용할 수 있다. 실 이
초당 10번의 요청을 허용했지만 이건 엄밀히 따지면 0.1초당 1번의 요청을 허용한다.그래서 이렇게 한번에 여러개의 요청이 오는 경우 429가 발생한다.엔진엑스의 access.log를 보면 동일한 시간대에 요청이 한번에 몰려오는 걸 볼 수 있다.이러한 문제를 해결하려면
서버에서 발생하는 500에러를 디스코드 웹훅으로 보내는 기능을 구현했더니 갑자기 메시지 여러개가 들어왔다. 클라이언트 개발자분들께 관련 내용을 물어보니 본인들이 한 게 아니라고 하셨다. a
NGINX에 대한 보안을 강화하는 방법 Nginx security hardening guide을 참고해보자.현재는 NGINX로 요청을 보내면 응답 헤더에 NGINX 버전이 명시된다. 이를 숨기는 게 좋다고 한다.이 설정을 추가해주면 된다.이제 응답에 버전이 명시되지 않
현재 NGINX로 어뷰징 관련해서 제한하는 인프라와NGINX 로그를 확인해서 로봇으로 의심되는 IP를 차단하는 fail2ban 인프라를 구축했다.어뷰징 대응 목적으로 규정을 좀 빡빡하게 잡았는데하루 사이에 걸린 IP만 7개다. 지금은 초기라서 그렇고 IP가 수집되면 나
Tuning NGINX for Performance 이 글을 참고한다.NGINX에서는 access.log에 접근 로그들이 계속 쌓인다.error.log는 생각보다 많이 안 쌓이지만 access.log의 양이 계속 커질 것으로 보인다.우선 정적 리소스에 대해서 로그를 해
현재 테스트의 양이 많아지다 보니 커넥션 수가 늘어나고 이에 따라 연결을 거부하는 문제가 발생하는 것으로 보인다.If clients encounter Too many connections errors when attempting to connect to the mysq
우선 ElasticCache의 레디스는 직접 config 파일을 변경하는 게 아니라 Parameter group을 변경하는 식으로 해야 한다. 레디스의 보안을 위해서 비밀번호를 추가하는 등의 보안 지침이 있지만 이런것들이 가능하지 않아서 우선 TLS만 설정하기로 했다
인프런 -개발자에게 필요한 로그 관리 강의를 참고해서 로그 설정을 할 계획이다.1) 트러블 슈팅에 도움이 될 것 같은 정보2) 법적으로 필요한 경우Sl4j를 사용해서 로그를 입력만약 로그인이 안 된다면?? 이렇게 로그인 API 사용이 됐다는 로그만 남기는 거랑위처럼 어
현재 매칭과 관련해서 Redis 캐시를 이용할 계획이다.여러 방식으로 사용함에 따라 이 내용을 글로 정리해본다.우선 이 코드의 문제점을 살펴보자.레디스의 에러가 비즈니스 로직에 영향을 준다. 즉, 의존성이 너무 커져버린다. Matching을 할 때마다 레디스를 먼저 u
이 메서드를 보면 레디스에 요청을 보내고, 응답을 받고 이 과정이 여러번에 걸쳐서 반복된다. 레디스 로그를 보면 매칭 프로필을 조회를 하는데 한번에 5번이나 요청이 오는 것을 볼 수 있다. 레디스 Pipeline Redis pipelining > How to
현재 ElastiCache를 쓰고 있지만외부 포트를 다 막아서 WireShark로 패킷 분석이 불가능하다.그래서, Ec2에서 tcp dumpfile을 만든 뒤 이를 WireShark로 분석한다.이렇게 캡쳐를 시작하고 레디스 통신을 몇번 해준다.이렇게 scp를 통해서 내
DB 모델링을 하다보면연관관계를 맺거나 식별자를 사용하는 방법 둘 중 무엇을 써야할지 고민이 될 때가 있다.가령, User1과 그 유저의 '프로필 다시보지 않기' 데이터를 쌓는다고 해보자.이때 전자의 방식은 연관관계를 설정하는 것이고, 후자의 방식은 User1의 로그인
여기서 rotate가 14일치의 로그를 정리한다는 뜻이다.로그를 7일치까지만 쌓는 걸로 하자20일 이상된 로그들을 지워주는 명령어다.
git 관리를 잘못하는 바람에test코드의 설정파일이 git에 올라갔다.나는 그것도 몰랐는데그걸 지우긴 했지만 git 커밋 history에 그 내용이 남아있었던거 같다. 그래서, 레포지토리를 public으로 돌리자마자 aws에서 빨리 변경하라고 메일이 왔다...그 뒤로
연관관계를 맺다 보니 데이터를 삭제할 때 작업이 너무 복잡해진다. 특히, User 탈퇴를 할때 개인정보 보호법상 탈퇴한 회원도 데이터를 6개월간 보관하고 삭제를 해야 한다는데 우선 소프트 딜리트 처리를 하더라도 나중에 이 User에 걸려 있는 데이터들을 먼저 지워줘야
CascadeType.REMOVE는 부모 엔티티를 삭제하면 자식 엔티티도 삭제한다. 부모가 자식의 생명 주기를 관리한다. 부모 엔티티가 자식 엔티티와의 관계를 제거해도, 자식 엔티티는 삭제되지 않고 그대로 남는다.Profile과 List는Casacade.ALL 관계로
프로필의 경우 업데이트할 때마다 변경되는 부분이 있고 그렇지 않은 부분들이 있다.만약 변경감지를쓰면 sql쿼리에는 모든 걸 업데이트 하는 방식으로 들어간다.이 경우 성능을 위해서라면 그냥 사용하는 게 좋고, 엔티티 필드 수는 많은데 한번에 수정해야 할 필드가 적고 데이
프로필 관련 테스트를 하다가 이 부분에서 계속 테스트가 실패해서 로그를 확인해봤다.여길 보면 Long에서 longValue()메서드를 쓰면 참조타입-> 기본타입 number로 변경이 되는데null이라서 이 메서드를 사용할 수 없다는 것이다.그렇다. MyProfile 응
엔티티의 컬렉션을 수정하려고 할 때 간혹 만났던 예외다.이렇게 for문으로 컬렉션을 돌리면서 Collection의 원소를 삭제하려고 하니 생긴 문제다.이게 어떻게 예외가 발생하는지 궁금해서 한번 디버깅을 해봤다.List에서 remove를 하고서, hasNext()로 다
테스트를 하면서 프로필 이미지 모니터링 용으로 만든 엔티티에 프로필 이미지의 id가 맵핑이 되지 않는 문제가 발생했다. 설계는 위처럼 돼 있다. 외래키 제약조건 때문에 ProfileImage를 삭제하는 과정이 번거로워져서 FK 제약조건을 사용하지 않는다. 가 던져져야 하는데 갑자기?... 무슨 일인지 확인해보기 위해서 디버깅을 했다. profile이 nu
부끄러운 일이지만 클라이언트분들과 협업을 하면서 주석이나 API Tag에 오타를 내서 이를 수정해달라는 요청을 받았다. 깃헙 액션에 Pull request를 올렸을 때 오타체크를 하는 작업을 할 수 있다. name: Spell Check on: [push, pul
우분투 보안을 강화하고서처음으로 CI/CD 자동배포를 해보니 역시 SSH 연결이 안 됐다.syslog를 보니해외 IP의 SSH 접속을 막았기 때문인 것으로 추정된다.이걸 만들고 나서 알게 된 것인데사실 처음부터 private key를 사용해서 접근하게 했으면 될 것같다
이번에 앱개발자분들과 협업하면서컨벤션의 중요성을 다시 배웠다.우선, 엔드포인트마다 반환타입이 통일되지 않아서 앱 개발을 하는 과정에서 쉽지 않다는 이야기를 들었다.개발에 급급해서 변수명에도 신경을 많이 못쓰기도 했다.이렇게 플러그인을 설치해준다.구글 스타일을 적용해보자
우선 좋은 네이밍 패턴은1) 언더바 대신 하이픈(-)을 사용한다. 대신 이 하이픈은 가독성을 높이기 위해서 사용해야 한다.2) 행위를 표현하지 않는다. 행위는 URL대신 메서드로 표현한다.3) 파일 확장자는 URL에 포함하지 않는다.4) 전달하고자 하는 명사를 사용하되
스프링 서버가 메모리를 많이 잡아먹긴하지만 상당히 많이 쓰고 있다. 어떤 부분에서 메모리 사용이 많은 건지 확인해보기 위해서VisualVM을 로컬에 띄운 뒤 원격으로 모니터링 연결을 해보기로 했다.이를 위해서 우선 AWS에서 8500 인바운드 포트를 열어준다.jar 파
프로필 조회 API를 봐보자 처음에 GC를 수행하고 이랬던 상황에서 프로필 조회 API를 3~4번 연속했더니 이렇게 메모리 사용량이 커졌다. 이렇게 AOP를 활용해서 메모리 사용량을 추적하기로 했다. 약 2MB정도의 메모리를 사용한다. MyPage는 생각보다
보통은 엔티티를 조회할 때 모든 컬럼을 다 가져오지 말고 필요한 칼럼만 조회하라는 이야기를 많이 한다. 우선, Eager와 Lazy부터 Eager로 fetch하는 방식은 성능측면에서 권장되지 않는다. 연관관계에 있는 것들을, 모두 처음부터 fetch를 하는 데 처음부
이렇게 해준다음에sites-available파일에 들어가서이런식으로 해주면 된다.
포스트맨에서 https로 요청을 보내면 잘 가지만스웨거에서는 http로 요청을 보내게 되는 게 디폴트인것같고(curl을 보면 그렇게 간다)그래서 Mixed content에러가 뜬다. HTTPS 페이지에 일반 평문인 HTTP 프로토콜을 사용하는 것을 Mixted Cont
일반적으로 유저들은 ip를 통해서 서버에 접속하지 않는다. 그런 일은 거의 없다고 봐도 좋을 것이다. 그렇다면, 굳이 ip로 들어오는 이상한 access까지 허용할 필요가 없다. Should a website be directly accessible by its I
What is 444 Status Error Code?The 444 error code is unique to Nginx, which is a program some websites use to run their servers. Unlike other common er
신고하기 기능을 만들어야 하는데신고 타입을 'A', 'B', 'C'로 선택하거나 'ETC'를 선택해서 이유를 적게끔 해달라는요구사항을 받았다.이렇게 되면ETC에만 내용을 따로 저장해야 하는 상황이 생긴다. 처음 생각했던 구조는모든 신고마다 reason이라는 칼럼을 두고
보통 테스트는 서비스단을 주로한다.컨트롤러단 테스트는 잘 안하게 된다(필요성을 딱히 못 느꼈다)admin api나 jwt 인증이 필요한 경우도 이 기능이 제대로 작동하는지는직접 api 요청을 쏴보면 명확하게 나타난다.그럼에도, 시큐리티 설정을 실수로 변경할 수도 있다는
회원가입시 본인인증을 하기 위해서 SMS 인증을 한다.클라이언트 개발자 분들께 들어보니SMS같은 경우는 API 호출 IP가 계속 달라지면 안돼서서버에서 처리하는 게 좋다고 한다.구현 방식은 간단하다.SMS 서비스로 휴대폰에 인증번호를 보내고, 레디스에 유효시간동안 담아
visualvm으로 모니터링하던 서버에서 갑자기 cpu 사용량이 100%대로 치솟는 현상이 발생했다.이런 적은 처음이라 걱정이 됐고일단 빠르게 조치를 취해야겠다는 생각이 들었다.이때 활용할 수 있는 게 우분투의 rkhunter이라고 한다.이렇게 하면 루트킷을 찾아낼수
지난 밤 12시20분쯤에 cpu 사용량이 갑자기 90%대로 올라갔다.그당시에 백신을 돌려서 악성 바이러스를 확인하긴 했지만... 뭐때문인지 이유를 좀더 자세하게 보기 위해서syslog를 확인했다.그 시간대에 Lynis 검사가 돌아가고 있었다.로그를 좀더 보니 Lynis
Linux 운영체제는 여러 작동 이벤트를 기록하기 위해서 로그 파일들을 만든다. 다만, 이 파일을 읽기는 쉽지 않다. 그래서 원시 로그 파일을 보다 사용자 친화적인 로그 다이제스트로 변환할 수 있는 유틸리티가 활용된다.logwatch는 Perl로 작성된 오픈 소스 로그
메모리가 처음에는 100mb선이었다가, 이제 150mb선으로 넘어갔다.점진적으로 늘어나는 데 문제가 있는 것으로 보인다.heap dumpfile을 생성하고서MAT으로 이를 분석해보니Finalizer라는 클래스가 유력한 leak suspect였다.이 클래스를 봐도 딱히
(1)에서 DB 커넥션이 이상하게 많이 생성돼 있어서 이를 줄이는 방식을 썼다.이렇게 커넥션을 줄이게 된 이유는 99%가 모른다는 DB Connection 누수 문제이 글을 보고서 DB 커넥션이 메모리 사용량의 범인일 수 있겠다는 추측을 했기 때문이다.heap dump
Plaything에서는 광고를 시청하면 유저에게 포인트를 제공한다. 이를 위해서 서버에서 ssv라는 검증을 해줘야 한다고 한다. > Server-side verification validates each completed rewarded ad view. This en
기존에 PUT으로 수정하던 데이터들을 PATCH로 변경하고 배포 서버에서 메서드들을 실행해보니 계쏙 403이 떴다. 그 이유를 찾아보니 cors 설정 때문이라고 한다. 우선 여기 서버에서 cors로 허용해주는 메서드로 option과 patch를 넣어준다.
S3를 사용해서 프로필 이미지를 보관하고 있는데단위테스트를 돌릴 땐 S3를 직접 쓰지 않는 방식으로 저장/삭제 테스트를 했다.즉, 현재 구조가이렇게 ProfileFacade가 있는데 여기서 우선 validate를 앞단에서 다 진행해준다.그걸 통과한 애들만 db에 사진
JWT는 항상 탈취의 위험이 있다.
Smtp로 문의하기 기능을 개발했는데스웨거에서 보낼 때는 문제가 없었지만 클라이언트에서 요청을 보낼 때는 위처럼 timeout이 떴다.클라이언트 개발자분이 타임아웃 시간을 3초로 설정해두기도 했고Smtp가 요청을 보내면 끝날 때까지 시간이 좀 걸렸다.실제로 포스트맨으로
우선 현재 액세스 토큰 1개만 만들어놓은 상황이었으니 refresh 토큰까지 같이 발급하는 로직으로 변경해주자. 보통은 리프래시 토큰을 이렇게 쿠키로 만들어서 전송하는것으로 보인다. 다만 모바일 앱에서는 XSS에 대한 위험이 덜한것으로 보여서 헤더로 보낸다.
JWT의 장점은 StateLess함을 구현할 수 있다는 것이지만로그아웃, 탈취 등의 문제를 고려하면 완전히 Stateless함을 유지하기는 어렵다.해킹된 것으로 의심되는 토큰이나, 로그아웃 후 액세스 토큰을 DB나 레디스에 저장을 하고 계속 JWT 토큰이 들어올 때마다
현재 Plaything에서는 결제 요청에 transaction-id를 헤더에 넣어서 서버로 보내고 있는데, 서버는 이를 통해서 통일한 요청이 오면 중복 요청을 걸러내고 있다.이때 레디스를 활용해서 transaction-id를 일정 시간만 저장하고 제거한다.다만, 이렇게