>  기사  >  Java  >  Java 시스템의 높은 동시성 문제 해결

Java 시스템의 높은 동시성 문제 해결

黄舟
黄舟원래의
2017-09-21 10:22:561173검색

이 기사는 주로 Java 시스템을 위한 높은 동시성 솔루션을 소개합니다. 내용이 매우 풍부하여 여기 있는 모든 사람과 공유하고 도움이 필요한 친구들이 참조할 수 있습니다.

개인 웹사이트와 같은 작은 웹사이트는 가장 간단한 HTML 정적 페이지를 사용하여 구현될 수 있으며, 일부 사진을 사용하여 아름다운 효과를 얻을 수 있습니다. 이러한 웹사이트에는 시스템 아키텍처와 성능 요구 사항이 있습니다. 인터넷 비즈니스가 지속적으로 풍부해짐에 따라 웹 사이트 관련 기술은 수년간의 개발을 거쳐 매우 미세한 측면으로 세분화되었습니다. 특히 대규모 웹 사이트의 경우 사용되는 기술은 하드웨어에서 소프트웨어, 프로그래밍까지 광범위한 측면을 포괄합니다. 언어, mysql" target="_blank" title="MySQL Knowledge Base"> 데이터베이스, WebServer, 방화벽 및 기타 분야는 요구 사항이 매우 높아서 원래의 단순 HTML 정적 웹 사이트와 더 이상 비교할 수 없습니다.

대규모 웹 사이트, 포털과 같은 많은 사용자 방문과 높은 동시 요청에 직면했을 때 기본 솔루션은 고성능 서버, 고성능 데이터베이스 및 효율적인 언어 및 고성능 웹 컨테이너 사용에 중점을 둡니다. 하지만 이러한 측면을 제외하면 대규모 웹사이트가 직면한 높은 부하 및 높은 동시성 문제를 근본적으로 해결할 수 있는 방법은 없습니다. 낮은 비용, 높은 성능 및 높은 확장성의 관점에서 내 경험을 이야기하겠습니다. 따라서 우리는 웹사이트의 페이지에 정적 페이지를 사용하기 위해 최선을 다하고 있지만, 실제로는 이 간단한 방법이 가장 효과적입니다. 그러나 콘텐츠의 양이 많고 업데이트가 빈번한 웹사이트에서는 이를 모두 수동으로 구현할 수 없습니다. , 그래서 우리가 자주 방문하는 각종 포털 사이트의 뉴스 채널은 물론, 다른 채널까지 모두 정보 공개 시스템을 통해 관리 및 구현되는 우리의 공통 정보 공개 시스템인 CMS가 가장 간단한 정보 입력을 실현할 수 있습니다. 채널 관리, 권한 관리, 자동 크롤링 등의 기능도 갖추고 있습니다.
포털, 정보 게시형 웹사이트 외에도 효율적이고 관리 가능한 CMS가 필요합니다. 상호 작용 요구 사항이 높은 커뮤니티 유형 웹 사이트에서는 가능한 한 정적으로 유지하는 것도 성능을 향상시키는 데 필요한 수단이기도 하며, 커뮤니티의 게시물과 기사를 실시간으로 정적으로 만든 다음, 문제가 있을 때 다시 정적화하는 것도 널리 사용되는 전략입니다. Mop의 hodgepodge는 이 전략을 사용하며 NetEase 커뮤니티도 마찬가지입니다.


동시에 html은 정적입니다. 시스템에서 데이터베이스 쿼리를 자주 사용하는 애플리케이션의 경우 정적화도 사용됩니다. 소규모 콘텐츠 업데이트의 경우 이를 달성하기 위해 포럼의 공개 설정 정보와 같은 정보를 사용할 수 있습니다. 이 정보는 현재 백그라운드에서 관리되고 데이터베이스에 저장될 수 있습니다. 프런트 엔드 프로그램에서 대량으로 호출하지만 업데이트 빈도는 매우 적습니다. 백그라운드 업데이트 중에 콘텐츠의 이 부분을 정적으로 만들어 많은 수의 데이터베이스 액세스 요청을 피할 수 있습니다.

2. 이미지 서버 분리


아파치든, IIS든, 다른 컨테이너든 웹 서버의 경우 이미지가 가장 많은 리소스를 소비하므로 페이지에서 이미지를 분리하는 것이 필요합니다. 이는 대규모 웹사이트에서 기본적으로 채택하는 전략입니다. 모든 웹사이트에는 독립적인 이미지 서버가 있거나 심지어 다수의 이미지 서버가 있습니다. 이러한 아키텍처는 페이지 액세스 요청을 제공하는 서버 시스템에 대한 부담을 줄일 수 있으며, 그림 문제로 인해 시스템이 충돌하지 않도록 보장할 수 있습니다. 예를 들어, 아파치는 응용 프로그램 서버에서 수행할 수 있습니다. ContentType을 구성할 때 최선을 다해 지원하고 가능한 한 적은 수의 LoadModule을 사용하여 더 높은 시스템 소비와 실행 효율성을 보장하세요.


3. 데이터베이스 클러스터 및 데이터베이스 테이블 해싱

