Java로 확장 성이 뛰어난 웹 서비스를 디자인하는 방법


15

동시 사용자가 2000 명인 웹 서비스를 만들고 있습니다. 서비스는 무료로 제공되므로 대규모 사용자 기반을 확보 할 것으로 예상됩니다. 향후 최대 50,000 명의 사용자를 확장해야 할 수도 있습니다.

/programming/2567254/building-highly-scalable-web-services 와 같은 문제를 해결하는 몇 가지 다른 질문이 이미 있습니다.

그러나 내 요구 사항은 위의 질문과 다릅니다.

예를 들어-내 응용 프로그램에는 사용자 인터페이스가 없으므로 이미지, CSS, 자바 스크립트는 문제가되지 않습니다. Java로되어 있으므로 HipHop을 사용하여 PHP를 원시 코드로 변환하는 것과 같은 제안은 쓸모가 없습니다.

그래서 나는 별도로 질문을하기로 결정했다.

이것은 내 프로젝트 설정입니다-

  1. Apache CXF를 사용한 나머지 웹 서비스
  2. 최대 절전 모드 3.0 (게으른 로딩 및 튠업을위한 사용자 지정 HQL과 같은 관련 최적화)
  3. 톰캣 6.0
  4. MySql 5.5

Java 기반 응용 프로그램을 확장 가능하게 만들기 위해 준수해야 할 모범 사례는 무엇입니까?


REST 서비스를 노출하는 경우 Varnish와 같은 리버스 프록시를 사용하면 큰 도움이됩니다. 데이터가 얼마나 신선한가? 관계형 데이터베이스가 필요하십니까? 데이터를 분할 할 수 있습니까? 기술 스택을 사용하면 가능한 적은 요청이 실제로 엔드 포인트에 도달하는 데 중점을 둡니다. Hazel cast / Gigaspaces와 같은 솔루션으로 메모리 내에서이 작업을 수행 한 적이 있습니까?
ebaxt 2016 년

@ebaxt 제안 해 주셔서 감사합니다. Gigaspaces는 오픈 소스 인 것 같습니다. 그러나 헤이젤 캐스트는 흥미로워 보입니다.
Kshitiz Sharma

1
@ebaxt "관계형 데이터베이스가 필요하십니까?" nosql을 채택하면 응용 프로그램 아키텍처가 크게 변경됩니다. 복잡성을 최소화하기 위해 노력하고 있습니다. 그러나 비용은 우리에게 중요한 요소가 아닙니다. 관계형 접근 방식을 고수하겠습니다.
Kshitiz Sharma

1
Postgres, MySQL 등을 사용할 수 있습니다. 인프라는 어떻습니까? 디스크 어레이를 사용할 수 있습니까? 서버가 같은 위치에 호스팅됩니까? 하트 비트 등으로 클러스터를 연결할 수 있습니까? 같은 서브넷에 넣을 수 있습니까?
edze 2016 년

1
나도 프로그래머입니다. 그러나 관계형 데이터베이스에 병목 현상이 발생하면이 질문으로 끝나는 경향이 있습니다. 시장 상황에 따라 일부 데이터베이스는 다른 데이터베이스보다 성능이 우수합니다. 그러나 서로 다른 기본 트랜잭션 격리 수준과 낙관적 동시성 대 비관적 동시성 등을 사용하고 있습니다.
edze

답변:


8

나는 과거의 문제를 다루었지만 여전히 현장에서 배울 것이 많다고 생각합니다. : 여기, 현재 소프트웨어 개발에이에 대한 몇 가지 생각을 거기 가장 흥미로운 분야 중 하나가이 찾을 수
MySQL의이 공정 은 데이터의 대규모 엄청난 양의 작업을하지 않는 한 충분한 데이터베이스,이 경우 당신은없는 NoSQL을 고려해 볼 수 있습니다 데이터베이스,하지만 당신은 신중에 가장 적합한되는 NoSQL 데이터베이스입니다 무엇을 조사해야 당신 이 필요합니다.

