'IT > JAVA' 카테고리의 다른 글
Java Method Signature (0) | 2017.12.08 |
---|---|
VO vs DTO (0) | 2017.01.12 |
String VS SringBuffer VS StringBuilder (0) | 2016.10.14 |
Annotaion (0) | 2016.05.09 |
Java Method Signature (0) | 2017.12.08 |
---|---|
VO vs DTO (0) | 2017.01.12 |
String VS SringBuffer VS StringBuilder (0) | 2016.10.14 |
Annotaion (0) | 2016.05.09 |
어플리케이션의 로직과는 상관없이 공통적인 설정을 변경해서 해결하는 경우
Database 등 외부 Reosurce에서 병목이 있을 때 부적절한 설정 때문에 발생하는 경우가 많음.
- DBCP : maxActive (maxTotal), maxWait (maxWaitMills), validation query
- Apache Httpd : maxClients
- Tomcat: maxThreads, AJP connector의 backlog 값
- 캐쉬 용량의 한도값이 적절한가?
- 모든 서버에 같은 현상이 궁극적으로는 생김.
- 일부 서버에만 OOM 발생
- 부조건 무한루프였으면 개발할때 모를리가 없음.
- iptables -A INPUT -p tcp -i lo -s xxx.xxx.xxx.xxx --sport 1024:65535 -j DROP
- 서버 내에서 include 시에는 lo(Lookback Interface)를 통해 sport 가 1024 이후의 High Port를 이용하여 통신한다는 특성을 이용
- ps aux | grep http로 보이는 프로세스에서 ls -la/proc /pid/로 각각의 http 프로세스가 어떤 파일을 참조하고 있는지 일일이 추적
(예:cwd -> /home/user1/public_html/infinite_loop/)
Thread Dump 분석 (0) | 2018.11.09 |
---|---|
4 steps to troubleshooting (0) | 2018.10.29 |
트러블 슈팅 (0) | 2018.11.09 |
---|---|
4 steps to troubleshooting (0) | 2018.10.29 |
참고
https://blog.naver.com/paninfo/10139797986
https://cdn.hosting.kr/cdn%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94/
http://brainwave.tistory.com/82
https://idchowto.com/?p=16938
http://i5on9i.blogspot.com/2014/05/cdn-proxy-server.html
https://www.kdata.or.kr/info/info_04_view.html?field=&keyword=&type=techreport&page=231&dbnum=127531&mode=detail&type=techreport
DNS 동작원리 (1) | 2018.11.05 |
---|---|
HTTP/1.1 VS HTTP/2 (1) | 2018.11.01 |
Container (0) | 2018.10.29 |
1. 웹 브라우저에 www.naver.com을 입력하면 먼저 Local DNS에게 "www.naver.com"이라는 hostname"에 대한 IP 주소를 질의하여 Local DNS에 없으면 다른 DNS name 서버 정보를 받음(Root DNS 정보 전달 받음)
2. Root DNS 서버에 "www.naver.com" 질의
3. Root DNS 서버로 부터 "com 도메인"을 관리하는 TLD (Top-Level Domain) 이름 서버 정보 전달 받음
4. TLD에 "www.naver.com" 질의
5. TLD에서 "name.com" 관리하는 DNS 정보 전달
6. "naver.com" 도메인을 관리하는 DNS 서버에 "www.naver.com" 호스트네임에 대한 IP 주소 질의
7. Local DNS 서버에게 "응! www.naver.com에 대한 IP 주소는 222.122.195.6 응답
8. Local DNS는 www.naver.com에 대한 IP 주소를 캐싱을 하고 IP 주소 정보 전달
Recursive Query : Local DNS 서버가 여러 DNS 서버를 차례대로 (Root DNS 서버 -> com DNS 서버 -> naver.com DNS 서버) 질의해서 답을 찾아가는 과정
참고
https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_domain_name
https://aws.amazon.com/ko/route53/what-is-dns/
https://www.netmanias.com/ko/post/blog/5353/dns/dns-basic-operation
CDN 동작 원리 (0) | 2018.11.05 |
---|---|
HTTP/1.1 VS HTTP/2 (1) | 2018.11.01 |
Container (0) | 2018.10.29 |
- HTTP/1.1의 connection당 하나의 요청 처리를 개선할 수 있는 기법 중 pipelining이 존재
- Connection을 통해서 다수개의 파일을 요청/응답 받을 수 있는 기법
예 ) 하나의 TCP연결에서 3개의 이미지( a.png, b.png, c.png )를 얻으려고 하는 경우 HTTP의 요청 순서.
| --- a.png --- |
| --- b.png --- |
| --- c.png --- |
순서대로 첫번째 이미지를 요청하고 응답 받고 다음 이미지를 요청하게 되는데 만약 첫번째 이미지를 요청하고 응답이 지연되면 아래 그림과 같이 두, 세번째 이미지는 당연히 첫번째 이미지의 응답 처리가 완료되기 전까지 대기하게 되며 이와 같은 현상을 HTTP의 HOB (Head of Line Blocking) 이라 부르며 pipelining의 큰 문제점 중 하나이다.
| ------------------------------- a.png ------------------ |
| -b.png- |
| --c.png-- |
요즘 브라우저들은 http/1.1이 단점을 극복하기 다수의 Connection을 생성해서 병렬로 요청을 보내기도 한다. 하지만 브라우저 별로 Domain당 Connection개수의 제한이 존재하고 이 또한 http/1.1의 근본 해결책은 아님.
Data URI Scheme은 HTML문서내 이미지 리소스를 Base64로 인코딩된 이미지 데이터로 직접 기술하는 방식이고 이를 통해 요청 수를 줄임.
SPDY는 실제로 HTTP/1.1에 비해 상당한 성능 향상과 효율성을 보여줬고 이는 HTTP/2 초안의 참고 규격이 됨
클라이언트가 요청한 HTML문서 안에 CSS파일 1개와 Image파일 2개가 존재하고 이를 클라이언트가 각각 요청하고 난 후 Image파일보다 CSS파일의 수신이 늦어지는 경우 브라우저의 렌더링이 늦어지는 문제가 발생하는데 HTTP/2의 경우 리소스간 의존관계(우선순위)를 설정하여 이런 문제를 해결
HTTP/2는 Header 정보를 압축하기 위해 Header Table과 Huffman Encoding 기법을 사용하여 처리하는데 이를 HPACK 압축방식이라 부르며 별도의 명세서(RFC 7531)로 관리.
위 그림처럼 클라이언트가 두번의 요청을 보낸다고 가정하면 HTTP/1.x의 경우 두개의 요청 Header에 중복 값이 존재해도 그냥 중복 전송한다. 하지만 HTTP/2에선 Header에 중복값이 존재하는 경우 Static/Dynamic Header Table 개념을 사용하여 중복 Header를 검출하고 중복된 Header는 index값만 전송하고 중복되지 않은 Header정보의 값은 Huffman Encoding 기법으로 인코딩 처리 하여 전송한다.
참고
https://www.popit.kr/%EB%82%98%EB%A7%8C-%EB%AA%A8%EB%A5%B4%EA%B3%A0-%EC%9E%88%EB%8D%98-http2/
http://americanopeople.tistory.com/115
https://developers.google.com/web/fundamentals/performance/http2/?hl=ko
https://kemptechnologies.com/solutions/http2/
문제의 진상을 파헤치는 것은 때때로 "스무고개 게임"을 하는 것처럼 느껴질 때가 있다. 즉 근본적인 문제를 빨리 발견하고 싶다면 무엇보다도 올바른 질문을 하는 것이 중요하다.
이제 문제의 본질에 대한 기본적인 이해를 하셨으니, 해결 방법을 찾을 수 있는 기술적인 세부 사항을 살펴보실 수 있습니다.
많은 경우에서 일반적인 문제로 보고 된 내용(예 : 인터넷이 다운 됨)은 사실 특정 웹 사이트가 오프라인 상태 인 것과 같이 매우 특별한 것입니다. 이것을 알아내는 가장 좋은 방법은 무엇일까요? 적절한 질문을 한 후 다음과 같은 다양한 출처에서 더 많은 정보를 찾아보십시오.
이제 기본 배경 정보를 수집했으므로 이제 문제를 직접 해결할 때입니다. 문제를 재현하는 것은 사용자가 보고한 것과 동일한 에러를 재현할 수 있음을 확인하는 것을 의미합니다. 이 작업은 문제가 되는 실제 사이트에서 또는 원격 데스크톱/원격 제어 응용 프로그램을 통해 수행할 수 있습니다. 이러한 옵션을 사용할 수 있습니까? 당신은 유사한 컴퓨터 환경에서 동일한 조건을 비슷하게 만들 수 있을 것입니다.
같은 오류가 발생하면 관찰 한 내용을 바탕으로 근본 원인에 대한 이론을 보다 쉽게 개발할 수 있으며 문제를 해결하기 위한 조치를 취하기 시작할 수 있습니다. 때로는 범인을 (솔루션을 생각해내는 것) 빨리 찾아 낼 수도 있을 겁니다. 가설과 다른 경우에는, 시간이 더 오래 걸릴 것이고, 가지고 있는 여러 지식을 파고들어야 할 수도 있고, 오래된 헬프 데스크 티켓들을 뒤적거리거나, 같은 문제에 직면한 다른 사람들의 해결책을 찾기 위해서 구글을 검색해야 할 수도 있다.
이 단계에서 컴퓨터의 작동 방식에 대한 깊은 이해가 입증될 것입니다. 예를 들어, 컴퓨터 네트워킹에서 네트워크에 대한 7계층 OSI 모델을 이해하는 경우(이 중 하나에 문제가 존재할 수 있음), 네트워킹 문제의 잠재적인 원인을 체계적으로 처리할 수 있는 프레임워크가 있습니다. 연결 문제의 경우 이더넷 케이블이 손상되거나 또는 분리되거나(Layer 1 문제), 네트워크 요청이 수행되지 않거나(Layer 3), 응용 프로그램이 제대로 코드화되지 않을 수 있습니다(Layer 6).
이미 수집한 증거는 근본 원인의 가능성이 있는 부분으로 좁혀갈 수 있고, 문제를 해결 할 수 있는 부분을 지적하고 있어야 한다. 이 시점부터는 초점을 맞추고 실험을 해야 할 단계이다. 문제와 관련된 변경 설정 변경, 문제가 있는 부분 교체, 손상된 파일을 복구, 드라이버와 소프트웨어 업데이트 등을 문제가 해결될 때까지(또는 최소한 가까워질 때까지) 시도해 볼 수 있습니다.
아직도 엉망진창? 모든 것이 정상적으로 작동하면 언제든지 기계를 다시 복원할 수 있습니다. 다시 말하면, 문제가 발생하기 전에 누군가가 데이터 또는 시스템 상태를 백업하는 매우 중요한 단계를 밟았을 때 문제가 발생하기 전의 정상적인 PC로 돌아갈 수 있습니다.
모든 문제는 고유한 눈송이와 유사하지만 문제 있는 시스템 재부팅, DNS 및 DHCP 문제 확인, 장치 관리자 드라이버 문제 확인, 시스템 정리 또는 방화벽 설정 확인 등의 일반적인 문제 해결 단계를 통해 많은 문제를 해결할 수 있습니다. 더 어려운 문제의 경우, 각자의 여러가지의 시도와 Google 검색 결과가 만족스럽지 않을 경우 Spiceworks와 같은 IT 포럼에서 토론을 검색하는 것이 PC 문제를 해결하는 데 매우 유용할 수 있습니다. 아무것도 나타나지 않으면 언제든지 Spiceworks의 수백만 명의 IT 전문가 커뮤니티에 문의할 수 있습니다.
기본적인 기술 문제(네트워크 문제, 드라이버 충돌, 디스크 문제 등)가 무엇이든 간에, 위에 설명된 프로세스는 정보 수집, 문제의 가능한 원인 확인, 문제 발생 시 솔루션을 찾는데 적합합니다. 하지만 여전히 각각의 독특한 사례에 따라 판단을 내려야 할 것입니다.
이런 종류의 시스템을 마련하고, 이전의 컴퓨터 문제를 통해 학습된 지식을 통해 여러분은 더 많은 경험을 쌓을 때 더 효율적으로 컴퓨터 문제를 해결할 수 있을 것입니다. 또한 향후 위기를 사전에 방지하기 위해 유사한 문제에 직면한 모든 사용자가 참조할 수 있도록 문제를 문서화할 수 있습니다.
참고
https://b.luavis.kr/server/linux-performance-analysis
https://www.spiceworks.com/it-articles/troubleshooting-steps/
트러블 슈팅 (0) | 2018.11.09 |
---|---|
Thread Dump 분석 (0) | 2018.11.09 |
사전적 의미로 컨테이너는 어떤 물체를 격리하는 공간을 뜻합니다. 클라우드에서 컨테이너는 어떤 의미를 가질까요? 컨테이너는 애플리케이션과 애플리케이션을 구동하는 환경을 격리한 공간을 뜻합니다. 컨테이너 기술은 약 10여 년 전에 리눅스에 내장된 기술로 소개되었으며, 현재는 차세대 트렌드 기술로 주목받으며 클라우드 서비스 환경에 적용되고 있습니다.
1) Virtual Machine과 Container의 차이점
Virtual Machine Server에서는 Hypervisor로 하드웨어를 가상화 하고, 그 위에 Guest OS가 설치된 Virtual Machine들을 구동 시켰다. 반면에 Container Server는 운영체제 레벨에서 CPU, RAM, Disk, Network 등의 자원을 격리하여 Container에 할당하기 때문에 게스트 OS가 따로 필요 없다.
2)
효율성
안정적인 운영을 위해, 1개의 가상머신(VM,
Virtual Machine)에 1개의 서비스를 구동하는 것이 권장된다. 이의 경우 가상머신의 모든 자원을 사용하는 것이 아니기 때문에 성능적 오버헤드가 발생한다. 반면 컨테이너의 경우, OS 커널을 공유하기 때문에 자원을 필요한
만큼 효율적으로 사용할 수 있다.
3)
신속성
사용자의 서비스 request traffic이 증가함에 따라, 가상머신이나 컨테이너를 추가적으로 배포한다. 가상머신의 크기는 최소
몇 GB이지만, 컨테이너의 경우 Guest OS가 없어 MB단위의 크기를 가진다. 결과적으로 가상머신은 배포하는데 수 분에서 수십 분의 시간이 소요되지만, 컨테이너는
배포에 소요되는 시간이 수 초에 불과하다.
4)
라이센스 비용 절감
가상화 서버의 경우 가상머신의 개수만큼 Guest OS의 라이센스 비용이 발생한다. 반면에 컨테이너 서버의 경우 Host OS 1대의 라이센스 비용만
발생한다. 만약 서버의 수가 많아진다면 비용의 차이도 기하급수적으로 증가할 것이다.
5)
안정성
가상머신의 경우 정확히 할당된 자원 내에서 가상머신이 운영되기 때문에, 컨테이너에
비해 안정적으로 운영할 수 있다. 반면에 컨테이너들은 OS 커널을
공유하기 때문에, 하나의 컨테이너가 무리하게 자원을 사용하게 될 수 있다. 자원 할당량을 사전에 지정 시켜줄 수 있지만, 만약 이런 상황이
발생하면 컨테이너에 장애가 발생 한다. 이런 컨테이너의 문제는 뒤에 등장할 쿠버네티스 등과 같은 Container 오케스트레이션 툴로 해결할 수 있다.
https://www.backblaze.com/blog/vm-vs-containers/
CDN 동작 원리 (0) | 2018.11.05 |
---|---|
DNS 동작원리 (1) | 2018.11.05 |
HTTP/1.1 VS HTTP/2 (1) | 2018.11.01 |
- HyperText Transfer Protocol의 준말로 링크 기반으로 데이터를 요청하고 받겠다는 것
- 클라이언트와 서버가 요청을 하고 응답을 하기 위해 따르는 프로토콜
- HTML 문서를 주고 받을 수 있음, 뿐만 아니라 이미지, 동영상, 오디오, 텍스트 문서 등을 주고 받을 수 있음
- 클라이언트 : 웹어플리케이션의 경우 브라우저를 통해서 서버에 요청 ( 프로토콜 + 도메인 + URI )
- 서버 : 클라이언트로부터 받은 요청을 내부적으로 처리하여 그에 대한 결과를 응답
- 1번 요청-응답 후 연결을 해제
- 클라이언트의 이전 상태를 알 수 없음 : 쿠키와 세션(클라이언트와 서버의 이전 상태 정보 저장)이 필요함
- 수십만 명이 웹서비스를 사용(요청)하더라도 최소 유지를 할 수 있기 때문에, 많은 유저의 요청을 처리할 수 있음
- HTTP는 1번의 요청에 대해 1번의 응답 하는 것을 기준으로 설계
- 웹사이트는 하나의 페이지에 수십 개 이미지, css 파일, js 파일들로 구성
- 1 요청 1응답 기준이라면 여러 번 연결을 끊었다 붙였다 해야해서 비효율적
- keep-alive 지원으로 지정된 시간 동안 연결을 끊지않고 연결된 상태를 유지할 수 있음
- keep-alive의 time out 내 클라이언트가 재 요청하면 새로운 연결이 아닌 기존 연결된 것을 이용함
1) 웹서버 연결
2) HTML 문서 다운로드
3) 필요한 img, css, js 등 다운로드
4) 연결 끊음
- 아래는 네이버 페이지에 대한 요청 헤더임
1) GET : 정보를 요청하기위해 사용(Read)
2) POST : 정보를 입력하기위해 사용(Create)
3) PUT : 정보를 업데이트하기위해 사용(Update)
4) DELETE : 정보를 삭제하기위해 사용(Delete)
- HTTP 프로토콜 장점을 살릴 수 있는 네트워크 기반 아키텍처
- REST API을 구현하기위해 HTTP method + 모든 개체 Resource화 + URL 디자인(라우팅) 필요
- 라우팅이란? 클라이언트의 요청에 대한 결과(응답)을 어떻게 이어줄 것인가를 처리하는 것
- URI를 이용한 접근 : 모든 개체를 리소스로 보고, 리소스에 고유번호를 부여
- URL 디자인 원칙 : 자원에 대한 처리를 주소에 나타내지않는다(HTTP method는 내부적으로 처리하도록), 어떤 자원인지 주소에 명확하게 나타냄
- REST API를 구현하기위해 HTTP 프로토콜에 대한 이해, method 종류, 라우팅에 대한 이해가 있어야함
- HTTP method를 클라이언트가 필요한 처리에 맞게 선택하여 서버에 요청
l API의 본질은 무엇인가 -> Decoupling, 탈 동조화
l 그렇다면 Web API의 본질은 무엇인가 -> Decoupling + Platform Agnostic
※ Platform Agnostic 이란?
플랫폼에 종속적이 않음을 뜻한다. 즉, 특정 기기나 OS에서만 돌아가는 것이 아닌 광범위하게 사용될 수 있는 것.
ex) 데이터 파일(텍스트파일, 그래픽 파일, 음원파일)은 윈도우든 OS X 든 안드로인드든 어디에서도 잘 돌아가니까.
REST(REpresentational State Transfer)란, "웹에 존재하는 모든 자원(이미지, 동영상, DB 자원)에 고유한 URI를 부여해 활용"하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미한다고 한다. 따라서 RESTful API는 REST 특징을 지키면서 API를 제공하는 것을 의미한다.
Roy Fielding에 의해 처음 쓰인 용어(필딩 논문)로써 일반적인 웹(혹은 유사한)을 만들기 위한 제약 조건들을 나열하여 제안한 일종의 디자인 가이드이다.
" 현재 아키텍처가 웹의 본래 설계의 우수성을 많이 사용하지 못하고 있다고 판단했기 때문에, 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처를 소개한 것이 Representational state transfer(REST) 이다."
HTTP 1.0이후 웹의 성공으로 인해 HTTP 프로토콜의 의도에 맞지 않은 사용으로 인한 확장성이나 유지보수성이 좋지 않은 웹이 늘어나면서 다시 한번 주목을 받게 되었다. 아래 설명할 6가지 조건을 “REST”라고 하며 이를 잘 지키는 서비스 디자인을 보고 RESTful하다고 한다.
l Uniform Interface
l Client-Server
l Stateless
l Cacheable
l Layered System
l Code on Demand(optional)
REST 요소를 파악하는 데는 Richardson Maturity Model(RMM)을 기준으로 이해하는 것이 좋은 것 같다.
LEVEL 0
웹의 기본 메커니즘을 전혀 사용하지 않는 단계로, HTTP를 통해 데이터를 주고받지만 모든 데이터 요청 및 응답과 관련한 정보를 HTTP의 body 정보를 활용한다. POX(Plain Old XML)로 요청과 응답을 주고받는 RPC 스타일 시스템이다. 이 때 HTTP method는 POST만 사용하며, 특정 서비스를 위해 클라이언트에서 접근할 endpoint는 하나이다.
즉, 하나의 URI을 가지고, 하나의 HTTP method(mainly POST)를 사용한다. 내용에 대한 구분은 XML을 Payload로 사용해서 요청을 구분하는 방식을 취한다. 모든걸 하나의 리소스를 가지고 처리한다.
LEVEL 1 – RESOURCE
RMM에서 REST를 위한 첫 단계는 리소스를 도입하는 것이다. 그래서 이제는 모든 요청을 단일 서비스 endpoint로 보내는 것이 아니라, 개별 리소스와 통신한다.
POST /doctors/mjones HTTP/1.1 |
즉, 함수를 호출하고 인자들을 넘기는 것이 아니라 다른 정보를 위해 인자들을 제공하는 특정 리소스로 요청을 보낸다. 이럴 경우의 이점은 자원이 외부에 보여지는 방식과 내부에 저장되는 방식을 분리 할 수 있다는 것이다.
예를 들면 클라이언트 단에서 완전히 다른 포맷으로 저장하더라도 JSON 형태의
데이터를 요청할 수 있다. 다양한 URI를 사용하지만 HTTP method는 하나만 사용한다. 그나마 URI를 통해 요청이나 파라미터를 명시한다.
LEVEL 2 - HTTP Method
LEVEL 1의 URL + HTTP Method 조합으로
리소스를 구분하는 것으로 응답 상태를 HTTP Status code 를 활용한다. 현재 가장 많은 Restful API가 이 단계를 제공한다.
GET
/doctors/mjones/slots?date=20100104&status=open HTTP/1.1 |
발생한 에러의 종류를 커뮤니케이션하기 위해 상태 코드(status code)를 사용하는 것, 그리고 안전한 오퍼레이션(GET 등)과 안전하지 않은 오퍼레이션 간의 강한 분리를 제공하는 것이 레벨 2의 핵심 요소이다.
우선, Status Code를 사용한다는 것은 어떤 의미일까?
기존에는 유저 생성 요청을 했을 경우 302 등의 Redirect Request을 서버에서 내려주는 방식이었다면, 지금은 201(created)로 유저 생성 성공을 알릴 뿐 페이지 이동은 Client 단에서 해결하는 방식이다. (login의 경우 성공은 200, 실패 시 인증 실패는 401, 성공했으나 권한 문제시엔 403 등) 즉, 서버는 순수하게 api로서의 기능만을 제공하게 된다. View는 Client에서 알아서 표시한다.
두번째로, 강한 분리를 제공하는 것이 어떤 이점이 있는 것일까?
HTTP에서 GET은 멱등방식(Idempotent )으로 자원을 추출하는데, 이
말은 호출 순서나 횟수에 영향 받지 않고 매번 같은 결과를 받을 수 있게 한다. 그렇기 때문에 모든
request에 '캐싱'기능을
지원하는 다양한 방법을 제공한다.
※ Idempotent(멱등)의 개념을 설명한 이유는 REST는 각 개별 API를 상태 없이 수행하게 된다. 따라서 해당 REST API를 다른 API와 함께 호출하다가 실패하였을 경우, 트랜잭션 복구를 위해서 다시 실행해야 하는 경우가 있는데, Idempotent 하지 않은 메서드들의 경우는 기존 상태를 저장 했다가 다시 복원해 줘야하는 문제가 있지만, Idempotent한 메서드의 경우에는 반복적으로 다시 메서드를 수행해주면 됩니다.
예를 들어 게시물 조회를 하는 API가 있을 때, 조회 시 마다 조회수를 올리는 연산을 수행한다면 이 메서드는 Idempotent 하다고 볼 수 없고, 조회하다가 실패 하였을 때는 올라간 조회수를 다시 -1 만큼 빼줘야 합니다. 즉 Idempotent 하지 않은 메서드에 대해서는 트랜잭션에 대한 처리에 특히 주의가 필요하다.
LEVEL 3 - HYPERMEDIA CONTROL
HATEOAS(Hypertext As The Engine Of Application State)
하이퍼미디어란 하나의 컨텐츠가 텍스트나 이미지, 사운드와 같은 다양한 포맷의 컨텐츠를 링크하는 개념이다. 이것은 관련 컨텐츠를 보기 위해 링크를 따라가는 방식과 유사한 방식으로 동작하는데, 클라이언트가 다른 자원에 대한 링크를 통해 서버와 (잠재적으로 상태 변이를 초래하는) 상호작용을 한다.
즉, 특정 API를 요청한 후 다음 단계로 할 수 있는 작업을 알려주는 것이며, 다음 단계의 작업을 위한 리소스의 URI를 알려주는 것이다. 이 단계를 적용하면 클라이언트에 영향을 미치지 않으면서 서버를 변경하는 것이 가능하다.
GET /doctors/mjones/slots?date=20100104&status=open
HTTP/1.1
Host: royalhope.nhs.uk
HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id =
"1234" doctor = "mjones" start = "1400" end =
"1450">
<link rel =
"/linkrels/slot/book"
uri =
"/slots/1234"/>
</slot>
<slot id =
"5678" doctor = "mjones" start = "1600" end =
"1650">
<link rel =
"/linkrels/slot/book"
uri =
"/slots/5678"/>
</slot>
</openSlotList>
단점은, 클라이언트가 수행할 작업을 찾기 위해 링크를 따라가기 때문에 컨트롤 탐색에 꽤 많은 호출이 발생할 수 있다는 것이다. 또한 복잡성이 증가할 수 있으며, HTTP 요청 상에 나타나는 부하로 낮은 지연시간이 요구될 때 문제가 될 수 있다. HTTP 기반의 REST Payload는 JSON 또는 바이너리 등의 포맷을 지원하므로 실제로 SOAP 보다 훨씬 간결할 수 있지만 Thrift와 같은 바이너리 프로토콜에는 상대가 되지 못한다.
또한 WebSocket의 경우 HTTP 초기 handshake 후에 클라이언트와 서버 간에 TCP 접속이 이루어지고 브라우저에서 스트림 데이터를 보낼 때 효율적일 수 있다. 따라서 HTTP가 대규모 트래픽에는 적합할 수 있지만 TCP 또는 다른 네트워킹 기술 기반의 프로토콜과 비교하면 낮은 지연시간이 필요한 통신에는 그다지 좋은 선택이 아닐 수 있다.
이러한 단점에도 HTTP 기반의 REST는 서비스 대 서비스의 상호작용을 위해 합리적이고 기본적인 선택이다.
l 자원(RESOURCE) - URI , 애플리케이션에서 제공하는 resource를 어떻게 분할하고 통합할 것인가?, ( LEVEL 1의 고민 )
l 행위(METHOD) - HTTP METHOD, STATUS CODE , 에러 상황에 대한 적절한 처리와 method 도입을 통한 불필요한 다양성(복잡성) 제거 (LEVEL 2의 고민)
l 표현(Representations) - hypermedia, API가 스스로 문서화 가능하도록 지원할 것인가? ( LEVEL 3의 고민 )
REST는 HTTP 표준만 따른다면, 어떠한 기술이든 사용이 가능한 인터페이스 스타일이다.
예를 들어 HTTP + JSON으로 REST API를 정의했다면, 안드로이드 플랫폼이건, IOS 플랫폼이건, 또는 C나 Java / Python 이건 특정 언어나 기술에 종속 받지 않고 HTTP와 JSON을 사용할 수 있는 모든 플랫폼에 사용이 가능한 느슨한 결합(Loosely Coupling) 형태의 구조이다.
※ 흔히들 근래에 REST를 이야기하면, HTTP + JSON을 쉽게 떠올리는데, JSON은 하나의 옵션일 뿐, 메시지 포맷을 꼭 JSON으로 적용할 필요는 없다. 자바스크립트가 유행하기전에만 해도 XML 형태를 많이 사용했으며, 근래에 들어서 사용의 편리성 때문에 JSON을 많이 사용하고 있지만, XML을 사용할 경우, XPath, XSL 등 다양한 XML 프레임워크을 사용할 수 있을 뿐만 아니라 메시지 구조를 명시적으로 정의할 수 있는 XML Scheme나 DTD등을 사용할 수 있기 때문에, 복잡도는 올라가더라도, 메시지 정의의 명확성을 더할 수 있다.
각각의 리소스는 URI를 구분자로 식별이 가능해야 한다. 예를 들어, http://www.google.com은 구글의 메인 페이지를 나타낸다. TO-DO list 웹사이트를 예로 들자면 아래와 같을 것이다.
http://www.example.com/v2/tasks # 할 일들의 collection http://www.example.com/v2/tasks/2 # id 값이 2인 할 일 http://www.example.com/v2/tasks/14 # id 값이 14인 할 일 |
리소스 자체를 전송하는 것이 아닌 리소스의 표현을 전송한다.
예를 들어, GET http://www.example.com/v2/apple 는 사과 그 자체(리소스)가 아닌 사과를 묘사한 표현를 전송한다. 리소스 자체가 아닌 표현을 사용함으로써 서버의 코드에 얽매이지 않고 client를 구현할 수 있고, 서버의 수정에 거의 영향을 받지 않는다.(최소한 영향을 줄일 수 있다.)
예를 들어 Database에 있는 리소스를 요청할 경우에 Database에 있는 그대로 응답을 할 경우에는 추후 database scheme가 변경될 경우에 클라이언트가 영향을 받을 수 있어 수정에 제약이 걸릴 수도 있다.
REST는 메시지가 자신을 어떻게 처리해야 할 지에 대한 정보를 포함하고 있어야 한다. 즉 수신자가 이해하기 위한 모든 정보를 가지고 있어야 한다. 즉, API 메시지 자체만 보고도 API를 이해할 수 있는 Self-descriptiveness 구조를 갖는 다는 것이다.
아래 내용을 로이 필딩의 논문에서 제시된 몇가지 예시다:
- state-less 시스템에서 서버는 클라이언트의 요청을 처리했던 이력을 저장하지 않는다. 그렇기 때문에 각각의 요청에 해당 정보가 포함되어야 한다.
- 표준 method(GET, POST, DELETE, PUT)와 미디어 유형을 사용하여 별도의 설명 없이 명확하게 파악할 수 있도록 한다.
- PUT method를 사용할 경우 수정한다는 의미를 파악할 수 있고 Content-Type에 json이 명시되어 있을 경우 client는 response 메시지를 읽기 위한 방법을 알 수 있다.
- Response에 캐시 가능성을 지정한다. Client가 아닌 server가 해당 내용을 header에 명시해야 한다.
어플리케이션의 상태는 하이퍼미디어에 의해 변경된다는 의미이다.
<!-- GET로 task들의 list를 가져오고 --> <a href="http://example.com/v2/tasks"/> <!-- POST로 task를 추가한다 --> <form action="http://example.com/v2/tasks"/> |
위에서처럼 클라이언트의 하이퍼미디어에 의해 어플리케이션에 task가 추가되고 제거(상태 변화) 된다는 제약이다.
서비스가 수행되길 기대하는 클라이언트 구성 요소는 연결자를 통해 서버에 요청을 보내며, 서버는 해당 요청을 거절하거나 수행하고 클라이언트에 응답을 보낸다. 그리고 모든 통신은 클라이언트-서버 간의 일대일로 연결된다.
REST 서버는 API를 제공하고, 제공된 API를 이용해서 비즈니스 로직 처리 및 저장을 책임진다. 클라이언트의 경우 사용자 인증이나 Context(세션, 로그인 정보)등을 직접 관리하고 책임 지는 구조로 역할이 나뉘어 지고 있다.
- 클라이언트는 서버의 자세한 사항에 대해서 신경 쓸 필요 없이(e.g., 데이터베이스) 제공되는 인터페이스를 통해 접근하여 응답을 받는다. 대신 자신의 Context를 관리한다.
- 서버는 클라이언트의 상태를 신경 쓰지 않고 제공한 인터페이스에 대한 처리만 담당하여 요청이 들어올 때 그에 맞는 응답을 제공한다.
이렇게 역할이 각각 확실하게 구분되면서, 개발 관점에서 클라이언트와 서버에서 개발해야 할 내용들이 명확하게 되고 서로의 개발에 있어서 의존성이 줄어들게 된다.
State가 있다/없다의 의미는 사용자나 클라이언트의 Context를 서버 쪽에 유지 하지 않는다는 의미로, 쉽게 표현하면 HTTP Session과 같은 Context 저장소에 상태 정보를 저장하지 않는 형태를 의미한다.
상태 정보를 저장하지 않으면 각 API 서버는 들어오는 요청의 메시지로만 처리하면 되며, 세션과 같은 Context 정보를 신경 쓸 필요가 없기 때문에 구현이 단순해 진다.
다시 말하면, 각각의 요청 시에 클라이언트의 Context가 서버에 저장되지 않는다. 그렇기 때문에 위에서 언급한 자기 서술형 메시지가 지켜져야 한다. 이 조건을 지킨 서버는 요청에 대한 처리만 하면 되기 때문에 구현이 단순해 진다. 또한 URI에 해당 내용을 포함시키지 않음으로써 Caching 사용 범위가 넓어질 수 있다.
상태에 대한 정보는 클라이언트가 가지고 있고 서버는 전혀 신경쓰지 않는다. 만약 어떠한 상태가 너무 중요한 나머지 서버에 두어야 할 경우에는 Resource에 추가하는 것을 고려한다.
자기 서술형 메시지 덕분에 각각의 요청에 대한 응답은 그 자체로 해석이 가능하다. 그렇기 때문에 독립적으로 처리가 가능한데, 이로 인해 Caching이 가능해진다. 다른 상황에 영향을 받았다면 Caching을 했을 경우 잘못된 결과가 나올 수 있다. 네트워크를 사용하는 비용이 가장 오래 걸리므로 이를 줄이는 것이 어플리케이션 성능을 향상시키는 좋은 방법이 될 수 있다.
# 첫번재 요청 GET /v2/tasks/2 # Reponse 200 OK Last-Modified: Sun, 03 Apr 2016 16:09:23 GMT # 두번째 요청 GET /v2/tasks/2 If-Modified-Since: Sun, 03 Apr 2016 16:09:23 GMT # Reponse 304 Not Modified # 기존의 데이터를 그대로 사용한다(이건 구현에 따라서 달라질 수 있다)
|
REST의 큰 특징 중의 하나는 HTTP라는 기존의 웹 표준을 그대로 사용하기 때문에, 웹에서 사용하는 기존의 인프라를 그대로 활용이 가능하다.
HTTP 프로토콜 기반의 로드밸러서나 SSL은 물론이고, HTTP가 가진 가장 강력한 특징 중에 하나인 캐싱 기능을 적용할 수 있다.
일반적인 서비스 시스템에서 60%에서 많게는 80% 가량의 트랜잭션이 Select와 같은 조회성 트랜잭션인 것을 감안하면, HTTP의 리소스들을 웹 캐시 서버 등에 캐싱하는 것은 용량이나 성능 면에서 많은 장점을 가지고 올 수 있다.
구현은 HTTP 프로토콜 표준에서 사용하는 "Last-Modified" 태그나 E-Tag를 이용하면 캐싱을 구현할 수 있다.
아래와 같이 Client가 HTTP GET을 "Last-Modified" 값과 함께 보냈을 때, 컨텐츠가 변화가 없으면 REST 컴포넌트는 "304 Not Modified"를 리턴 하면 Client는 자체 캐쉬에 저장된 값을 사용하게 된다.
이렇게 캐시를 사용하게 되면 네트워크 응답시간 뿐만 아니라, REST 컴포넌트가 위치한 서버에 트랜잭션을 발생시키지 않기 때문에, 전체 응답시간과 성능 그리고 서버의 자원 사용률을 비약적으로 향상시킬 수 있다.
- E-Tag : 메시지에 담겨있는 Entity를 위한 Entity 태그를 제공한다. 이를 활용하여 리소스를 식별할 수 있다.
- Last-Modified : Entity가 마지막으로 변경된 시각에 대한 정보를 제공한다. (파일인 경우 파일 시스템이 제공해 준 최근 변경 시각, 동적으로 생성된 리소스라면 응답이 만들어진 시간)
서버는 클라이언트가 모르게 API 서버에 여러 계층을 추가하여 유연한 구조로 개발될 수 있다. 클라이언트 입장에서는 REST API 서버만 호출한다. 그러나 서버는 다중 계층으로 구성될 수 있다.
순수 비즈니스 로직을 수행하는 API 서버와 그 앞 단에 사용자 인증(Authentication), 암호화(SSL), 로드밸런싱 등을 하는 계층을 추가해서 구조상의 유연성을 둘 수 있는데, 이는 근래에 들어서 앞에서 언급한 마이크로 서비스 아키텍쳐의 API Gateway나 간단한 기능의 경우에는 HA Proxy나 Apache와 같은 Reverse Proxy를 이용해서 구현하는 경우가 많다.
클라이언트는 리소스에 대한 표현을 응답으로 받고 처리해야 하는데, 어떻게 처리해야 하는지에 대한 Code를 서버가 제공하는 것을 의미한다. Html에서의 javascript가 가장 대표적인 예이다. 하지만 서버에서 제공되는 코드를 실행해야 하기 때문에 보안 문제를 야기할 수 있다.
참조
https://joonyon.tistory.com/13
https://brainbackdoor.tistory.com/53
https://meetup.toast.com/posts/92
http://bcho.tistory.com/m/321
http://amazingguni.github.io/blog/2016/03/REST%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4-1
http://jinbroing.tistory.com/96
https://blog.npcode.com/2017/04/03/rest%EC%9D%98-representation%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/
Java의 Method Signature란
Java에서 메소드가 무엇인지 먼저 알아보자.
메소드는 일련의 코드를 포함하는 코드 블록으로 프로그램에서 파라미터를 지정하여 메소드를 호출하고 실행할 수 있다. Java에서 실행되는 모든 명령은 메소드의 Context에서 수행되며, main 메소드는 모든 Java 프로그램의 진입접으로 JVM(Java Virtual Machine)에 의해 호출된다.
아래 간단한 메소드 예제이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Method { public static int Plus(int a, int b) { return a + b; } public static int Minus(int a, int b) { return a - b; } public static void main(String[] args) { int result = Plus(3, 4); System.out.println(result); result = Minus(5, 2); System.out.println(result); } } | cs |
메소드는 파라미터를 "()"로 묶고 ","로 구분한다. 빈 괄호는 메소드에 파라미터가 없다는 의미이지만 괄호를 생략할 수 없다.
또한 메소드는 클래서에서 public (공개), private(비공개), protect 와 같은 Access 수준과 abstract(추상), final(최종)과 같은 선택적 한정자, 반환값, 메소드 이름 및 메소드 파라미터를 지정하여 선언한다.
이러한 메소드를 생성하기 위한 규칙들을 중 메소드의 이름과 파라미터 만을 메소드의 시그니처(Method Signature)라고 한다.
참고 :
http://ngmaster.tistory.com/entry/151-Java-%EB%A9%94%EC%86%8C%EB%93%9C%EC%9D%98-%EC%8B%9C%EA%B7%B8%EB%8B%88%EC%B2%98-Methods-Signature
https://stackoverflow.com/questions/16149285/does-a-methods-signature-in-java-include-its-return-type