대규모 웹사이트에는 복잡한 애플리케이션이 있으며, 이러한 애플리케이션은 데이터베이스를 사용해야 하며, 이때 데이터베이스의 병목 현상이 금방 드러납니다. 시간이 지나면 하나의 데이터베이스가 곧 애플리케이션을 만족시킬 수 없게 되므로 데이터베이스 클러스터링이나 데이터베이스 테이블 해싱을 사용해야 합니다.

데이터베이스 클러스터의 경우 자체 솔루션이 있는 경우가 많습니다. Oracle, Sybase 등은 일반적으로 사용되는 MySQL에서 제공하는 마스터/슬레이브도 유사한 솔루션을 사용합니까? 이를 구현하려면 해당 솔루션을 참조하세요.

위에서 언급한 데이터베이스 클러스터는 아키텍처, 비용, 확장성 측면에서 사용되는 DB 유형에 따라 제한되므로 애플리케이션 관점에서 시스템 아키텍처 개선을 고려해야 합니다. 라이브러리 테이블 해싱은 일반적으로 가장 많이 사용됩니다. 효과적인 솔루션 계획. 우리는 데이터베이스를 분리하기 위해 애플리케이션에 비즈니스 및 애플리케이션 또는 기능 모듈을 설치한 다음 특정 전략을 사용하여 사용자 테이블과 같은 특정 페이지 또는 기능에서 더 작은 데이터베이스 해시를 수행합니다. 사용자 ID에 따른 테이블을 생성하여 저렴한 비용으로 시스템 성능을 향상시킬 수 있으며 확장성이 좋습니다. 소후의 포럼은 포럼의 사용자, 설정, 게시물 및 기타 정보를 데이터베이스로 분리한 다음 섹션과 ID에 따라 데이터베이스와 게시물 및 사용자 테이블을 해싱하는 구조를 채택하고 있으며, 마지막으로 구성에서 간단하게 구성할 수 있습니다. 이를 통해 시스템은 언제든지 저비용 데이터베이스를 추가하여 시스템 성능을 보완할 수 있습니다.

4. 캐싱

모든 기술 담당자는 캐시라는 단어를 접하게 되며 캐시는 여러 곳에서 사용됩니다. 웹 사이트 아키텍처 및 웹 사이트 개발에서 캐싱도 매우 중요합니다. 여기서는 먼저 가장 기본적인 두 가지 캐시에 대해 이야기합니다. 고급 및 분산 캐싱에 대해서는 나중에 설명합니다.

아키텍처 캐싱 측면에서 Apache에 익숙한 사람이라면 Apache가 자체 캐싱 모듈을 제공하며 캐싱을 위해 추가 Squid 모듈을 사용할 수도 있다는 것을 알 것입니다. 두 방법 모두 Apache의 액세스 응답 기능을 효과적으로 향상시킬 수 있습니다.

웹사이트 프로그램 개발 시 캐시, 리눅스에서 제공하는 메모리 캐시는 흔히 사용되는 캐시 인터페이스로, 예를 들어 자바로 개발할 때 일부 데이터를 캐시하고 통신할 수 있습니다. 대규모 커뮤니티는 이 아키텍처를 사용합니다. 또한 웹 언어 개발을 사용할 때 각 언어에는 기본적으로 자체 캐시 모듈과 메서드가 있습니다. PHP에는 Pear의 캐시 모듈이 있고 Java에는 더 많은 것이 있습니다. .net에는 익숙하지 않지만 분명히 있을 것이라고 생각합니다.

5. 미러링

미러링은 성능 및 데이터 보안을 향상하기 위해 대규모 웹사이트에서 자주 사용하는 방법입니다. 미러링 기술은 ChinaNet과 같은 다양한 네트워크 액세스 공급자 및 지역으로 인한 사용자 액세스 속도 차이를 해결할 수 있습니다. EduNet의 차이점으로 인해 많은 웹사이트가 교육 네트워크 내에 미러 사이트를 구축하게 되었으며, 데이터는 정기적으로 또는 실시간으로 업데이트됩니다. 미러링의 세부 기술에 대해서는 여기서 너무 자세히 설명하지 않겠습니다. 선택할 수 있는 전문 기성 솔루션 아키텍처와 제품이 많이 있습니다. rsync 및 Linux의 기타 도구와 같은 소프트웨어를 통해 이를 구현하는 저렴한 방법도 있습니다.

6. 로드 밸런싱

로드 밸런싱은 대규모 웹사이트에서 높은 로드 액세스와 많은 수의 동시 요청을 해결하는 최고의 솔루션이 될 것입니다.

로드 밸런싱 기술은 수년 동안 개발되었으며 선택할 수 있는 전문 서비스 제공업체와 제품이 많이 있습니다. 저는 개인적으로 몇 가지 솔루션을 접했는데 그 중 두 가지를 참고로 사용할 수 있습니다.

1) 하드웨어 레이어 4 스위칭