시스템에서 캐싱을 구현해야합니다. 가능한 한 많은 읽기 전용 데이터를 캐싱하거나 캐싱 전략을 정의해야합니다. 예를 들어, 사용자가 "오래된 데이터"를 다음과 같이 볼 수있는 시나리오가있었습니다. 최근 업데이트가 지난 1 시간 동안 발생한 한.
JBoss Cache 또는 Infinispan (분산 데이터 구조와 비슷 함) 또는 기타 인기있는 캐싱 프레임 워크를 고려할 것 입니다.
또한 Tomcat을 언급했듯이 일부 요청 응답 모듈에서 작업한다고 가정합니다. 주어진 요청의 범위에 존재하는 캐시 사용을 고려하십시오. 이것은 스레드 로컬 스토리지 와 연관된 간단한 HashMap 일 수도 있습니다 .
내 아이디어 는 Hibernate의 첫 번째 수준 캐시 와 매우 유사합니다 .

파일, 트랜잭션 및 기타 리소스는 파일을 열어 두는 데 비용이 많이 듭니다. 가능한 빨리 파일과 트랜잭션을 닫아야합니다. 그렇지 않으면 대규모 설정에서 재생산되는 버그가 발생합니다.

또한 2000 명의 동시 사용자가 무엇인지 이해해야합니다. 이는 2000 명의 사용자가 한 번에 서버에 액세스하고 있거나 시스템을 사용하고 있다는 의미입니까? 2000 명의 사용자가 서버에 소켓을 열려고하는 경우와 현재 클라이언트 측의 입력을 채우는 결과가 500 명, 1500 명만보고있는 경우를 구별하십시오.

클러스터링 사용을 고려해야합니다. 로드 밸런싱 , 고정 세션 (로드 밸런서가 동일한 세션에 대해 동일한 서버로 요청을 리디렉션 함) 등의 문제를 처리해야합니다 .

동기화 코드가 필요한 경우 동기화 전략을 신중하게 선택하십시오. 간단한 잠금이 사용 된 일부 시스템을 보았지만 ReaderWriterLock대부분의 액세스는 읽기 전용이므로 개선 할 수 있습니다.

동일한 매개 변수를 가진 요청에 대한 응답이 대부분 변경되지 않는 경우 가능하면 클라이언트 측 캐싱 및 유효성 검사를 수행하고 서버에 대한 호출을 저장하고 데이터의 차이 만 보내도록하십시오.
예를 들어, oVirt 오픈 소스 프로젝트에서는 지정된 가상 머신의 통계를 가져 오도록 요청합니다. VM의 일부 데이터는 거의 변경되지 않으므로 MD5 만 전송합니다. 데이터가 변경되면 MD5 값도 변경되면 MD5뿐만 아니라 전체 데이터를 가져 오기위한 요청을 수행합니다.

전에 최대 절전 모드를 언급했습니다. 신중하게 사용하는 것이 좋습니다. 많은 쓰기 작업과 적은 읽기 작업을 수행해야하는 경우에는 최대 절전 모드가 이상적이지 않을 수 있으므로 Spring-JDBC 를 래퍼로 사용하는 것이 좋습니다. JDBC.

데이터베이스를 현명하게 색인화하고 올바른 DB 체계를 사용하십시오. 사전 컴파일되고 최적화 된 저장 프로 시저 레이어 사용을 고려해보십시오

. 과거에는 jboss 4.2.1을 사용하여 mysql (대부분 읽기 전용 액세스)의 시스템 (단일 노드)을 처리했으며 동시에 2000에 도달 할 수 있다고 언급하고 싶습니다 사용자
(서버에 대해 2000 소켓을 여는 관점에서 한 번에 액세스하지 않음), 시스템 사용 / 탐색, JBoss Cache를 사용하고 가장 많이 액세스 한 데이터 중 일부를 캐시에 미리로드하거나, 우리가 깨달은 데이터는 "매우 인기가 있습니다" "하지만 우리의 솔루션은 아키텍처와 흐름에 좋았
습니다.이 경우에 말한 것처럼
더 많은 팁과 요령이 있지만 실제로는 아키텍처와 시스템에 어떤 흐름이 필요한지에 달려 있습니다. 행운을 빕니다!


