no image
sql JOIN(Inner, Outer, Cross, Self)
Inner Join 교차 부분만 추출한다. ( NULL이 없다. ) Outer Join Left Outer Join - 왼쪽 테이블 기준으로 추출한다. JOIN 조건과 무관하게 왼쪽 데이터가 모두 보이는 결과이다. - JOIN 조건(on)에 맞지 않은 부분은 NULL 로 구성된다. Right Outer Join - 오른쪽 테이블 기준으로 추출한다. JOIN 조건과 무관하게 오른쪽 데이터가 모두 보이는 결과이다. - JOIN 조건(on)에 맞지 않은 부분은 NULL 로 구성된다. Full Outer Join - 양쪽의 모든 데이터를 추출한다. JOIN 조건과 무관하게 양쪽 데이터가 모두 보이는 결과이다. - 데이터 조합을 추출하는건 아니다. ( JOIN 조건이 있다. ) - JOIN 조건(on)에 맞지 않..
2023.09.06
no image
HTTP 메서드 GET/POST 차이
HTTP GET/POST 차이 이 질문에 대한 대답은 "언제 어떤 메서드를 사용한다." 가 주대답이고 GET/POST 동작의 차이가 부가적인 대답같다. 언제 어떤 메서드를? 우리는 보통 API를 설계할 때 서버의 상태를 변화시키지 않고 정보를 조회하는 성격의 요청은 GET을 사용하고 서버의 상태를 변화시키는 요청이라면 POST, DELETE, PUT, PATCH 등 적절한 메서드를 사용한다. 동작 차이 GET query string을 통해 데이터를 전송하고 길이에 제한이 있고 URL에 노출된다. 브라우저 히스토리에 기록이 남고 서버 설정에 따라 캐싱이 가능하다. (캐싱이 가능하려면 당연히 브라우저 어딘가 기록이 있을 것이다.) POST body를 통해 데이터를 전송하고 데이터 크기에 제한은 없다. URL..
2023.09.06
Web
no image
java factory method pattern
Factory Method Product 객체를 직접 생성하지 않고 Factory 클래스에서 Product를 만든다. 여러 Product 구현체가 있고 그 Product 를 만드는 Factory 구현체가 있다. 각각의 Factory 구현체가 그에 해당하는 Product 객체 생성의 책임을 가지고 있다. 객체 생성에 필요한 과정과 메서드를 템플릿 처럼 구성해놓고 과정과 메서드의 내부 동작은 Product 구현체와 Factory 구현체에서 유연하게 만들 수 있다. 장점 생성자와 구현 객체의 강한 결합을 피할 수 있다. 팩토리 메서드를 통해 객체 생성 후 공통으로 할 일을 수행하도록 지정할 수 있다. 캡슐화, 추상화를 통해 생성되는 객체의 구체적인 타입을 감출 수 있다. SRP(Single Responsibi..
2023.09.06
no image
kafka-spring Producer key에 따른 partition 배정
카프카 producer key CompletableFuture future = kafkaTemplate.send(MSG_TOPIC, key, msg.getMsg()); future.whenComplete((result, ex) -> { System.out.println("future : " + result.getProducerRecord().value()); }); producer에 key가 있을 수도 있고 없을 수도 있다. 있다면 그 key로 해시값을 만들어 동일한 key라면 동일한 partition에 메세지를 전송할 수 있고 없으면 메세지를 라운드로빈으로 적절히 파티션들에 분산시키는 듯 하다. Consumer partition @Bean public NewTopic messageTopic() { re..
2023.09.03
docker bitnami/kafka 주키퍼없이(KRaft)
KRaft 모드 카프카에 대해 조사를 해보면 카프카의 메타 데이터, 브로커 상태, 토픽 상태 등을 관리하기 위해 주키퍼를 사용하는 것을 볼 수 있다. 그런데 docker kafka 이미지들을 보면 zookeeper 없이 구성된 docker-compose를 볼 수 있는데 카프카의 최근 버전에서는 주키퍼 없이 카프카를 사용할 수 있는 구조를 지향한다고 한다. 그래서 주키퍼없이 자체적으로 메타데이터를 관리하기 위해 만들어진 것이 KRaft 모드이고 QUORUM 컨트롤러는 KRaft 와 관련된 키워드이다. bitnami/kafka services: kafka: image: bitnami/kafka:latest ports: - '9092:9092' environment: # KRaft settings - KAFK..
2023.09.02
spring kafka - @KafkaListener Annotation
@KafkaListener Annotation 많은 consumer의 방법 중 하나이다. @KafkaListener(id = "foo", topics = MSG_TOPIC, clientIdPrefix = "myClientId") public void listen(String data) { System.out.println(data); } 사용 방법은 다음과 같다. id는 GROUP_ID_CONFIG 와 같다. 그래서 kafkaListener에서 지정하면 consumerConfig에서 group id 설정을 빼야한다. [Consumer clientId=myClientId-0, groupId=foo] [Consumer clientId=myClientId-1, groupId=foo] [Consumer clie..
2023.09.02
no image
docker-compose nginx load-balancing (spring, node, ws)
nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log..
2023.08.28
no image
Message service 아키텍처
Message service 아키텍처 현재 현재 구조에서 트래픽이 많아질 때 문제를 생각해보면 다음과 같다. 1. socket 연결의 리소스 점유와 많은 트래픽으로 pub/sub 속도가 느려진다. 2. pub/sub 속도는 충분하지만 db처리가 느리다. 서버를 늘린다면? 그럼 채널 기준으로 서버를 늘리면 될까? 채널 수와 그에 따른 socket 연결의 리소스는 해결되지만 특정 몇몇 채널에서 엄청난 볼륨의 메세지가 트래픽의 주요 원인이라면 해결되지 않는다. 결론 그래서 채널을 기준으로 나누지 않고 사람을 기준으로 라운드 로빈으로 로드 밸런싱하는 접근을 생각해본다. 이 구조에선 어떤 유저가 어떤 pub/sub을 바라볼지 모른다. 그래서 특정 서버의 pub은 모든 서버의 pub으로 전파되어야 한다. 그 전파의..
2023.08.27
no image
최적화 관련 useRecoilState, useState
문제 Message 하나를 우클릭해서 contextMenu 열고 닫을 때 마다 모든 Message 가 재실행된다. //Chat.tsx const [menuState, setMenuState] = useRecoilState(contextMenuState); ... return ( {user.sub !== "0" && {menuState.show && } } ) Chat 컴포넌트 구성은 다음과 같고 Messages 안에는 Message 컴포넌트가 있다. //Message.tsx const [menuState, setMenuState] = useRecoilState(contextMenuState); ... const msgPContextHandler = (e: React.MouseEvent) => { e.pr..
2023.08.25