Taobao 온라인 응용 프로그램의 기존 소프트웨어 스택 구조는 Nginx + Velocity + Java입니다.
이 시스템에서 Nginx는 요청을 Java 응용 프로그램으로 전달하여 트랜잭션을 처리하고 속도 템플릿을 사용하여 데이터를 최종 페이지로 렌더링합니다.
Node.js를 도입 한 후에는 불가피하게 다음과 같은 문제에 직면하게됩니다.
기술 스택의 토폴로지 구조를 설계하는 방법과 배포 방법을 선택하는 방법은 과학적이고 합리적 인 것으로 간주됩니까? 프로젝트가 완료된 후 트래픽을 나누는 방법은 운영 및 유지 보수에 편리하고 빠릅니까? 온라인 문제가 발생할 때 가능한 빨리 위험을 제거하고 더 큰 손실을 피하는 방법은 무엇입니까? 응용 프로그램의 건강을 보장하고로드 밸런싱 스케줄링 수준에서 관리하는 방법은 무엇입니까? 시스템 토폴로지
전면 및 후면 끝의 분리에 대한 우리의 생각과 실습 (ii) - 전면 및 후면의 템플릿 탐색에 기초하여, 속도는 node.js로 대체되어야 하므로이 구조는 다음과 같습니다.
이것은 물론 이상적인 목표입니다. 그러나 전통적인 스택에서 node.js 층의 첫 번째 도입은 결국 새로운 시도입니다. 안전하기 위해, 우리는 즐겨 찾기의 즐겨 찾기 페이지 (shoucang.taobao.com/item_collect.htm)에서 새로운 기술 만 활성화하기로 결정했지만 다른 페이지는 기존 솔루션을 계속 사용합니다. 즉, NGINX는 요청의 페이지 유형을 결정하고 요청이 node.js 또는 java로 전달 될지 여부를 결정합니다. 그래서 최종 구조는 다음과 같습니다.
배치 계획
위의 구조는 괜찮은 것처럼 보이지만 실제로 새로운 문제는 여전히 전면을 기다리고 있습니다. 기존 구조에서는 Nginx와 Java가 동일한 서버에 배포됩니다. NGINX는 포트 80을 듣고 하이 비트에서 포트 7001을 듣고 자바와 의사 소통합니다. 이제 node.js가 도입되었으므로 청취 포트를 실행 해야하는 새로운 프로세스가 필요합니다. ngenx + java를 사용하여 동일한 시스템에 node.js를 배포해야합니까, 아니면 별도의 클러스터에 node.js를 배포해야합니까?
두 가지 방법의 특성을 비교해 봅시다.
Taobao 즐겨 찾기는 일일 평균 PV가 수천만 PV의 응용 프로그램으로 안정성에 대한 요구 사항이 매우 높습니다 (실제로 모든 제품의 온라인 불안정성은 용납 할 수 없습니다). 동일한 클러스터 배포 솔루션을 채택하는 경우 파일을 한 번만 배포하고 두 번 다시 부팅하여 릴리스를 완료하면됩니다. 롤백 해야하는 경우 기준 패키지를 한 번만 작동하면됩니다. 성능 측면에서 동일한 클러스터 배포에는 몇 가지 이론적 이점이 있습니다 (인트라넷의 스위치 대역폭 및 대기 시간은 매우 낙관적이지만). 일대일 또는 다중 관계에 관해서는 서버가 이론적으로 더 완전히 활용 될 수 있지만 안정성 요구 사항과 비교할 때이 점은 해결하기가 그렇게 시급하지 않습니다. 따라서 즐겨 찾기의 변환에서 동일한 클러스터 배포 솔루션을 선택했습니다.
그레이 스케일
최대 안정성을 보장하기 위해이 변환은 속도 코드를 직접 제거하지 않았습니다. 응용 프로그램 클러스터에는 거의 100 개의 서버가 있습니다. 우리는 서버를 세분성으로 사용하고 점차 트래픽을 도입합니다. 다시 말해, Java + Node.js 프로세스는 모든 서버에서 실행 중이지만 Nginx에 해당 전달 규칙이 있는지 여부는이 서버에서 베이비 컬렉션을 얻는 요청이 Node.js를 통해 처리 될지 여부를 결정합니다. nginx의 구성은 다음과 같습니다.
위치 = "/item_collect.htm"{proxy_pass http://127.0.0.1:6001; # node.js 프로세스 청취 포트}이 nginx 규칙을 추가 한 서버 만 Node.js가 해당 요청을 처리하게합니다. Nginx 구성을 통해 회색조 트래픽을 증가시키고 감소시키는 것이 매우 편리하고 빠르게 저렴하며 비용은 매우 낮습니다. 문제가 발생하면 NGINX 구성을 직접 롤백하고 기존 기술 스택 구조로 즉시 돌아와 위험을 완화 할 수 있습니다.
우리가 처음 출시했을 때, 우리는 두 개의 서버에서만이 규칙을 활성화했는데, 이는 온라인 트래픽의 2% 미만이 node.js에서 처리되며 나머지 트래픽에 대한 요청은 여전히 속도로 렌더링됩니다. 앞으로 상황에 따라 트래픽이 점차 증가 할 것이며, 마지막으로 세 번째 주에는 모든 서버가 활성화됩니다. 이 시점에서 프로덕션 환경에서 트래픽이 100% 인 제품 수집 페이지는 Node.js에 의해 렌더링됩니다 (소스 코드를 확인하여 node.js 키워드를 검색 할 수 있음).
변화
그레이 스케일 프로세스는 매끄럽지 않습니다. 흐름을 충분히 자르기 전에 크든 작든 몇 가지 문제가 발생했습니다. 대부분의 비즈니스는 특정 비즈니스와 관련이 있으며, 학습 할 가치가있는 것은 기술적 인 세부 사항과 관련된 함정입니다.
건강 점검
기존 아키텍처에서로드 밸런싱 스케줄링 시스템은 각 서버의 포트 80의 특정 URL에서 매 초마다 get 요청을 시작하고 반환 된 HTTP 상태 코드가 200 인지 여부를 기반으로 서버가 정상적으로 작동하는지 여부를 결정합니다. 1S 이후의 시간 초과가 요청되거나 HTTP 상태 코드가 200 아닌 경우 온라인 문제를 피하기 위해 서버에 트래픽이 도입되지 않습니다.
이 요청의 경로는 nginx-> java-> nginx입니다. 즉, 200 반환되는 한이 서버의 nginx와 java는 건강한 상태에 있음을 의미합니다. node.js를 도입 한 후이 경로는 nginx-> node.js-> java-> node.js-> nginx가됩니다. 해당 코드는 다음과 같습니다.
var http = 요구 ( 'http'); app.get ( '/status.taobao', function (req, res) {http.get ({host : '127.1', port : 7001, path : '/status.taobao'}, function (res.send) {res.statuscode);}). }));그러나 테스트 프로세스 중에 Node.js가 그러한 요청을 전달할 때 Java 측면을 6 ~ 7 번씩 한 번씩 다시 돌아 오는 데 몇 초 또는 10 초가 걸린 것으로 나타났습니다. 이로 인해로드 밸런싱 스케줄링 시스템이 서버에서 이상이 발생한 후 트래픽을 차단한다고 생각하게되지만 실제로 서버는 정상적으로 작동 할 수 있습니다. 이것은 분명히 큰 문제입니다.
검색 후 기본적으로 Node.js는 HTTP Agent 클래스를 사용하여 HTTP 연결을 생성하는 것을 발견했습니다. 이 클래스는 소켓 연결 풀을 구현합니다. 각 호스트 + 포트 쌍에 대한 연결 수의 기본 상한은 5입니다. 동시에 HTTP Agent 클래스가 시작한 요청에는 Connection: Keep-Alive , 반환 된 연결이 제 시간에 해제되지 않으며 나중에 시작된 요청은 대기 할 수 있습니다.
세 가지 최종 해결책이 있습니다.
HTTP Agent 비활성화, get 추가 매개 변수 agent: false
var http = 요구 ( 'http'); app.get ( '/status.taobao', function (req, res) {http.get ({host : '127.1', port : 7001, agent : false : '/status.taobao'}, function (res) {res.send (res.statuscode);}), ( 'error', erver (err) {err) {err) Res.send (404); http 객체의 글로벌 소켓 수의 상한을 설정하십시오.
http.globalagent.maxsockets = 1000;
요청이 반환되면 적시에 적극적으로 연결이 끊어집니다.
http.get (옵션, 함수 (res) {}). on ( "socket", function (socket) {socket.emit ( "agentremove"); // 소켓 이벤트를 듣고 콜백에서 AgentRemove 이벤트를 파견);실제로, 우리는 첫 번째 방법을 선택했습니다. 이 조정 후 건강 검사에서 다른 문제가 발견되지 않았습니다.
결합하다
Node.js를 전통적인 비즈니스 시나리오와 결합하는 관행이 막 시작되었으며 여전히 깊이 탐색 할 가치가있는 최적화 지점이 많이 있습니다. 예를 들어, Java 응용 프로그램이 완전히 중앙 집중화 된 후 서버 사용을 개선하기 위해 클러스터 배포 테스트를 수행 할 수 있습니까? 아니면 릴리스 및 롤백 방법이 더 유연하고 제어 가능 할 수 있습니까? 모든 세부 사항은 추가 연구의 가치가 있습니다.