레이어 4 스위칭은 3, 4번째 레이어 패킷의 헤더 정보를 이용하여 애플리케이션 간격에 따른 비즈니스 흐름을 파악하고 전체 간격의 비즈니스 흐름을 적절한 계층에 할당합니다. 처리를 위한 애플리케이션 서버입니다. 레이어 4 스위칭 기능은 물리적 서버를 가리키는 가상 IP와 같습니다. 전송하는 서비스는 HTTP, FTP, NFS, Telnet 또는 기타 프로토콜을 포함한 다양한 프로토콜을 따릅니다. 이러한 서비스에는 물리적 서버를 기반으로 하는 복잡한 로드 밸런싱 알고리즘이 필요합니다. IP 세계에서 서비스 유형은 터미널 TCP 또는 UDP 포트 주소에 의해 결정됩니다. 레이어 4 스위칭에서는 응용 프로그램 범위가 소스 및 터미널 IP 주소, TCP 및 UDP 포트에 의해 결정됩니다.

하드웨어 4레이어 스위칭 제품 분야에는 Alteon, F5 등 잘 알려진 제품이 있습니다. 이러한 제품은 가격이 비싸지만 그만한 가치가 있으며 매우 우수한 성능을 제공할 수 있습니다. 매우 유연한 관리 기능을 제공합니다. Yahoo China는 3~4개의 Alteon을 사용하여 거의 2,000대의 서버를 처리했습니다.

2) 소프트웨어 4레이어 스위칭

하드웨어 4레이어 스위치의 원리를 모두가 알게 된 후, OSI 모델을 기반으로 한 소프트웨어 4레이어 스위칭이 등장했습니다. 그러나 이러한 솔루션의 원리는 일관됩니다. , 성능이 약간 나쁩니다. 그러나 어느 정도의 압박은 여전히 ​​충족하기 쉽습니다. 일부 사람들은 소프트웨어 구현 방법이 실제로 더 유연하며 처리 능력은 전적으로 구성의 친숙성에 달려 있다고 말합니다.
Linux에서 일반적으로 사용되는 LVS를 사용하여 소프트웨어 4계층 스위칭을 해결할 수 있습니다. LVS는 하트비트 라인 기반의 실시간 재해 대응 솔루션을 제공하고 시스템의 견고성을 향상시키며 유연한 VIP를 제공합니다. 구성 및 관리 기능은 여러 애플리케이션 요구 사항을 동시에 충족할 수 있으며 이는 분산 시스템에 필수적입니다.

일반적인 로드 밸런싱 전략은 소프트웨어 또는 하드웨어 4계층 전환을 기반으로 Squid 클러스터를 구축하는 것입니다. 이 아이디어는 검색 엔진을 포함한 많은 대형 웹 사이트에서 채택되고 있으며 이 아키텍처는 저렴하고 성능이 뛰어납니다. 확장성이 뛰어나며 언제든지 아키텍처에 노드를 추가하거나 제거하는 것이 매우 쉽습니다. 이 구조를 자세히 정리해서 여러분과 논의해보겠습니다.

1: 높은 동시성, 고부하 웹사이트의 중심이 되는 데이터베이스

예, 첫 번째는 대부분의 애플리케이션이 직면하는 첫 번째 SPOF인 데이터베이스입니다. 특히 Web2.0 애플리케이션의 경우 데이터베이스의 응답을 먼저 해결해야 합니다.

일반적으로 MySQL이 가장 일반적으로 사용됩니다. 처음에는 데이터가 100만 개 이상으로 증가하면 MySQL의 성능이 급격히 떨어집니다. 일반적인 최적화 방법은 쿼리와 작업이 서로 다른 서버에서 수행되는 동기 복제를 위한 M-S(마스터-슬레이브) 모드입니다. 제가 추천하는 방법은 M-M-Slave 방식으로, 2개의 마스터 Mysql과 여러 개의 슬레이브가 있습니다. 비록 2개의 마스터가 있지만 동시에 한 개만 활성화될 수 있다는 점에 유의해야 합니다. 두 개의 M을 사용하는 이유는 M이 다시 시스템의 SPOF가 되지 않도록 하기 위한 것입니다.

슬레이브는 추가로 로드 밸런싱을 수행할 수 있으며 LVS와 결합하여 다양한 슬레이브에 대한 선택 작업의 균형을 적절하게 맞출 수 있습니다.

위 아키텍처는 일정량의 부하를 감당할 수 있지만 사용자 수가 더 증가함에 따라 사용자 테이블 데이터가 1천만 개를 초과하고 M이 SPOF가 됩니다. 슬레이브를 임의로 확장할 수 없습니다. 그렇지 않으면 복제 동기화 비용이 급등하게 됩니다. 어떻게 해야 합니까? 내 방법은 테이블 파티셔닝, 즉 비즈니스 수준에서 파티셔닝하는 것입니다. 가장 간단한 것은 사용자 데이터를 예로 들어보겠습니다. ID와 같은 특정 분할 방법에 따라 서로 다른 데이터베이스 클러스터로 분할됩니다.

메타데이터 쿼리에는 글로벌 데이터베이스가 사용됩니다. 단점은 쿼리할 때마다 한 번씩 추가된다는 점입니다. 예를 들어 nightsailer 사용자를 쿼리하려면 먼저 전역 데이터베이스 그룹으로 이동하여 nightsailer에 해당하는 클러스터 ID를 찾은 다음 해당 그룹으로 이동해야 합니다. nightsailer의 실제 데이터를 찾기 위해 지정된 클러스터를 사용합니다.

