Skip to content

Commit 118f1b8

Browse files
authored
Merge pull request #5 from goohooh/master
web-pattern
2 parents 7818f2e + 95b43ba commit 118f1b8

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

08_웹_패턴/goohooh.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# 웹 패턴
2+
3+
## 자바스크립트 전송
4+
5+
### 파일 결합
6+
브라우저의 컨텐츠 전송
7+
8+
#### DNS 쿼리
9+
1. URL 입력 -> 이벤트 발생
10+
2. 운영체제에 웹사이트 이름을 IP 주소로 알려줄 것을 요청
11+
3. 윈도우 / 리눅스 / 맥에선 표준 C 라이브러리 함수인 `gethostbynam` 호출
12+
4. 로컬 DNS 캐시를 확인 하여 매핑된 주소가 있는지 탐색
13+
5. 있다면 캐시 정보를 사용하고 없다면 DNS 서버에 이를 요청
14+
6. 일반적으로 DNS 서버는 ISP(Internet Service Provider)업체에 의해 제공
15+
7. 해당 서버에 기록이 존재할 때 까지 DNS 서버 체인을 따라 전파
16+
8. 루트 서버까지 도달하여 찾지 못한다면 조회는 실패
17+
18+
#### 연결 및 요청
19+
1. 브라우저가 사이트 주소를 알면 연결을 만들고 컨텐츠 요청
20+
2. 문서 혹은 문자 전송. 보안 연결일 경우 이 시점에 SSL/TLS 협상 수행
21+
3. 서버가 HTML을 전송하고, 여기서 외부 자원을 발견하면 다시 서버와 연결하여 자원 요청
22+
23+
여기서 `파일 결합`의 이유가 필요해진다. 전송이 오버헤드를 줄여야 한다.
24+
25+
네임 스페이스를 통해 결합에 문제를 피할 수 있다.
26+
27+
다만 이때 트레이드 오프가 필요하다
28+
29+
- 사용자가 페이지를 돌아다닐 경우
30+
- 파일 결합으로 캐시를 사용하여 재사용성 증대
31+
- 사용자가 페이지 일부분만 방문할 경우
32+
- 파일을 결합할 경우 필요없는 스크립트까지 받게 됨
33+
34+
> 이를 해결하기 위해 두 방법 사이의 스윗 스팟을 찾아야하는데 이를 위해 이동 통계가 필요하다.
35+
36+
### 축소
37+
1. 태스크 러너/번들러 사용
38+
2. 서버에서 컨텐츠 스트림을 압축할 때 `gzip`(무손실 압축) [관련 링크](http://www.playnexacro.com/index.html#show:article)
39+
40+
### 콘텐츠 전송 네트워크(CDN)
41+
오직 정적 콘텐츠 제공을 목적으로 하는 호스트 분산 네트워크
42+
43+
## 플러그인 & 제이쿼리 & d3
44+
[추천 도서](http://www.yes24.com/24/goods/11371306)
45+
46+
## 멀티 스레드
47+
UI 환경에서 싱글 스레드는 흔히 사용된다. 레이스 컨디션을 피하기도 좋다.
48+
49+
하지만 웹 앱의 규모가 커지면서 복잡도는 증가했고 이에때라 복잡한 연산을 백그라운드에서
50+
51+
실행해야할 필요성이 높아졌다. 이에 대응한 것이 `Web Workers` 출현이다.
52+
53+
모던 브라우져에서 사용 가능하며 메시지를 통해 메인 스레드와 통신한다.
54+
55+
```js
56+
// 워커 파일 내부(worker.js)
57+
self.addEventListener('message', e => {
58+
var data = e.data;
59+
// startCalcualtion 메시지를 받으면
60+
if (data.cmd === 'startCalculation') {
61+
self.postMessage({event: 'caculationStarted'});
62+
// fib의 새로운 인스턴스를 시작
63+
var result = fib(data.parameters.nummber);
64+
self.postMessage({
65+
event: 'calculationComplete',
66+
result: result
67+
});
68+
}
69+
}, false);
70+
71+
// 메인 스레드
72+
// 외부 파일에서 웹워커를 로드하고
73+
worker = new Worker('worker.js');
74+
// 리스너를 추가한다.
75+
worker.addEventListener('message', message => {
76+
logEvent(message.data.event);
77+
if (message.data.event === 'calculationComplete') {
78+
writeResult(message.data.result);
79+
}
80+
if (message.data.event === 'calculationStarted') {
81+
document.getElementById('result').innerHTML = 'working';
82+
}
83+
});
84+
85+
// 계산을 위한 명령
86+
worker.postMessage({
87+
cmd: 'startCaculation',
88+
parameters: {number: 40}
89+
});
90+
```
91+
백그라운드 실행 동안 메인 스레드는 다른 작업을 할 수 있고,
92+
93+
웹 워커로 부터 메시지가 수신되면 기존 이벤트 루프로 처리한다.
94+
95+
Node.js에서 자식 프로세스를 포크 하는 형식으로 비슷한 인터페이스를 제공한다.
96+
97+
하지만 프로세스를 포크하는 만큼 비용이 많이 든다.
98+
99+
## 서킷 브레이커 패턴
100+
101+
대형 시스템은 많은 중복으로 이루어져 있다. 이러한 중복은 컴포넌트의 실패 시
102+
103+
백업을 제공하는 수단이 될 수 있다.
104+
105+
> 앱이 외부 데이터 소스에 5초마다 쿼리를 보낸다고 가정하자.
106+
107+
이러한 폴링이 실패하면, 대부분 실패를 무시하고 계속 폴링한다.
108+
109+
일부의 경우 실패시 즉시 재요청을 하기도 하는데, 이는 바쁜 스케쥴링에서
110+
111+
문제가 될 수 있다.
112+
113+
서버측에서는 수많은 클라이언트에게 5초마다 응답해야 한다.
114+
115+
서킷 브레이커 패턴은 실패가 일정 횟수에 도달하면 통신 시도를 차단 한다.
116+
117+
물론 어느 시점에서는 서킷 브레이커를 리셋하여 서비스가 복구되도록 해야한다.
118+
119+
## 백 오프
120+
121+
서킷 브레이커의 변형으로 통신을 차단하는 대신 요청에 딜레이를 준다.
122+
123+
폴링 간격이 5초 였다면, 고장 검출 시 간격을 10초로 변경한다.
124+
125+
이 과정을 반복하여 간격을 늘리고, 다시 정상 작동 한다면 다시 간격을 줄여간다.
126+
127+
## 성능 저하 애플리케이션 동작
128+
129+
실시간 주식 시세를 서비스하는 경우
130+
131+
시스템에 문제가 생기면, 비실시간으로 서비스를 제공할 수 있다.
132+
133+
모던 브라우저가 제공하는 저장 공간을 사용하는 것이다.
134+
135+
앱이 서버로 데이터를 전송할 때도 유용하다.
136+
137+
데이터 업데이트를 로컬에 저장하고 서비스가 가능해질 때 한꺼번에 보낼 수도 있다.
138+
139+
(사용자가 페이지를 떠나면 백그라운드 작업은 종료된다.)
140+
141+
> 이런 방식을 사용할 경우 사용자에게 데이터가 최신이 아님을 경고해 줘야 한다.
142+
143+
## 프로미스
144+
145+
냉무

0 commit comments

Comments
 (0)