저장된 procs를 제외하고는 저장된 procs를 사용하지 않습니다. 그리고 스레드 안전을 위해 해시 맵과 원자 값을 동시에 사용할 수 있습니다.
NimChimpsky

3

좋은 질문. 아마도 가장 좋은 방법이라고 말하기는 어렵지만 내 경험에서 시도해 볼 것입니다.

Java 기반 웹 응용 프로그램을 확장하는 가장 좋은 방법은 가능하면 상태 비 저장을 작성하는 것입니다. 이를 통해 응용 프로그램을 수평으로 확장 할 수 있으며 동시 사용자가 더 많은 경우 Tomcat 서버를 추가 할 수 있습니다.

그러나 언급했듯이 데이터베이스 연결에 문제가있을 수 있습니다. 그러나 내가 가진 질문은 데이터를 어떻게 얻습니까? 사용자가 생성했거나 타사에서 데이터를 얻습니까? 타사 응용 프로그램에서 수집 한 데이터 (예 : FB, Twitter 등)로 사용자에게 서비스를 제공하는 경우 추적 할 수있는 것은 마스터 데이터베이스에 쓰고 슬레이브 데이터베이스에 데이터를 복제하기 때문에 매우 중요합니다. 각 Tomcat 인스턴스에 할당됩니다. 그런 다음 각 Tomcat 서버는 자체 슬레이브 데이터베이스에서 가져올 수 있습니다.

 Are there faster alternatives to Mysql?

인 메모리 데이터 스토어가있는 MySQL 클러스터를 사용할 수 있습니다. 그러나 응용 프로그램에 약간의 변경이 필요할 수 있습니다. 는 sql joins최신 버전에서 동일한에 대한 개선 있기는하지만 잘 MySQL 클러스터에서 지원되지 않습니다. 비용이 중요하지 않은 경우 Oracle을 사용해 볼 수 있습니다.

캐싱 솔루션은 확실히 성능을 향상시킵니다. 그러나 모든 것은 전체 응용 프로그램의 아키텍처에 달려 있습니다. 데이터를 캐시로 푸시 할 때, 더티를 만들 때 (캐시에서 제거)를 잘 알고 있어야합니다.

다중 서버 환경에서로드 분배와 관련하여로드 밸런싱에 Apache를 사용하는 것보다로드 밸런서를 사용하는 것이 좋습니다.


"로드 밸런싱에 Apache를 사용하는 것보다로드 밸런서를 사용하는 것이 좋습니다."Apache가 아닌 경우 어떤 접근법 / 소프트웨어를 제안 하시겠습니까?
Kshitiz Sharma

기본적으로 네트워크 관리자가 구성 할 수있는로드 밸런서 하드웨어를 권장하고있었습니다. 물론이 프로젝트에는 추가 비용이 발생합니다. 이로드 밸런서는 자체 IP (가상 IP라고도 함)를 가지며 기본적으로이 IP를 도메인에 할당합니다. 요청이 오면 라운드 로빈 (사용 가능한 다른 알고리즘도) 방식으로 연결된 모든 서버로 요청을 라우팅합니다. 하드웨어가 옵션이 아닌 경우이 목적으로 아파치를 사용할 수 있지만,이 목적으로 만 아파치를 조정할 필요가 없으므로 하드웨어를 선호합니다.

동일한 작업을 수행하기 위해 httpd가있는 전용 서버를 사용하고 있습니다. 하드웨어는 문제가되지 않습니다.
Kshitiz Sharma

내가 올바르게 기억한다면 httpd와 mod_cluster를 사용할 수 있습니다. httpd와 mod_cluster를 확인하기 전에 하드웨어 LB의 "오버 킬 (overkill)"솔루션으로 가기 전에 신중하게 고려해야합니다.

