url shortner 만큼 많이 들어봣을 예제인 realtime notification system 을 만들고잇음
원래는 그냥 핫딜갖고와서 디코에다가 뿌리는거엿는데, 키워드알림에대한 수요가 생겨서 아얘 알림시스템을 직접만들어보고 잇는중임
대략 이런구조
일단 키워드를 관리하는 쪽임
현재는 디스코드 봇으로 입력을 받아서, 키워드를 CRUD 함
물론 웹서버라든가, 텔레그램 등 다른 봇을 지원하는 멀티클라이언트도 가능하게 확장성고려해서 설계해놓음
-
db 는 postgresql 을 사용햇음
benchmark 보면 mysql 에 비해 어느정도 선에서 throughput 도 잘나오는 편이고 container 기준으로 configuration 도 쉽기때문임
* 물론 rds 좋은거알고 나도 쓰고싶지만 돈이없어서 container 로 띄우고 volume mapping 해주고 쓰는중
index 는 user 는 userId 에, keyword 는 keywordHash 에 걸어줌
-
Domain model 은 a keyword has many user 로 설계하고, keyword 가 aggregate root 가 됨
이렇게하니까 ddd 에서 나온대로 생각을 다양하게 하지않고 간단하게 획정시킬수잇어서 복잡성의 임계치를 걸어둘수잇다는점은 좋은데 장기적으론 어떨까 모르겟음
-
Caching layer 가 잇고, keyword 에 대한 write transaction 이 이루어질 때 write-through 방식으로 갱신시킴
왜냐면 알림시스템에서 사용자한테 알림을 쏴줘야할때마다 데이터베이스에 쿼리를 날리는건 너무 오버헤드라고 생각햇기때문임
Redis 를 사용햇고 keyword hash-user id 를 key 로 해서 구독한 user 들의 정보를 keywordHash-userId: { rawKeyword, cameFrom } 구조로 HSET 을 통헤 저장중
scrapper side 임
-
펨코가 fingerprinting 해서 그거 피하느라 이거저거 좀 햇음
네트워크탭이나 소스탭에서 fingerprinting 을 어떤식으로하는지 소스도 보고, 어떤 http header 가 오가는지도 확인해서 어찌저찌 해결
-
뽐뿌는 뭐 무난햇고
어미새라든가 다른곳들도 점진적으로 추가해나갈 예정
setTimeout 으로 반복시키는걸 하고잇는데, rxjs 같은거로 좀 깔끔하게 할순없으려나 생각도좀들지만 이 작업의 우선순위는 현재 높지않아서 일단 돌아만가다오드리븐디벨롭먼트 중
-
핫딜중복을 걸러내는덴 LRU Cache + Hash table 을 이용함
id 로만 해도되잔아? 하는데, id는 같은데 양식에맞추어 다시 개시하다보니 제목이 달라지는 경우도 잇고 재업이나 끌올, 아니면 인기핫딜에 올라가면서 제목은 같은데 id 가 달라지는 경우도 잇어서... 그걸 검증하기 위해 고안해봄
size 가 40개 정도 되는 LRU Cache 하나를 만들고, 제목이랑 id 로 해시문자열을 하나 만들어서 그걸 key 로 하는 Hash table 에 넣음
key 로 찍엇을때 없는애들은 점점후순위로밀리고 size 가 꽉차는순간 순차적으로 evict 됨
가운데에 잇는 message broker 임
kafka 말고 새로운거좀 써봄
memphis 라는건데, NATS 라고 지금은 사실상 유기된 프로젝트를 포크해서 의기투합하는 사람들이 만들어나가는 거임 개발자경험이 상당히 좋으니 토이프로젝트로 츄라이해보는거 추천
web gui 가 잘만들어져잇어서 topic management 등의 관리가 쉽고 DLQ, schemaverse 같은 기능들도 gui 로 쉽게쉽게가능
그리고 무엇보다 가볍다
-
얘는 현재까지 핫딜이 들어오면 HotDealUpdated 라는 event 를 중계해주는 역할만 하고잇는데, 아마 형태소분석을 돌린다든가 데이터엔지니어링을 한다든가 그런 추가적인 과정이 들어가면 처리하는 이벤트도 많아질것으로 예상
캐싱레이어가 뻗엇을때를 대비해서 캐시갱신도 장기적으로 이벤트로하는걸 고려중림
물론 하나의 트랜잭션을 과한수준으로 이벤트로 쪼개는건 무조건 지양할 예정임... 피본사례들을 너무많이 알고잇음
알림시스템 부분임
일단 HotDealUpdated event 를 consume 하고, 그 안에 이제 키워드가 잇는지를 검사하는 과정을 거치는 worker 가 돌고, 키워드가 잇는경우 해당키워드 구독자에게 알림을 발송하는 job 을 만들어 job queue 로 던지고, job queue 를 구독하는 쪽에서 job 을 소화함
db 에 쿼리를 또날릴순없으니 redis 에서 모든 key 를 가져오고, hget 으로 불러와서 파싱한것을 활용함
-
여기서 고민한포인트는 보내야하는 알림이 너무나도 많아지는 상황임, 물론 근들갑이지만 오면재밋을거같음
일단은 알림 job 을 만들어주는 애를 multithread 로 돌리는방법을 생각해봣고, 알림 job 을 소화하는 애를 여러개의 봇을 만들고 여러개의 job queue 를 두어서 여러개의 인스턴스에서 보내게 하려고 함
왜 굳이 인스턴스 여러개를 쓸 생각이냐고 묻는다면, 디코가 ip 기준으로 rate limit 을 걸어서 어쩔수없이 이렇게 해야함
-
그리고 기존 핫딜 목록들을 채널에 쏴주던건, 디코 인프라를 써서 내 채널을 구독하는 사람들이 자기 디코서버에 땡겨갈수잇는 구조로 바꿈
근데 이 api rate limiting 이 좀 빡빡해서, 이걸 또 고려해서 써야할듯...
-
만약 redis connection 이 죽으면 db 로 transaction 날려서 땡겨온다음 그 값으로 failover 할수잇게 코드도 작성
* 이 부분에서 cache consistency 에 대한 고민을 아주아주 많이함
-
job queue 는 bullmq 를 사용함
delay 나 rate limiting 등의 인터페이스가 직관적이어서 좋음
---
이런저런일들로 지지부진하다가 원하던 기능동작까지 완성해봄
---
이제 grafana, loki, promtail 로 모니터링 인프라 꾸리고 로그 찍고 아는사람들에게 베타테스트를 부탁할예정임
써봣는데 elk 나 efk 보다 설정하는게 훨편하더라
그 시스템으로 얻어지는 지표랑 로그를통해 시스템을 페이즈를 두고 개선해나갈 생각
테스트도... unit testing 만 필요한 기능에 한해서 하고잇는데 argo 같은거로 배포할때 테스트코드 믿고할수잇을정도로 커버하는게 다음목표임
배포도 docker-compose 로 햇는데, k8s 는 무료인스턴스라 불가능에 가깝다고 쳐도 k3s 같은 arm/엣지머신용으로 좀 뗌빵쳐서 해보고싶고... 뭐 그럼
scale out 도 어려운문제고... 하여튼 그럼
공개로 돌리게 되면 이런저런글들이랑같이 홍보하러올게
---
언어는 ts 5.1, runtime 은 node.js LTS 로 작업햇고
흙수저라 공짜인스턴스에 docker-compose 써서 컨테이너로 꾸역꾸역밀어넣어서 HA 구성은 못햇다
그림은 뭘로 그려?
miro 사용함
다 미로임??
ㅇㅇ 다 miro
요금 얼마나옴?
전부공짜임
Redis, mq등등 전부 한 인스턴스에 띄운거임?
그렇지
url shorten도 글좀. 가상면접사례 책에 있는게 전부인가? 트위터가만든id쓰기 싫은데, 6~11글자 사이의 random id 생성은 뭐가 베스트라 보냐
0. 사실 그거도 나중엔 할예정임. url shortner 만들어놓으면 이거저고 확장할수잇는게 많으니깐. 구현은 너가말한 alex xh system design interview 책 2nd 기준에 나와잇는거, 그리고 각종 기술블로그보고 뗌빵질하는식으로 무식하게 구현할듯?
혹시 이거관련 아는 링크(블로그 사이트 etc)있으면 추천좀. 오픈소스 몇개찾아봐도 a-zA-Z0-9 랜덤돌리고 db에서 확인하는식이던데 더 좋은방법찾고싶음. 걍 nanoid 쓰는 이런거말고
1. snowflake 정도면 좋지않나? 나는 어떻게 만들어졋나 봣는데 분산시스템 스케일에 써도 될정도로 나쁘진 않아보이던데, uuid 최신버전들도 많이발전햇으니 확인해봐도 나쁘지않아보임
https://youtube.com/shorts/AbaqosbnRrc?feature=share
나는 1판만 본 상태고, 2판에 진짜 그 시스템 디자인하고 운용한 사람들이 적은 노하우까지 확인해볼 예정임 그거로도 안되면 bitly 같은 url shortner 애들 블로그나 좀 찾아보려고함
우왕 재밌다. 이거 나도 한번 해봐야지. 근데 젠부 js로 짰어요?
네 ts 로 짯어요 다음엔 다른언어를 써볼예정 Go 라든가
이유가있나요?
써보고싶은 언어 / 가고싶은 회사에서 주력으로 사용하는 언어 / 컨테이너 및 클라우드쪽이랑 많이 엮여잇는 언어 / 성능이 나쁘지 않은언어 이유는 이렇게 네개정도입니다
와 블로그하면 굉장히 잘 하겠다 다이어그램 너무 잘 만들었네 나도 너처럼 할 수 있으면 좋겠어
고마워 도구가좋아져서 나같은사람도 괜찮게표현할수잇더라고