각 클러스터는 M-M 모드 또는 M-M-슬레이브 모드를 사용할 수 있습니다. 이는 부하가 증가함에 따라 새로운 mysql 클러스터를 추가하기만 하면 되는 확장 가능한 구조입니다.

주의해야 할 점:

1. 모든 auto_increment 필드를 비활성화합니다.

2. ID는 공통 알고리즘을 사용하여 중앙에서 할당되어야 합니다.

3. mysql 호스트의 상태와 서비스의 실행 상태. 30개가 넘는 mysql 데이터베이스를 실행하고 있다면 무슨 뜻인지 이해하실 것입니다.

4. 영구 링크를 사용하지 마십시오(pconnect를 사용하지 마십시오). 대신 sqlrelay와 같은 타사 데이터베이스 연결 풀을 사용하거나 직접 수행하십시오. 왜냐하면 php4의 mysql 연결 풀에는 종종 문제가 있기 때문입니다.

둘: 동시성 및 부하가 높은 웹사이트의 시스템 아키텍처를 위한 HTML 정적

사실 가장 효율적이고 가장 적게 소비되는 페이지는 순전히 정적 페이지라는 사실을 모두가 알고 있으므로 우리는 최선을 다해 웹사이트의 페이지 이를 달성하기 위해 정적 페이지를 사용하는 것이 가장 간단한 방법이자 실제로 가장 효과적인 방법입니다. 하지만 콘텐츠의 양이 많고 업데이트가 잦은 웹사이트의 경우 일일이 수동으로 구현할 수 없기 때문에 우리가 자주 방문하는 각종 포털 사이트의 뉴스 채널은 물론 다른 포털 사이트의 뉴스 채널까지 공통 정보 게시 시스템인 CMS가 등장했습니다. 채널 관리, 정보 공개 시스템에 의해 관리 및 구현됩니다. 정보 공개 시스템은 가장 간단한 정보 입력을 실현할 수 있으며 채널 관리, 권한 관리, 자동 크롤링 등의 기능도 가질 수 있습니다. 대규모 웹사이트에는 효율적이고 관리 가능한 CMS가 필수적입니다. 포털, 정보 게시 웹 사이트 외에도 상호 작용 요구 사항이 높은 커뮤니티 유형 웹 사이트의 경우 최대한 정적으로 만드는 것도 커뮤니티의 게시물과 기사를 실시간으로 정적으로 만들고 업데이트할 수 있는 필수 수단입니다. 재정적화는 NetEase 커뮤니티와 마찬가지로 Mop의 hodgepodge에서도 널리 사용되는 전략입니다.

동시에 HTML 정적화는 일부 캐싱 전략에서 사용되는 수단이기도 합니다. 데이터베이스 쿼리를 자주 사용하지만 콘텐츠 업데이트가 매우 적은 시스템의 애플리케이션의 경우 이를 달성하기 위해 HTML 정적화를 사용할 수 있습니다. 포럼의 공개 설정 정보입니다. 이 정보는 현재 주류 포럼에서 관리하고 데이터베이스에 저장할 수 있습니다. 실제로 이 정보 중 상당수는 프런트엔드 프로그램에서 호출되지만 업데이트 빈도는 매우 적습니다. 많은 수의 데이터베이스 액세스 요청이 동시에 발생하는 것을 방지하기 위해 백그라운드를 업데이트할 때 콘텐츠의 이 부분을 정적으로 만드는 것을 고려할 수 있습니다.

웹사이트 HTML 정적 솔루션

서블릿 리소스 요청이 웹 서버에 도달하면 지정된 JSP 페이지를 채워 요청에 응답합니다.

HTTP 요청---웹 서버---서블릿-- 비즈니스 로직 처리--데이터 액세스--JSP 채우기--응답 요청

HTML 정적화 후:

HTTP 요청---웹 서버---서블릿--HTML--응답 요청

정적 액세스 요청은 다음과 같습니다

서블릿:


public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if(request.getParameter("chapterId") != null){
String chapterFileName = "bookChapterRead_"+request.getParameter("chapterId")+".html";
String chapterFilePath = getServletContext().getRealPath("/") + chapterFileName;
File chapterFile = new File(chapterFilePath);
if(chapterFile.exists()){response.sendRedirect(chapterFileName);return;}//如果有这个文件就告诉浏览器转向
INovelChapterBiz novelChapterBiz = new NovelChapterBizImpl();
NovelChapter novelChapter = novelChapterBiz.searchNovelChapterById(Integer.parseInt(request.getParameter("chapterId")));//章节信息
int lastPageId = novelChapterBiz.searchLastCHapterId(novelChapter.getNovelId().getId(), novelChapter.getId());
int nextPageId = novelChapterBiz.searchNextChapterId(novelChapter.getNovelId().getId(), novelChapter.getId());
request.setAttribute("novelChapter", novelChapter);
request.setAttribute("lastPageId", lastPageId);
request.setAttribute("nextPageId", nextPageId);
new CreateStaticHTMLPage().createStaticHTMLPage(request, response, getServletContext(),
chapterFileName, chapterFilePath, "/bookRead.jsp");
}
}

HTML 정적 페이지 생성을 위한 클래스:


