-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seminar2 #4
Open
paragon0107
wants to merge
27
commits into
main
Choose a base branch
from
seminar2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Seminar2 #4
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
한줄일기
명세서
구현사항
고민사항
구현할 때 Reposioty에 adapter 역할을 하는 Finder, Saver, Deleter를 추가했습니다. 해당 어뎁터를 추가한 이유는 클래스별 책일을 확실하게 하기 위해서 입니다.
Service단은 프로그램의 서비스적인 로직이 들어와야 한다고 생각했습니다. 그래서 Repository로 부터 얻은 엔티티들의 상호작용이 Service단에 와야 한다고 생각을 했고 서비스적인 로직이 아닌 데이터의 정책적인 부분은 따로 어뎁터를 만들어서 빼주었습니다.
Adpater에 속하는 Finder, Saver, Deleter는 데이터들이 Repository에서 제어하기 힘든 정책적인 부분을 책임지고 있습니다. 예를 들어 일기 생성시 중복되는 Title이 존재해서는 안된다거나, 목록 조회시 10개 이하로 가져와야 하는 등의 데이터의 정책을 담당하고 있는 부분입니다.
Repository는 단순 CRUD를 하는 책임을 가집니다.
일기 작성 기능
mingyu.shin/src/main/java/org/example/diary/service/DiaryService.java
Lines 29 to 37 in 45e53c6
Controller단에서부터 받은 DTO를 분해시켜 Saver로 넘겨주었습니다. 엔티티의 정잭적인 부분을 담장하고 있는 Saver의 경우 DTO에 대한 불필요한 의존성을 가질 필요가 없을것 같아 Service단에서 DTO를 분해하여 넘겨주었습니다.
mingyu.shin/src/main/java/org/example/diary/repository/adapter/DiarySaver.java
Lines 20 to 26 in 45e53c6
Service단으로부터 전달받은 Entity의 Title이 존재하는지 Finder를 통해 확인 후 있으면 예외를 발생 시키고 없다면 Repository를 통해 저장하는 구조를 가집니다.
일기 목록 조회 기능
mingyu.shin/src/main/java/org/example/diary/service/DiaryService.java
Lines 50 to 52 in 45e53c6
서비스단에선 단순하게 Finder 메서드만 호출합니다
mingyu.shin/src/main/java/org/example/diary/repository/adapter/DiaryFinder.java
Lines 21 to 34 in 45e53c6
repository단으로 부터 받아온 리스트를 정해진 정책에 맞게 제어합니다.
반한될 리스트의 길이는 10을 넘지 않으며 같은 글자 수가 있다면 개수를 초과할 수 있도록 구현했습니다.
구현 방식은 리스트 가장 마지막 엔티티의 Body Length와 추가할 엔티티의 BodyLength 길이가 동일하다면 계속해서 추가 하는 형식으로 구현했습니다.
mingyu.shin/src/main/java/org/example/diary/repository/DiaryRepository.java
Lines 15 to 16 in 45e53c6
리스트 조회는 sql을 활용해서 엔티티의 Body Length를 기준으로 오름차순으로 정렬하여 전달했습니다.
일기 상세 조회 기능
mingyu.shin/src/main/java/org/example/diary/service/DiaryService.java
Lines 39 to 48 in 45e53c6
Finder에 메서드를 호출하여 엔티티를 찾습니다. 성공적으로 찾은 경우 서비스단에서 DTO를 만들어 컨트롤러 단으로 전달합니다. Finder의 결과를 바로 Controller로 넘겨주지 않고 Service단에서 DTO로 만들어서 넘긴 이유는 Finder의 결과에 우리가 원하지 않는 정보가 있을 경우 그 정보를 Controller에서 접근하지 못하게 하기 위함입니다.
mingyu.shin/src/main/java/org/example/diary/repository/adapter/DiaryFinder.java
Lines 40 to 46 in 45e53c6
Finder에서는 전달 받은 id가 존재하는지 확인후 있으면 반환 없으면 예외를 발생시킵니다.
일기 카테고리 별 조회 기능
mingyu.shin/src/main/java/org/example/diary/service/DiaryService.java
Lines 54 to 56 in 45e53c6
서비스단에서는 목록조회와 동일하게 Finder의 메서드만 호출합니다.
mingyu.shin/src/main/java/org/example/diary/repository/adapter/DiaryFinder.java
Lines 36 to 38 in 45e53c6
repository에 JPA커맨드를 활용하여 카테고리별로 조회하여 전달합니다. 카테고리 별 조회에는 별다른 정책이 존재하지 않아 단순하게 구현했습니다.
일기 수정 기능
mingyu.shin/src/main/java/org/example/diary/service/DiaryService.java
Lines 58 to 60 in 45e53c6
마찬가지로 업데이트 기능은 "해당 아이디를 갖고 있는 엔티티가 존재한다"라는 가정이 성립해야 업데이트가 가능하기 때문에 이 부분이 서비스 로직보다는 데이터 조작을 성공적으로 마치기 위한 정책적인 부분이라 판단하여 Adapter에 책임을 맡겼습니다.
mingyu.shin/src/main/java/org/example/diary/repository/adapter/DiarySaver.java
Lines 28 to 33 in 45e53c6
FInder의 메서드를 통해 해당 아이디를 가진 엔티티가 존재하는지 확인후 Body를 업데이트 하여 저장했습니다.
일기 제거 기능
mingyu.shin/src/main/java/org/example/diary/service/DiaryService.java
Lines 62 to 65 in 45e53c6
업데이트와 마찬가지로 핵심 로직을 Adapter에 두었습니다.
mingyu.shin/src/main/java/org/example/diary/repository/adapter/DiaryDeleter.java
Lines 18 to 21 in 45e53c6
업데이트와 마찬가지로 FInder메서드를 통해 존재하는지 확인후 제거를 진행했습니다.
필수 과제
Switch?
L4 스위치
L4스위치란
OSI 7레이어중 레이어4인 전송계층에서 동작하는 스위치로 Port를 이용하여 들어오는 전송 계층 정보를 기반으로 한 패킷 처리 혹은 로드밸런싱등을 처리하는 장비입니다.
TCP/UDP
L4스위치는 패킷의 헤더를 분석하여 TCP/UDP port 정보를 이용하여 송 수신자간 논리적 연경을 생성 및 제어합니다.
클라이언트와 서버가 3-way-handshake 과정을 통해 Connection을 생성하면 L4스위치 또한 이 Connection을 생성하여 관리합니다.
L4스위치는 Connection time out값을 갖는데 일정 시간동안 사용되지 않는 Connection을 삭제하고 클라이언트와 서버측에 필요시 Connection을 다시 맺도록 Reset 패킷을 전송합니다.
로드 밸런싱
L4 스위치에서 가장 많이 사용되는 기능은 로드밸런싱입니다.
한개의 서버가 있다고 가정했을때 서버의 이용자 수가 증가하면서 서버를 하나 증설했다고 가정합니다. 이때 이 두개의 서버에 적절하게 사용자들의 분배되기 위해선 사용자가 서로 다른 아이피로 접속을 해야합니다.
예를 들어보면 기존 서버는 123.123.123.111 을 가지고 있었고 사용자는 이 아아피 주소로 서버에 접속을 합니다. 이 상황에서 유저수가 증가하여 123.123.123.112주소를 갖고있는 서버를 한대 증설했다고 하면 사용자들에게 123.123.123.111 혹은 123.123.123.112로 접속을 해달라고 해야한다. 이상황에서는 큰 문제가 아닐 수 있지만 서버가 늘어남에 따라 주소 목록을 알려줘야 한다.
위 같은 상황을 방지하기 위해 L4스위치를 둔다. 그리고 유저들에게 L4스위치의 public주소를 알려주고 서버들은 private 주소로 스위치에 연결한다. 그러면 유저들은 서버가 증설되어도 똑같이 L4스위치의 주소로 접속을 하고 L4스위치는 상황에 맞게 서로 다른 서버들로 패킷을 전송하여 서버들의 부하량을 관리할 수 있다.
Port
서버는 다양한 서비스를 제공합니다. 그 서비스를 구분해주는 것이 바로 포트입니다.
위에서 언급한 상황을 살펴보면 우리는 서버로 접속하기 위해서 L4스위치를 거쳐야 합니다. 포트가 없는 상황은 L4스위치에 존재하는 모든 문이 열린상황과 같습니다. 어떤 서비스든 주소를 안다면 L4스위치를 통해 서버를 접속할 수 있습니다. 하지만 우리가 포트를 사용하게 된다면 서버에서 사용자에게 제공해주는 서비스만 문을 열 수 있게 할 수 있습니다.
예를 들어 서버에서 80포트에 해당하는 서비스만 제공한다면 L4스위치는 80포트에 해당하는 문만 열어놓고 다른 문을 닫아놓는 식으로 제어할 수 있습니다.
추가적으로
이외에도 L4스위치는 패킷의 송수신을 모니터링 하고 필요에 따라 트래픽을 제어합니다.
트래픽 패턴을 분석하여 QoS정책을 적용하여 트래픽의 흐름을 제어하거나 특정 IP주소 혹은 포트로의 접근 제어등이 가능합니다.
L7스위치
L7스위치란
L7 스위치는 L4스위치와 마찬가지로 로드밸런싱하는 역할을 담당합니다. L7에서는 패킷의 내용에 해당하는 URL, 캐시, 쿠키등을 분석해 요청을 분배합니다. 또한 애플리케이션 수준에서 보안 기능을 제공해 줄 수도 있습니다. 웹 애플리케이션 방화벽(WAF) 기능을 포함해서 악성 요청을 필터링하거나 인증 및 접근 제어를 수행하여 보안을 강화할 수 있습니다. 즉 더 세밀한 고급 로드밸런싱이 가능해집니다.
예를 들면 /images 로 온 패킷의 경우 이미지 서버로 /api 로 온 경우 api로 보내준다거나, 패킷의 콘텐츠 유형에 따라서 비디오는 미디어 서로 텍스트 콘텐츠는 웹서버로 이런식으로 세부적인 트래픽 분산을 담당하고 있습니다.
또한 캐싱, 압축등 트래픽 최적화 기능을 제공하여 서버 부하를 줄이고 대역폭을 절약하며 서버의 성능을 향상시킬 수 있습니다.
L4스위치의 존재 이유
그러면 이런 L7스위치가 존재한다면 L4스위치의 존재 이유에 대해 궁금증이 생길 수 있습니다.
L7스위치는 때에 따라 많은 기능을 수행하게 되는데 단순하게 포트 정보만을 사용하여 로드 밸런싱이 가능한데 굳이 L7의 더 많은 정보들을 해석하며 자원을 낭비할 필요가 없기 때문입니다.
What is Restful?
REST(Representational State Transfer)의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미합니다.
즉 REST란
HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고,
HTTP Method(POST, GET, PUT, DELETE, PATCH 등)를 통해
해당 자원(URI)에 대한 CRUD Operation을 적용하는 것을 의미합니다.
위가 REST에 대한 정의입니다.
저 정의를 따라 url을 보는 사용자 즉 , 클라이언트 개발자가 url를 보고 어떤 일을 하는지 쉽게 짐작할 수 있게 하는 것이 RSST FUL한 API라 생각합니다
이런 RESTFUL함을 정의 해 놓는 이유가 url를 네이밍하는 프로토콜을 만들어 처음 보는 사용자도 url 네이밍 프로토콜에 따라 쉽게 기능을 추측할 수 있게 위함이라고 생각합니다.
따라서 가장 중요한건 네이밍을 할 때 일관성이 있어야 한다고 생각합니다. 그래야 제 3자가 패턴을 파악하고 어떤 기능을 하는지 쉽게 추측할 수 있기 때문입니다. 일관성을 주지 않는다면 url을 보는 클라이언트에게 혼돈을 줄 거라 생각합니다.
또한 클라이언트는 세부동작에 대해 몰라도 되고 원인과 결과에 대해서만 알면 되기 때문에 자세한 동작을 네이밍에 집어 넣기 보다는 큰 범주에서 어떤 역할을 하는지 명료하게 쓰는 것이 중요하다고 생각합니다. 따라서 복잡한 동사를 사용하는 것이 아니라 단순하게 CRUD에 대한 것만 URL에 나타내 주는 것이 클라이언트가 보다 직관적으로 기능을 파악하는데 도움이 될 거라 생각합니다.