2012-05-17 2 views
2

우리는 외부 게이트웨이를 사용하여 SMS를 송수신하는 클라이언트 - 서버 기반 애플리케이션을 보유하고 있습니다. 효율성과 성능을 높이기 위해 기존 아키텍처를 재 설계/수정하려고합니다. 같은 생각과 제안을 환영합니다. 최대치 도중 시간 동안 약. 3000 SMS는 클라이언트 - 서버 - 게이트웨이에서 시간당 전송됩니다.외부 게이트웨이를 통한 SMS 전송을위한 설계 비평

보내기 SMS는 클라이언트가 서버로 SMS를 전송

  1. 고유 SMSID를 기다린다는 (생성 기존 아키텍처

    10000 - 8000 사이 하루에 전송 SMS의 총량은 어디 수 서버 별 db 연결)

  2. 서버는 sms를 데이터베이스에 저장하고 sms를 게이트웨이로 보냅니다.
  3. 게이트웨이는 SMS를 핸드셋으로 보내고 고유 한 receiptid를 서버에 반환합니다. 데이터베이스
  4. 서버에서
  5. 서버는 고유의 receiptid 클라이언트에 (2 단계에서 생성)의 고유 SMSID를 반환

단계 1 -5 한 요청입니다 - 응답주기.

이 SMS를 게이트웨이 서버에게 메시지 서버는 전달에 전송에서 DB에서 메시지의 상태를 업데이트

  • 의 상태를 전송

    1. 를 인정//
    2. 등 알 수없는 실패 클라이언트는 이전에받은 smsid를 사용하여 메시지 상태를 수신하기 위해 정기적으로 서버를 폴링합니다.
    3. 클라이언트가 클라이언트 측에서 상태를 업데이트합니다.

    데이터베이스 설계

    모든 SMS는 데이터베이스에서 하나 하나 개의 SMS를 테이블에 저장됩니다. 처음에는 2006 년에 이라는 데이터가 있었으며 하나의 테이블에 약 5 백만 개의 레코드가있었습니다. 이제 데이터를 보관했으며 테이블에 현재 연도 데이터 만 있습니다.

    단점 - 클라이언트에 의한 대기 시간이 길어지면 때때로 연결 시간 초과 오류가 발생하여 동일한 메시지가 서버에 다시 전송됩니다. 서버가 중복 메시지임을 감지 할 수있는 방법이 없기 때문에 게이트웨이에 메시지를 다시 보내고 메시지를 보내 고객에게 중복 된 SMS를 보냅니다. - 여러 SELECT, UPDATE 쿼리가 매초마다 sms 테이블에서 수행되고 db 에 상당한 부하가 걸리고 시스템이 작동하지 않는 경우가 있습니다. 또한 데이터를 아카이브하는 메커니즘도 없습니다.

    새로운 아키텍처 클라이언트가 서버에 SMS를 전송

    1. 보내기 SMS 서버에서 (dB에 의해 생성 된) 고유 SMSID (열린 연결)
    2. 서버에 저장 SMS를 기다립니다

      데이터베이스에서 고유 한 smsid를 클라이언트에 반환합니다.

    단계 1- 2는 하나의 요청 - 응답주기입니다. SMS 를 검색하고 게이트웨이로 전송하거나 자바 멀티 스레딩을 사용할 수에 regulary에 데이터베이스 테이블을 폴링 크론을 사용

    1. 별도의 프로세스 ???
    2. 게이트웨이는 SMS를 핸드셋으로 보내고 고유 한 receiptid를 서버에 반환합니다.

    는 SMS를 인정 데이터베이스에

  • 서버는 고유의 receiptid는

    DB 디자인 상기와 동일하게 유지

      날짜를 기준으로 데이터를 분할하는
    1. 사용 PostgreSQL을 시간/범위 분할은, 기반 수신 상속 OR
    2. 매일 table1에서 table2로 데이터를 이동하는 별도의 스크립트. 유니온 쿼리를 사용하여 데이터를보고 및 검색하기위한 테이블을 조인 할 수 있습니다.

    더 나은 접근 방법은 무엇입니까?

  • 답변

    0

    먼저, 여러 테이블로 나누어야 할 필요성을 확신하지 못했습니다. 대량 작업보다 작은 테이블에서 검사 키를 쉽게 만들 수있는 대량 작업이 수행되지 않습니다. 그러나 당신의 경우에는 부분 색인의 개념이 도움이 될 가능성이 더 큽니다. 이 경우 현재 일일 기록에만 색인을 생성합니다.

    이와 관련하여 현재 날짜의 레코드에 대해서만 새 인덱스를 만들고 이전 인덱스를 삭제할 수 있습니다. 이 작업을 수행하는 경우이 부분 인덱스를 빠르게 만들 수 있도록 날짜를 인덱싱 할 수도 있습니다.

    일단 테스트 할 기회가 있으면 성능 관련 메모로 곧 수정하겠습니다.

    UPDATE 일반 날짜 인덱스가 충분하지 않을 것 같습니다 테스트 후

    . 당신이해야 할 일은 current_index bool 값을 붙이는 것과 같고, 기본값은 true입니다. 그런 다음 where current_index = true를 인덱싱 할 수 있으며 하루의 끝에서 이들을 false로 설정하여 인덱스에서 제외시킵니다.

    이렇게하면 쿼리를 빠르게 수행 할 수 있으므로 매일 새 인덱스를 추가하지 않아도되고 동시에 훨씬 작은 인덱스의 이점을 얻을 수 있습니다. 이렇게하면 성능면에서 두 가지 장점을 모두 얻을 수 있습니다.

    또한 this : cron을 사용하여 데이터베이스 테이블을 폴링하여 SMS를 검색하고 게이트웨이에 보내거나 java 멀티 스레딩을 사용할 수있는 프로세스를 분리 ???

    Postgres 문서에서 LISTEN 및 NOTIFY를 살펴보십시오. db 테이블을 폴링하지 마십시오. 그냥 알림을 받으면. 이렇게하면 상당한 오버 헤드를 줄일 수 있습니다. 안전하지 않기 때문에 페이로드에 대해 NOTIFY에 의존하지 마십시오. 응용 프로그램이 폴링해야 함을 알기위한 "트리거"로 사용하십시오.

    기본적으로 이것은 서버에 매우 가벼운 비동기 알림을 전송합니다 (트리거 btw에서이를 수행 할 수 있음). 그러면 앱이 폴링하는 것이 좋습니다. nodifying 트랜잭션이 커밋 될 때 알림이 전송됩니다.

    +0

    훌륭한 세부 답변이지만 테이블에서 대량 작업이 수행됩니다. Insert - 테이블에 SMS 데이터를 삽입하고 특정 sms에 대한 게이트웨이로부터 알림을 받으면 업데이트합니다. 피크 시간에는 테이블에 대한 필터가 포함 된 쿼리가 약 10-15 초 걸리고 상당한 시간이 걸립니다. 나는 LISTEN/NOTIFY와 부분적인 색인을 살펴보고 돌아올 것이다. – Angela

    +0

    그런 일이 벌어지고 있습니까? 한 번에 몇 개의 행을 삽입하거나 업데이트합니까? 부분 색인의 핵심은 작은 색인을 사용하여 대형 테이블을 공격 할 수있는 기능을 구입하고 색인이 테이블처럼 커질 필요가 없다는 것입니다. 쿼리에서 오랜 시간이 걸리는 경우 다른 무엇을 최적화 할 수 있는지 살펴볼 가치가 있습니다. –

    관련 문제