package com.jb.y2t034.thefifth.web.servlet;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* 创建HTML静态页面
* 功能:创建HTML静态页面
* 时间:2009年1011日
* 地点:home
* @author mavk
*
*/
public class CreateStaticHTMLPage {
/**
* 生成静态HTML页面的方法
* @param request 请求对象
* @param response 响应对象
* @param servletContext Servlet上下文
* @param fileName 文件名称
* @param fileFullPath 文件完整路径
* @param jspPath 需要生成静态文件的JSP路径(相对即可)
* @throws IOException
* @throws ServletException
*/
public void createStaticHTMLPage(HttpServletRequest request, HttpServletResponse response,ServletContext servletContext,String fileName,String fileFullPath,String jspPath) throws ServletException, IOException{
response.setContentType("text/html;charset=gb2312");//设置HTML结果流编码(即HTML文件编码)
RequestDispatcher rd = servletContext.getRequestDispatcher(jspPath);//得到JSP资源
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//用于从ServletOutputStream中接收资源
final ServletOutputStream servletOuputStream = new ServletOutputStream(){//用于从HttpServletResponse中接收资源
public void write(byte[] b, int off,int len){
byteArrayOutputStream.write(b, off, len);
}
public void write(int b){
byteArrayOutputStream.write(b);
}
};
final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream));//把转换字节流转换成字符流
HttpServletResponse httpServletResponse = new HttpServletResponseWrapper(response){//用于从response获取结果流资源(重写了两个方法)
public ServletOutputStream getOutputStream(){
return servletOuputStream;
}
public PrintWriter getWriter(){
return printWriter;
}
};
rd.include(request, httpServletResponse);//发送结果流
printWriter.flush();//刷新缓冲区,把缓冲区的数据输出
FileOutputStream fileOutputStream = new FileOutputStream(fileFullPath);
byteArrayOutputStream.writeTo(fileOutputStream);//把byteArrayOuputStream中的资源全部写入到fileOuputStream中
fileOutputStream.close();//关闭输出流,并释放相关资源
response.sendRedirect(fileName);//发送指定文件流到客户端
}
}

3: 캐싱, 로드 밸런싱 및 스토리지에 중점을 둔 동시성 및 로드가 많은 웹사이트

캐시는 또 다른 큰 문제입니다. 질문, 저는 주로 memcached를 캐시 클러스터로 사용합니다. 일반적으로 말하면 10개 정도의 유닛(10g 메모리 풀)을 배포하면 충분합니다. 한 가지 주의할 점은

swap을 사용해서는 안 된다는 것입니다. Linux 스왑을 끄는 것이 가장 좋습니다.

로드 밸런싱/가속

可能上面说缓存的时候,有人第一想的是页面静态化,所谓的静态html,我认为这是常识,不属于要点了。页面的静态化随之带来的是静态服务的

负载均衡和加速。我认为Lighttped+Squid是最好的方式了。

LVS b3c39e73f82b358bad409308ba9884dclighttped====>squid(s) ====lighttpd

上面是我经常用的。注意,我没有用apache,除非特定的需求,否则我不部署apache,因为我一般用php-fastcgi配合lighttpd,
性能比apache+mod_php要强很多。

squid的使用可以解决文件的同步等等问题,但是需要注意,你要很好的监控缓存的命中率,尽可能的提高的90%以上。
squid和lighttped也有很多的话题要讨论,这里不赘述。

存储

存储也是一个大问题,一种是小文件的存储,比如图片这类。另一种是大文件的存储,比如搜索引擎的索引,一般单文件都超过2g以上。

小文件的存储最简单的方法是结合lighttpd来进行分布。或者干脆使用Redhat的GFS,优点是应用透明,缺点是费用较高。我是指你购买盘阵的问题。我的项目中,存储量是2-10Tb,我采用了分布式存储。这里要解决文件的复制和冗余。这样每个文件有不同的冗余,这方面可以参考google的gfs的论文。

大文件的存储,可以参考nutch的方案,现在已经独立为Hadoop子项目。(你可以google it)

其他:此外,passport等也是考虑的,不过都属于比较简单的了。

四:高并发高负载网站的系统架构之图片服务器分离

大家知道,对于Web 服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他 们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用 服务器和图片服务器上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule, 保证更高的系统消耗和执行效率。

利用Apache实现图片服务器的分离

缘由:

起步阶段的应用,都可能部署在一台服务器上(费用上的原因),第一个优先分离的,肯定是数据库和应用服务器。第二个分离的,会是什么呢?各有各的考虑,我所在的项目组重点考虑的节约带宽,服务器性能再好,带宽再高,并发来了,也容易撑不住。因此,我这篇文章的重点在这里。这里重点是介绍实践,不一定符合所有情况,供看者参考吧,环境介绍:

WEB应用服务器:4CPU双核2G, 内存4G

部署:Win2003/Apache Http Server 2.1/Tomcat6

数据库服务器:4CPU双核2G, 内存4G

部署:Win2003/MSSQL2000

步骤:

步骤一:增加2台配置为:2CPU双核2G,内存2G普通服务器,做资源服务器

部署:Tomcat6,跑了一个图片上传的简单应用,(记得指定web.xml的),并指定域名为res1.***.com,res2.***.com,采用