@zaske-하드웨어로드 밸런서가 과도 할 수도 있습니다. 그러나 확장이 필요한 경우 더 많은 서버를 추가하여 쉽게 수행 할 수 있습니다.

2

현재 비슷한 수준의 시스템 (전문가 수준)을 설정 중이며 이것이 내가 선택한 디자인입니다.

  • 두 개의 Nginx로드 밸런서 (둘 다 활성, 둘 다 장애 조치, DNS 라운드 로빈과 균형 조정)
  • 마스터 마스터 복제 모드의 두 MySQL 데이터베이스
  • Tomcat 클러스터로서의 Tomcat 인스턴스 2 개
  • Tomcat 클러스터의 캐싱 및 세션 상태 공유를위한 2 개의 Memcached 인스턴스

이를 통해 중복성, 고 가용성, 확장 가능한 솔루션을 얻을 수 있습니다.

적절한 하드웨어의로드 밸런서는 포화 된 1gbit 라인을 쉽게로드 밸런싱합니다. SSL 오프 로딩을하기에도 좋은 장소입니다.

세션 정보를 memcached에 저장할 수 있습니다. Tomcat 인스턴스가 실패하는 경우 다른 Tomcat 인스턴스가 관련 세션 정보를 검색 할 수 있으며 클라이언트는이를 알지 못합니다. 이것을 끈적 끈적한 세션과 결합하는 것을 잊지 마십시오. (네트워크 트래픽을 줄이려면)

Tomcat 클러스터링에는 memcached를 사용하지 않고도 실시간으로 클러스터간에 세션 정보를 공유 할 수있는 옵션이 있습니다. 성능은 현명하다고 생각하지만 Memcached를 사용하는 것이 좋습니다.

이러한 응용 프로그램에서 더 많은 전원이 필요한 경우 :

  • Nginx :로드 밸런서를 더 추가하십시오. 그러나 이것이 곧 병목이 될 것이라고는 생각하지 않습니다.
  • Tomcat : Tomcat 클러스터의 크기를 쉽게 늘리거나 더 많은 클러스터를 추가 할 수 있습니다
  • MySQL : 읽기 전용 슬레이브를 추가하거나 클러스터 크기를 늘리십시오 (응용 프로그램에 따라 다르지만 REST 기반 응용 프로그램을 작성 했으므로 문제가되지 않습니다)
  • Memcached : 더 많은 노드를 추가하면 Memcached의 확장 성이 상당히 좋습니다.

응용 프로그램이 어떻게 구축되는지, 큰 리소스가 무엇인지 모르지만 (부하 테스트 중) 데이터베이스로드가 높으면 응용 프로그램과 데이터베이스 사이에 캐시를 추가하면 성능이 크게 향상 될 수 있습니다. 그러나 쿼리가 항상 다르면 캐싱이 도움이되지 않는 모든 것이 캐싱 가능한 것은 아닙니다.

내 조언은 VMware Workbench (또는 Similair 가상화 소프트웨어)를 다운로드하고 간단한 설정을 만드는 것입니다. 로드 밸런싱이나 클러스터링이 없으며 기본 사항 만 작동합니다. 하나씩 더 많은 기능 (밸런싱, 캐싱, 클러스터링 등)을 추가하고 각 주제에 대해 약간의 조사를 수행해야 올바른 선택을 할 수 있습니다.

이 프로세스 동안 동일한 성능 테스트를 계속 실행하면 설정에서 X 를 사용하는 것이 Y 를 사용하는 것보다 낫 거나 캐싱에 미치는 영향 등 을 직접 확인할 수 있습니다 .

결국, 이와 같은 설정은 실제로 응용 프로그램과 클라이언트의 요구 사항에 따라 다르며 모든 것은 각자의 강점과 약점을 가진 다양한 방법으로 수행 할 수 있습니다.

또 다른 질문?

행운을 빕니다!

웨슬리


헤이즐 캐스트? hazelcast.com
NimChimpsky 2016 년

캐싱 계층에 프레임 워크를 사용합니까, 아니면 SQL 쿼리에 여러 수동 해시를 사용하십니까?
djechlin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.