Spring Cloud with Apache Kafka - 3

최혜성·2024년 1월 17일
0

msa

목록 보기
5/7

For What?

이왕 MSA 처음 구성해보는 김에 주제를 정할려고 한다.
대용량의 트래픽 발생하는 서비스가 뭐가 있을까 생각했더니 티켓팅이 생각났다.

사이드 프로젝트 수준으로 하기엔 너무 크고 그냥 개인적으로 공부 용도로 최대한 간단하게 설계하고자 한다.

Entity - API

  • User
  • Owner
  • Event
  • Reservation

유저는 행사를 예약 하는사람 Owner는 행사를 주최하는 사람
Event는 행사
Reservation은 유저가 예약한 행사 정보이다.

Event는 대충 각 Seat가 있고, Seat가 꽉 찰경우 예약할 수 없다.
Seat는 시트의 정보 (좌석번호, 등급, 가격...)이 있다.
Reservation은 유저와 시트가 매핑된다
Owner는 Event 리스트를 가진다.

대충 이런 느낌으로 갈려고 한다. (추후 좀더 체계적으로 하고싶으면 ERD까지 그리기로)

유저들은 이벤트가 열린순간 Reservation을 요청한다. 이때 각 Reservation은 2~3ms씩 지연을 걸 예정이고, 총 유저는 1만명, 자리는 2천석정도를 넣어보고자 한다.

이때, 1만명의 유저가 동시에 요청했을때 response는 어떻게 될지 확인하고자 한다.

갑자기 드는 생각

2번 포스트에서 언급했다 시피 OpenFeign과 Kafka를 사용하기로 했는데, 만약 Reservation을 요청할때 Seat의 갱신은 Kafka를 사용하고, 남은 Seat를 보는 방식은 Feign을 사용하면, 어떤게 먼저 이루어지는지 알 수 없다. kafka는 즉시 이루어지는게 아니니까..

음...

그러면 Seat 갱신시 Event 서버 말고도 Reservation 서버내에 모두 전달해서 갱신될 수 있도록 하면 되지 않을까? 여기서도 체크하고 Reservation에서도 체크하고, 다 체크하면 어디에는 걸리지 않을까??? :)

-> 실질적으로 Reservation에서만 핸들링 하면 굳이 Event까지 갈 필요 없고, Reserve간 Kafka등으로 공유하면 될듯? 아니면 어처피 같은 DB니까 안에서 잘 핸들링하고

Setup

https://velog.io/@haerong22/Spring-Cloud-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-MSA-2.-Spring-Cloud-Eureka
참조하여 setup 진행하였음

eureka.client.register-with-eureka=false

eureka 여러개 구성시 서로 통신이 가능. 나는 한개만 쓰니까 false

eureka.client.fetch-registry=false

registry에서 다른 api를 불러올 수 있는 방식. 단 '클라이언트'의 입장으로써 작동하는것이므로 현재 서버로 구성하고 있는 상황이라 false로 설정


127.0.0.1:8761/ 접속시 잘 뜨는 모습

Multi-Module

원래는 각 Api별로 Project 하나씩 만들려고 했는데, 그렇게 하면 프로젝트가 4~5개가 생성되고 창도 그만큼 띄워야 할것 같아서 한 프로젝트에서 각 모듈을 관리할 수 있는 멀티 모듈을 적용하고자 한다.
https://velog.io/@haerong22/IntelliJ-%EB%A9%80%ED%8B%B0-%EB%AA%A8%EB%93%88-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0

https://junuuu.tistory.com/627
위 두 링크를 참조하였음

정상적으로 Client또한 등록된 모습

멀티모듈로 지정했더니 공유하는 라이브러리는 메인 라이브러리에 적어 깔끔하게 유지할 수 있는게 좋았지만, 설정이 너무 복잡했다.

각 모듈이 필요한 라이브러리는 각 모듈의 build.gradle에 작성하면 됨.

Error

  • Eureka setup시 버젼 적어줘야함..
  • dependency management에 cloud 관련해서 넣어줘야함
  • Servlet버전이 낮아서 그런가 javax.servlet-api 추가해줘야 했음
  • 멀티 모듈 작업하다 apply false 해놨더니 dependencyManagement 미작동
  • properties에 list를 받는데 [0][1]이런거 없이 넣었더니 String replace error..
  • 여러가지 삽질 등등..

Route

오늘은 1일차니까 여기까지 하기

API Gateway라는 개념이 있다. 네이버 클로바 API 쓸때도 이게 뭔가 싶었는데 지금 봐도 이게 뭔가 싶다.

요청받은 API 주소를 쪼개서 /api/user면 User-API 서비스, /api/event면 event-api 서비스 호출하는 방식으로 이해하면 되겠다. 그냥 MSA를 모놀리식처럼 느껴지게 하는듯. 라우팅은 위 Eureka보고 '해줘' 하면 유레카가 넘겨주는듯.

  • GlobalFilter를 이용하여 Servlet Filterling 하는 느낌인듯
class GlobalFilter : AbstractGatewayFilterFactory<GlobalFilter.Config>() {

    val log = logger()

    //Config는 properties의 arg에 매핑
    inner class Config(val message : String)

    override fun apply(config: Config?): GatewayFilter {
        return GatewayFilter { exchange, chain ->
            val request = exchange.request
            val response = exchange.response
            log.info("{}", config?.message)
            log.info("Global Filter Accepts request. id : {} uri : {}", request.id, request.uri)

            chain.filter(exchange).then(Mono.fromRunnable {
                log.info("Global Filter Respose code : {}", response.statusCode)
            })
        }
    }
}

GlobalFilter를 작성할때 Mono를 리턴하는걸 볼 수 있는데, 이 Mono는 WebFlux에서 사용됐던걸로 알고 있음
-> WebFlux는 Netty위에서 돌아가고.. 그래서 GateWay가 Netty로 작동한다고 한듯
Mono의 fromRunnable로 Mono를 감싸고 (아직 실행 안됨) then으로 filter가 적용된 이후 Wrapping된 Mono를 실행함.

Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.

그래서 실행할때 MVC랑 호환안된다고 오류 뱉음 :(
Netty랑 Tomcat은 서로 안맞는 관계

-> 코틀린의 coroutine이 Mono Convert 지원을 한다고 했던거 같은데 suspend로 구현할 수 있지 않을까 싶다.

val result = chain.filter(exchange)
log.info(result.statusCode)
result

요런식으로 바꿔지지 않을까 싶음. 근데 Mono Coverting은 어노테이션 매핑된 컨트롤러 수준부터 인식할텐데 얘는 어노테이션으로 붙이는게 아니라 Bean으로 정의해서 몰?루

끝..?

Original Stack Trace:
Caused by: java.net.ConnectException: Connection refused: no further information

분명 이상없게 잘 구성했는데 왜 자꾸 마크에서 볼 법한 refused가 뜨는지 머리가 아팠는데

https://velog.io/@vector13/MSA%EC%8A%A4%ED%84%B0%EB%94%94-5.-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%8F%84%EA%B5%AC-%EB%8B%A4%EB%A3%A8%EA%B8%B0
Eureka가 서비스들을 가져오는데 30초 정도 걸리니까 그 사이에 요청하면 그럴 수 있다.

분명 위에서도 30초마다 정보 주고 받는다고 했는데도 이를 생각하지 못한게 아쉬웠다.

Next

오늘 실수했던 부분 다시 한번 분석하고 지웠던 부분 복구하기

profile
KRW 채굴기

0개의 댓글