ajp协议

步骤二:修改Apache httpd.conf配置

原来应用的文件上传功能网址为:

1、/fileupload.html

2、/otherupload.html

httpd.conf中增加如下配置


ServerAdmin webmaster@***.com
ProxyPass /fileupload.html balancer://rescluster/fileupload lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3
ProxyPass /otherupload.html balancer://rescluster/otherupload.html lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3
#
BalancerMember ajp://res1.***.com:8009 smax=5 max=500 ttl=120 retry=300 loadfactor=100 route=tomcat1
BalancerMember ajp://res2.***.com:8009 smax=5 max=500 ttl=120 retry=300 loadfactor=100 route=tomcat2
< /VirtualHost>

步骤三,修改业务逻辑:

所有上传文件在数据库中均采用全url的方式保存,例如产品图片路径存成:http://res1.***.com/upload/20090101/product120302005.jpg

现在,你可以高枕无忧了,带宽不够时,增加个几十台图片服务器,只需要稍微修改一下apache的配置文件即可。

五:高并发高负载网站的系统架构之数据库集群和库表散列

大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。

  在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。

  위에서 언급한 데이터베이스 클러스터는 아키텍처, 비용, 확장성 측면에서 사용되는 DB 유형에 따라 제한되므로 애플리케이션 관점에서 시스템 아키텍처 개선을 고려해야 합니다. 라이브러리 테이블 해싱은 일반적으로 가장 많이 사용됩니다. 효과적인 솔루션 계획. 우리는 데이터베이스를 분리하기 위해 애플리케이션에 비즈니스 및 애플리케이션 또는 기능 모듈을 설치한 다음 특정 전략을 사용하여 사용자 테이블과 같은 특정 페이지 또는 기능에서 더 작은 데이터베이스 해시를 수행합니다. 사용자 ID에 따른 테이블을 생성하여 저렴한 비용으로 시스템 성능을 향상시킬 수 있으며 확장성이 좋습니다. 소후의 포럼은 포럼의 사용자, 설정, 게시물 및 기타 정보를 데이터베이스로 분리한 다음 섹션과 ID에 따라 데이터베이스와 게시물 및 사용자 테이블을 해싱하는 구조를 채택하고 있으며, 마지막으로 구성에서 간단하게 구성할 수 있습니다. 이를 통해 시스템은 언제든지 저비용 데이터베이스를 추가하여 시스템 성능을 보완할 수 있습니다.

클러스터 소프트웨어 분류:

