Skip to content

2주차 금요일 그룹 1

김수현 edited this page Jul 5, 2024 · 1 revision

박혜성

학습이 필요한 부분

  • LinkedBlockingQueue에 대해서
    • 싱크, 바운드라는 키워드에 대해서 공부해볼 것

고민해볼 부분

  • 매핑되는 자원이 없을때 IllegalArgument 대신 NoSuchElement 예외를 던져서 사용자에게 404를 줄 수 있도록 하는 편이 더 좋을 것 같다.
  • 소켓을 열고 요청을 파싱하고 응답을 만드는 부분과 사용자 요청을 처리하는 부분을 명확히 나눠서 구조를 만드신 분이 많다. 이 부분을 개선해볼 점으로 잡아보자.

김현수

[신경 쓴 것]

  • router hanlder 구조로 만들었다.
  • ServerSocket 동작 원리

[고민해볼 것]

  • handler method 시그니처로 전달할 때 나중에 db 붙이면 어떻게 할 것인가
  • BufferedStream 을 이용하면 커널을 덜 접근하나???

김수현

  • 구조가 복잡한만큼 다른 분들처럼 그림으로 구조를 표현했으면 더 이해를 도울 수 있지 않았을까.
  • spring 프레임워크밖에 알지 못해서 그 구조를 많이 따라서 했는데, 다른 프레임워크를 사용한 코드를 보니 간편한게 큰 장점인것 같다. 어플리케이션의 사이즈에 따라서 한 눈에 파악이 가능한 심플한 프레임워크를 사용하는 것도 좋은 방법인 것 같다.
  • 지금 내가 설계한 것은 너무 미리 복잡하게 구조를 꼬아서 요구사항에 비해 너무 무거운 것 같다.
  • 서버를 실행하고 통합테스트 해보는 코드를 작성해보기.
  • response가 outputstream만 가지고 있을때의 장점?
    • response 객체 필드 body에 전체 파일을 가지고 있는게 있으면 메모리 낭비가 발생할 수 있다고 생각했음. file inputstream을 버퍼 크기만큼 바로 Outputstream에 작성해주고 싶어서
    • response가 필드 값을 가지도록 수정하는 게 request 객체와의 일관성, 필드별 값 세팅 가능하도록 해서 유연해질 것 같다. 다만, 일부 필드만 초기화되어서 http 응답 메시지 프로토콜을 어기는 경우가 없도록 체크가 추가적으로 필요할 것 같다.
  • outputstream에 flush()를 호출하는데 왜 Outputstream.flush() 구현부가 비어있는데 왜 호출하는가? BufferedOutputStream의 경우 flush() 호출해서 버퍼에 남아있는 값을 밀어내야함

최현식

  • ThreadPool을 아무 생각없이 fixedPool을 생성해서 사용했는데, 각 설정값이 무엇이있고 이를 살펴봐야 될 것 같습니다. 특히 KeppAlive가 필요한 이유에 대해 고민할 필요가 있을 것 같은데, 자바 NativeThread가 OS 스레드와 1:1로 매칭되어서 그럴 것 같다는 이유가 합리적이였습니다. 하지만 자바 뿐만 아니라 다른 스레드풀에서도 유사한 방식을 채택한 것으로 아는데 더 자세히 찾아봐야겠습니다!
  • 직접 싱글스레드로 서버를 열어서 통합테스트를 할 수 있다는 것을 보고 저도 적용해봐야겠다고 생각했습니다. 지금은 테스트 가능할 것 같은 클래스들만 한정적으로 단위테스트를 진행하고 있는데 적용해봐야겠습니다^^
  • 정적 자원을 불러올 때, 실행주체가 jar인지 여부를 구분하고 path를 다르게 설정하는 방법으로 static 파일을 읽어올 수 있다는 것을 보았습니다. 저도 바로 classLoader를 기준으로 파일을 읽어오기보다는 이러한 방법들을 생각해봐도 좋지 않았을까~ 문제를 만났을 때 혼자 생각을 조금 해보는 시간을 가져봐야겠습니다.!
  • 쓰레드를 활용할 때, addShutdownHook과 Thread.isInterrupted를 활용해서 예외상황들에 대처하는 것이 안정적인 서비스를 만드는데 도움이 될 것 같습니다.
  • 각 예외를 정의하고 이를 상위에서 catch하는 방식으로 예외를 처리하면 더 간편하고 명료할 것 같습니다..! 현재는 예외처리 로직이 여기저기 산개되어있고, 모든 케이스들을 전부 커버하는 것인지 알기가 힘들기 때문에 이러한 구조로 수정하면 좋을 것 같다고 생각했습니다.
  • Interface와 Abstract 활용에 대해 조금 더 찾아봐야겠다는 생각이 들었습니다. 저는 대부분의 상황에서 Interface 사용을 선호하면서 Abstract를 사용할 상황이 언제인지는 생각하지 않고 있던 것 같습니다~

