문제
다음과 관련하여 풀을 설정하는 가장 좋은 방법은 무엇입니까?
- 언제 연결을 만드나요?
- 언제 연결을 닫고 모든 연결을 닫으시겠습니까?
- 테스트 연결이 여전히 양호합니까?언제 어떻게?
- 최대 연결 수에 대한 적절한 수를 어떻게 파악합니까?
- 풀 사용자가 올바른 행동을 하는지 확인하기 위해 어떤 종류의 모니터링을 실시하고 있나요?하나의 잘못된 코드가 모든 것을 파괴하는 것을 막을 수 있습니까?
- 자신만의 풀을 작성했거나 타사 라이브러리를 사용해 보셨나요?
나는 이것이 불가지론적인 질문이라고 생각하지만 특정 데이터베이스/언어의 "기능"에 대한 의견은 환영합니다.예를 들어 일부 데이터베이스에서는 다른 데이터베이스에 비해 연결 속도가 느리거나 비용이 더 많이 들 수 있습니다.
명확히 하자면, 처음부터 풀을 작성할 생각은 없습니다. 이 질문은 풀링을 수행하는 기존 라이브러리를 구성하는 방법에 대한 것입니다.
해결책
나는 그것이 단지 디자인 패턴일 뿐이고 공통 라이브러리가 아니었을 때 Java로 데이터베이스에 대한 연결 풀을 작성했습니다.이제 Tomcat에 내장된 것을 사용합니다.
풀의 여러 측면을 모니터링하기 위해 스레드를 사용했고 풀의 동작을 제어하기 위해 여러 매개변수를 사용했습니다.
- 최소InPool="3"...처음 세 개는 출시 시 생성됩니다.수영장은 절대로 3 이하로 떨어지는 것이 허용되지 않습니다.
- maximumIdleTimeBeforeRemoval="60"...연결이 한 시간 동안 유휴 상태이면 연결을 삭제하고 새 연결을 만듭니다.유휴 시간은 아마도 수영장에 최소 3개만 있다는 의미일 것입니다.
- maximumInUseTimeBeforeRemoval="30"...해당 연결이 30분 이상 체크아웃된 경우 뭔가 문제가 있을 수 있습니다.그것을 기억하고 연결을 끊으십시오.
- maximumTimeBeforeRemoval="60"...60분 이상 경과한 경우 제거하십시오.
- maximumUsageBeforeRemoval="1000"...1000회 이상 체크아웃된 경우 제거하세요.
- 모니터 간격="15"...15분마다 위의 매개변수를 확인하십시오.
이것은 몇 년 동안 나에게 매우 도움이 되었습니다.내가 수영장을 본 것 중 가장 높은 것은 야생 엿보기 동안 151개의 연결이었습니다.일반적으로 수영장은 사용량이 많을 때 약 12개 정도였으며 이른 아침 시간에는 최소 3개까지 유휴 상태였습니다.
Oracle의 JDBC 씬 드라이버를 사용하고 Oracle 데이터베이스에 연결했습니다.
다른 팁
다음은 최근 구현에 사용한 이론적 근거입니다.
연결 풀에 두 가지 종류의 연결이 있습니다. 첫 번째는 준비가되었으며, 이는 개방적이지만 고객이 사용하지 않는 것을 의미합니다. 두 번째는 활성이며 클라이언트가 사용하는 의미입니다.
연결 풀링이 클라이언트를 요청하는 피크 속도에 따라 최소 N 및 최대 M의 최대 N 및 최대 M. N을 적은 수의 준비된 연결을 유지하도록하십시오. 준비된 연결 수가 0으로 떨어지면 더 큰 N이 필요합니다. 숫자가 일관되게 높으면 (예 : 10 이상) N이 더 낮아야합니다.
클라이언트가 연결을 원할 때 준비된 것 중 하나를 제공 한 다음 (활성화) NER이 완료되기를 기다리지 않으면 즉시 새 제품을 열어야합니다. 풀링의 이점을 잃게됩니다). 이것은 항상 최소한 준비된 연결이있을 수 있도록합니다. 클라이언트가 원할 때 준비가 아무도 없다면 새 제품을 만들 때 기다려야합니다.
클라이언트가 활성 연결로 완료되면 준비된 연결이 미만인 경우 준비 상태로 반환하십시오. 그렇지 않으면 닫습니다. 이것은 당신이 m 준비된 연결 이상을 갖지 못하게합니다.
오래된 연결을 방지하기 위해 준비된 연결을 주기적으로 재활용하십시오. 준비된 연결이 더 많으면 가장 오래된 연결을 닫으십시오. 그렇지 않으면 그것을 닫고 다른 것을 다시 열었습니다.
이것은 충분히 준비 할 수 있다는 이점이 있습니다 그리고 서버에 오버로드하지 않고 연결 풀에서 유쾌한 연결을 사용할 수 있습니다.
Jakarta Commons DBCP는 이미 귀하가 나열된 모든 작업을 수행합니다.
- 필요에 따라 연결을 생성하고 수영장에서 관리합니다.
- 일정 기간 동안 사용되지 않으면 연결을 닫을 수 있습니다.
- 연결하기 전에 연결에서 쿼리를 실행할 수 있으며 오류가 있으면 연결이 버려지고 새 새로운 것이 생성됩니다. 유휴 상태에서 연결을 주기적으로 테스트 할 수도 있습니다.
- 생성 될 연결과 준비가 된 최소 연결 수에 제한을 설정할 수 있습니다. 물론 한도는 응용 프로그램에 따라 다릅니다.
- 나는 방법을 모르지만 DBCP는 연결이 닫히지 않았을 때를 알고 있으며, 예외를 던져서 로그를 볼 때 무슨 일이 있었는지 알 수 있습니다.
- DBCP에는 매우 유용한 타임 아웃 매개 변수가 있습니다. 수영장의 모든 연결이 사용되는 경우 연결이 풀로 반환 될 시간이 기다리고 제한에 도달 할 때 사용할 수없는 경우 오류가 발생합니다.
최소 연결 수, 생성 할 최대 연결 수 및 타임 아웃을 사용하여 수영장을 미세 조정할 수 있습니다. 타임 아웃이 길면 연결 한계가 낮을 수 있지만 시간 초과가 짧아지면 더 많은 숫자가 필요할 수 있습니다. 이는 응용 프로그램의 수행 및 연결 사용 방법에 크게 좌우됩니다.
나는 당신이 당신의 연결을 사용하는 맥락이 무엇인지 잘 모르겠지만 나에게 효과가있는 것처럼 보일 수 있습니다.
SQL Server를 백엔드로 사용하고 캐싱의 조합을 사용하여 더 나은 성능을 얻습니다. 내 연습은 실제로 필요한 경우에만 연결을 열고 연결을 풀지 않아서 즉시 정리하고 SQL Activity에서 활성화 된 내용과 그렇지 않은 것을 정확히 모니터링 할 수 있도록하는 것입니다. 각 연결은 메모리를 차지하므로 필요하지 않을 때는 둔한 포효로 유지하는 것이 좋습니다.
연결에 응답하기 전에 열린 질문과 가까운 질문은 캐싱이 정말로 중요하다고 가정 해 봅시다. 캐시에서 객체를 얻으면 많은 시간을 절약 할 수 있습니다. DEV에서 캐싱이 켜져있을 때 ASP.NET 앱 중 일부에서는 대기 시간을 거의 측정 할 수는 없지만 DB 호출을 사용하면 통화를 완료하는 데 15ms에서 45m가 소요될 수 있으며 다른 대기 시간을 고려하지도 않습니다. 요인 또는 부하. 내가 사용하는 다른 방법은 내 데이터에 대한 좋은 객체 구조이므로 무언가가 변경되는 경우에만 DB 업데이트를 만듭니다. 내 객체에 몇 가지 방법을 구현했습니다. o 가능한 한 적은 작은 IO를 수행해야합니다.
그것은 우리 모두가 어느 시점에서 DB에 액세스하고 편지해야한다는 것을 알고 있으므로 두 가지 원칙을 따릅니다.
에너지를 절약하기 위해 문과 창문을 닫아 두십시오. 한 곳에서 열린 연결은 다른 곳에서 사용할 수 없음을 의미합니다 (또는 메모리 및 기타 리소스가 더 제한적 임). 우리는 우리에게 더 나은 성능을 얻었 기 때문에 풀링을 끄 었습니다.
연결이 열릴 때 가능한 한 배치 또는 한 번에 많은 일을합니다. 이것은 조금 더 복잡하므로 설명하겠습니다.
- 내가 사용한 방법 중 하나는 연결 객체를 파이프 아래로 전달하여 모든 객체가 하나의 연결 객체를 사용할 수 있도록하는 것입니다. 이로 인해 앱에 따라 10 개 이상이 아닌 한 가지 연결이 열리고 닫힙니다. 이에 대한 좋은 예는 통계를 수집하고 복잡한 주문 패턴을 해시하기 위해 SQL Server의 전력을 활용하는 구매 모델 중 하나입니다. 200k+ DB 조회 또는 앱이 무엇이든 할 때 연결을 계속 열고 닫는 것은 의미가 없습니다. 이것의 다른 부분은 객체를 사용할 때 업데이트를 묶어 연결을 열어 두는 시간을 줄이려고한다는 것입니다. 삽입 통화에서 SCOPE_IDENTITY를 수행하면 캐싱하기 전에 삽입물과 객체에 추가 할 고유 ID를 찾을 수 있습니다. ASP 앱을 처음 개발하고있는 날에 페이지가로드되기 시작하자마자 실제로 연결을 열었습니다. 더 이상 그렇게하는 것이 좋습니다. 이제 하루 종일 이러한 종류의 추상화와 계층에 큰 이점이 있습니다.
내 두 센트 :
데이터를 캐시하십시오! 데이터를 캐시하십시오! 데이터를 캐시하십시오! 캐시를 할 수없는 경우 가능한 한 적은 DB 액세스를 수행 한 다음 데이터를 캐시하십시오!