일반적으로 클러스터 소프트웨어는 초점 방향과 해결하려는 문제에 따라 세 가지 주요 범주로 나뉩니다. 고성능 클러스터(HPC), 로드 밸런싱 클러스터( 로드 밸런싱 클러스터(LBC), 고가용성 클러스터(HAC).

클러스터 내 여러 시스템을 사용하여 동일한 작업을 완료하는 고성능 클러스터(HPC)는 단일 시스템보다 작업 완료 속도와 안정성을 훨씬 더 높게 만듭니다. 독립 실행형 성능의 단점을 보완합니다. 이 클러스터는 일기 예보 및 환경 모니터링과 같이 대용량 데이터와 복잡한 계산이 있는 환경에서 널리 사용됩니다.

클러스터에서 여러 단일 시스템을 사용하여 많은 병렬 작업을 완료하는 로드 밸런스 클러스터(LBC). 일반적으로 응용 프로그램을 사용하는 사람이 많으면 사용자 요청에 대한 응답 시간이 늘어나고 시스템 성능에도 영향을 미칩니다. 로드 밸런싱 클러스터를 사용하면 클러스터의 모든 시스템이 사용자의 요청에 응답할 수 있습니다. 사용자가 서비스 요청을 발행한 후 클러스터는 로드가 가장 적고 서비스가 가장 좋은 시스템을 선택하여 요청을 수락하고 응답합니다. 이러한 방식으로 클러스터를 사용하여 가용성과 안정성을 높일 수 있습니다. 시스템의. 이러한 유형의 클러스터는 웹사이트에서 일반적으로 사용됩니다.

클러스터 내 시스템의 중복성을 사용하는 고가용성 클러스터(HAC)는 시스템의 머신이 손상되면 다른 백업 머신이 이를 신속하게 인수하여 시작할 수 있습니다. 서비스를 받고 결함이 있는 기계가 수리되어 반환될 때까지 기다립니다. 클러스터에서 서비스 가용성을 최대화합니다. 이러한 유형의 시스템은 일반적으로 시스템 신뢰성에 대한 요구 사항이 높은 은행 및 통신 서비스와 같은 분야에서 널리 사용됩니다.

2 데이터베이스 클러스터 현황

데이터베이스 클러스터는 컴퓨터 클러스터 기술을 데이터베이스에 도입하여 구현됩니다. 각 제조업체는 아키텍처가 얼마나 완벽하다고 주장하지만 Oracle이 선두에 있고 모두가 그 완벽함을 바꿀 수는 없습니다. 이에 따라 Oracle RAC는 클러스터 솔루션 측면에서 여전히 Microsoft를 포함한 다른 데이터베이스 공급업체보다 앞서 있습니다. 이는 고가용성, 고성능, 데이터베이스 로드 밸런싱 및 편리한 확장에 대한 고객의 요구를 충족할 수 있습니다. S ORACLE의 RAC(Real Application Cluster)

Microsoft SQL Cluster Server(MSCS)

B2 Udb 고가용성 클러스터(UDB)

Sybase Ase 고가용성 클러스터(ASE)

Mysql 고가용성 클러스터(MySQL CS )


IO 기반 타사 HA(고가용성) 클러스터

현재 주요 데이터베이스 클러스터 기술에는 위의 6가지 범주가 포함되며, 일부는 데이터베이스 제조업체가 직접 개발한 것입니다. ; 타사 클러스터 회사와 협력하여 개발하는 데이터베이스 공급업체도 있으며, 다양한 클러스터에서 구현하는 기능과 아키텍처도 다릅니다.


RAC(Real Application Cluster, Real Application Cluster)

는 Oracle9i 데이터베이스에 사용되는 신기술이자 그리드 컴퓨팅 환경을 지원하는 오라클 데이터베이스의 핵심 기술이기도 합니다. 이 기술의 등장은 기존 데이터베이스 애플리케이션이 직면한 중요한 문제인 고성능, 높은 확장성 및 저렴한 가격 간의 모순을 해결합니다. 오랫동안 오라클은 RAC(Real Application Cluster) 기술로 클러스터 데이터베이스 시장을 장악해 왔습니다.


6: 높은 동시성 및 고부하 웹 사이트의 시스템 아키텍처에 캐시를 적용합니다.

캐시라는 단어는 누구나 기술에 종사하고 있으며 캐싱이 여러 곳에서 사용됩니다. 웹 사이트 아키텍처 및 웹 사이트 개발에서 캐싱도 매우 중요합니다. 여기서는 먼저 가장 기본적인 두 가지 캐시에 대해 이야기합니다. 고급 및 분산 캐싱에 대해서는 나중에 설명합니다.

아키텍처 캐싱과 관련하여 Apache에 익숙한 사람이라면 Apache가 자체 캐싱 모듈을 제공하거나 캐싱을 위해 추가 Squid 모듈을 사용할 수 있다는 것을 알 것입니다. 두 방법 모두 Apache의 액세스 응답 기능을 효과적으로 향상시킬 수 있습니다.

  웹사이트 프로그램 개발 시 캐시, 리눅스에서 제공하는 메모리 캐시는 흔히 사용되는 캐시 인터페이스로, 예를 들어 자바로 개발할 때 메모리 캐시를 호출해 일부 데이터를 캐시하고 통신할 수 있다. 일부 대규모 커뮤니티에서 사용되는 구조입니다. 또한 웹 언어 개발을 사용할 때 각 언어에는 기본적으로 자체 캐시 모듈과 메서드가 있습니다. PHP에는 Pear의 캐시 모듈이 있고 Java에는 훨씬 더 많은 .net이 있지만 분명히 있을 것이라고 생각합니다.

Java 오픈 소스 캐시 프레임워크

JBossCache/TreeCache JBossCache는 엔터프라이즈 수준 애플리케이션 데이터를 캐시하여 성능을 향상시킬 수 있는 복제된 트랜잭션 캐시입니다. 캐시 데이터가 자동으로 복제되므로 Jboss 서버 간 클러스터 작업을 쉽게 수행할 수 있습니다. JBossCache는 Jboss Application Service 또는 기타 J2EE 컨테이너를 통해 MBean 서비스를 실행할 수 있습니다. 물론 독립적으로 실행할 수도 있습니다. JBossCache에는 TreeCache와 TreeCacheAOP라는 두 가지 모듈이 포함되어 있습니다. TreeCache - 트리 구조의 복제된 트랜잭션 캐시입니다. TreeCacheAOP - AOP를 사용하여 POJO를 동적으로 관리하는 "객체 지향" 캐시입니다.

OSCache OSCache 태그 라이브러리는 OpenSymphony에 의해 설계되었으며 기존 JSP 페이지 내에서 기능을 구현하는 획기적인 JSP 사용자 정의 태그 애플리케이션입니다. 빠른 메모리 버퍼링. OSCache는 널리 채택된 고성능 J2EE 캐싱 프레임워크로 모든 Java 애플리케이션에 대한 공통 캐싱 솔루션으로 사용할 수 있습니다. OSCache에는 다음과 같은 특징이 있습니다. 모든 개체를 캐시하고, JSP 페이지 또는 HTTP 요청의 일부를 제한 없이 캐시할 수 있으며, 모든 Java 개체를 캐시할 수 있습니다. 포괄적인 API 보유 - OSCache API는 모든 OSCache 기능을 제어할 수 있는 포괄적인 프로그램을 제공합니다. 영구 캐시 - 캐시는 마음대로 디스크에 기록될 수 있으므로 애플리케이션을 다시 시작해도 생성 비용이 많이 드는 데이터를 캐시된 상태로 유지할 수 있습니다. 클러스터링 지원 - 코드 수정 없이 클러스터 캐시 데이터를 개별적으로 구성할 수 있습니다. 캐시 레코드 만료 - 플러그형 새로 고침 전략(기본 성능에 필요하지 않은 경우)을 포함하여 캐시된 개체의 만료를 최대한 제어할 수 있습니다.

JCACHE JCACHE는 객체 생성, 공유 액세스, 스풀링, 무효화, 각 JVM의 일관성 등을 포함하여 Java 객체를 메모리에 임시로 캐싱하는 방법을 설명하는 곧 출시될 표준 사양(JSR 107)입니다. 제품 카탈로그 및 가격 목록과 같이 JSP 내에서 가장 자주 읽는 데이터를 캐시하는 데 사용할 수 있습니다. JCACHE를 사용하면 캐시된 데이터를 통해 대부분의 쿼리에 대한 응답 시간이 가속화됩니다(내부 테스트에 따르면 응답 시간은 약 15배 더 빠릅니다).
Ehcache Ehcache는 Hibernate에서 유래되었으며 Hibernate에서 데이터 캐싱 솔루션으로 사용됩니다.

Java 캐싱 시스템 JCS는 자카르타 프로젝트 Turbine의 하위 프로젝트입니다. 복합 버퍼 도구입니다. 개체는 메모리와 하드 디스크에 버퍼링될 수 있습니다. 버퍼 개체 시간 만료 설정이 있습니다. 또한 JCS를 통한 버퍼링을 통해 분산 아키텍처를 구축하여 고성능 애플리케이션을 구현할 수도 있습니다. 자주 액세스해야 하고 액세스할 때마다 많은 리소스를 소비해야 하는 일부 객체의 경우 임시로 버퍼에 저장하여 서비스 성능을 향상시킬 수 있습니다. 그리고 JCS는 좋은 버퍼링 도구입니다. 버퍼링 도구는 쓰기 작업보다 읽기 작업이 훨씬 더 많은 애플리케이션의 성능을 크게 향상시킬 수 있습니다.

SwarmCache SwarmCache는 간단하면서도 강력한 분산 캐싱 메커니즘입니다. 캐시된 인스턴스 간에 효율적으로 통신하기 위해 IP 멀티캐스트를 사용합니다. 클러스터된 웹 애플리케이션의 성능을 빠르게 향상시키는 데 이상적입니다.

ShiftOne ShiftOne 개체 캐시는 기본 개체 캐싱 기능을 제공하는 Java 라이브러리입니다. 구현된 전략은 선입선출(FIFO), 최근 사용(LRU), 최소 빈도 사용(LFU)입니다. 모든 전략은 요소의 크기를 최대화하고 생존 시간을 최대화합니다.

WhirlyCache Whirlycache는 메모리에 존재하는 객체에 대한 빠르고 구성 가능한 캐시입니다. 데이터베이스나 기타 비용이 많이 드는 프로세스를 쿼리하여 구축해야 하는 개체를 캐싱하여 웹 사이트나 애플리케이션의 속도를 높일 수 있습니다.

Jofti Jofti는 캐시 계층(EHCache, JBossCache 및 OSCache 지원) 또는 맵 인터페이스를 지원하는 스토리지 구조에서 객체를 색인화하고 검색할 수 있습니다. 프레임워크는 또한 인덱스의 개체 추가, 삭제 및 수정에 대한 투명성과 사용하기 쉬운 검색 쿼리 기능을 제공합니다.
cache4j 캐시4j는 간단한 API와 빠른 구현을 갖춘 Java 객체 캐시입니다. 그 기능은 다음과 같습니다: 멀티 스레드 환경을 위해 설계된 메모리 캐싱, 두 가지 구현: 동기화 및 차단, 다중 캐시 지우기 전략: LFU, LRU, FIFO, 강력한 참조(강한 참조) 및 소프트 참조(소프트 참조) 저장소 사용 물체.

Open Terracotta는 HTTP 세션 복제, 분산 캐싱, POJO 클러스터링 및 클러스터 간 JVM을 제공하여 분산 애플리케이션 조정을 달성하는 JVM 수준 오픈 소스 클러스터링 프레임워크입니다(코드 주입을 사용하므로 아무것도 수정할 필요가 없음). ).

sccache SHOP.COM에서 사용하는 개체 캐싱 시스템입니다. sccache는 프로세스 내 캐시이자 두 번째 수준의 공유 캐시입니다. 캐시된 개체를 디스크에 저장합니다. 관련 키, 모든 크기의 키, 모든 크기의 데이터를 지원합니다. 자동으로 가비지 수집을 수행하는 기능.

Shoal Shoal은 내결함성이 있고 안정적이며 사용 가능한 Java 애플리케이션을 구축하기 위한 인프라 지원을 제공하는 Java 기반의 확장 가능한 동적 클러스터 프레임워크입니다. 이 프레임워크는 특정 통신 프로토콜에 연결되기를 원하지 않지만 클러스터 및 분산 시스템 지원이 필요한 모든 Java 제품에 통합될 수도 있습니다. Shoal은 GlassFish 및 JonAS 애플리케이션 서버용 클러스터링 엔진입니다.

Simple-spring-Memcached Simple-Spring-Memcached는 MemCached에 대한 호출을 캡슐화하여 MemCached 클라이언트 개발을 매우 간단하게 만듭니다.

요약

위 내용은 Java 시스템의 높은 동시성 문제 해결의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.