김준기

학습 필요한 부분

  • SyncQueue → acceptQueue → ThreadPool
  • keepAlive Time → 스레드풀인데 왜 죽이지? → OS에서 생성할 수 있는 개수가 제한되어 있으니까인듯?

리뷰 받은 부분

  • 중복된 코드 (HTTP Header Must Have Setting) → HttpResponse 에 상태를 넘겨서 처리하도록 하면 개선할 수 있지 않을까? → 수현님 Response 구조 한 번 살펴볼 것
  • 매 번 실행할 때마다 new HttpProcessor 만드는게 낭비아닐까? → 스레드 풀 개수만큼 리스트에 캐싱해서 쓴다면?
  • Header에 들어가야할 내용이 Body에 들어가있음

인상 깊었던 부분

  • JIoEndpoint → BIO EndPoint 느낌
  • Acceptor → Server Socket Listen 용 클래스 (싱글 스레드)
    • 나중에 부하가 복잡해질 때, 도움이 될 수 있을듯
  • BufferedOutputStream → flush()

고민하고 있는 부분

  • 확장성 있는 설계에 대한 기준이 있는지?
    • 현수님: 좋은 래퍼런스를 참고하고 있는 지금 과정이 도움 되지 않을까? 단위 테스트에 대해 고민하다보면 응집성이 올라가다보니 설계에 좋지 않을까?

이지표

추상화의 기준

노출되는 부분을 최대한 줄이기 위해 최소한의 메서드만 인터페이스로 분리하였다. 구현체에서 공통적으로 필요한 메서드들은 추상 클래스를 만들어 구현했다. 실제 사용하는 곳에서는 인터페이스에만 의존하여 결합도를 낮추고, 응집도를 높였다.

OutputStream과 BufferedOutputStream

OutputStream을 사용하면 1 byte식 커널에 접근하여 정보를 전송한다고들어 BufferedOutputStream을 사용하는게 성능상 이득이라는 의견을 들었다. 아직까지는 잘 이해가 완전히 안되어서 조금더 공부할 계획이다.

ThreadPool의 keepAlive

Http의 keepAlive만 생각하고 있었는데, Thread Pool인자로 keepAlive를 넘겨주는 것을 알게 되었다. Keep Alive가 지나면 스레드를 죽인다는 의미인데, Thread pool이 탄생한 이유와 상반된 기능이기에 의문이 들었다. 찾아보니 기준 스레드의 수보다 많이 생성될 경우 Keep Alive의 시간이 지나면 스레드를 죽이는 기능이다. 자바의 경우 One to One 매핑이기에 스레드를 죽이는 것이 오히려 더 성능상 좋다는 것을 알았다.

Spring…

Spring만 사용했기에, 다른 언어의 웹 프레임워크를 몰라 Spring의 구조와 비슷하게 만들어졌다. 다른 was나 프레임워크를 참고해보면서 공부해보면 좋을 것 같다!

👼 개인 활동을 기록합시다.

개인 활동 페이지

🧑‍🧑‍🧒‍🧒 그룹 활동을 기록합시다.

그룹 활동 페이지

🎤 미니 세미나

미니 세미나

🤔 기술 블로그 활동

기술 블로그 활동

📚 도서를 추천해주세요

추천 도서 목록

🎸 기타

기타 유용한 학습 링크

Clone this wiki locally