높은 동시성에서 http 요청은 어떻게 현재 요청의 절대 수를 반환할 수 있습니까?

WBOY
풀어 주다: 2016-08-18 09:16:21
원래의
1064명이 탐색했습니다.

예를 들어 첫 번째 액세스 요청에서 json이 반환되었습니다.
{"n": 1}

100번째 액세스 요청이 json을 반환합니다:
{"n": 100}

데이터베이스에 쓴 다음 데이터베이스를 확인하여 결과를 반환하는 기존 방법은 동시성이 클 경우 어떻게 해야 합니까? 이것은 가장 간단한 질문이어야 합니다

답글 내용:

예를 들어 첫 번째 액세스 요청에서 json이 반환되었습니다.
{"n": 1}

100번째 액세스 요청이 json을 반환합니다:
{"n": 100}

데이터베이스에 쓴 다음 데이터베이스를 확인하여 결과를 반환하는 기존 방법은 동시성이 클 경우 어떻게 해야 합니까? 이것은 가장 간단한 질문이어야 합니다

가장 간단한 방법은 자동 증가된 기본 키 id를 사용하여 mysql 테이블을 구축한 다음 각 요청에 대한 레코드를 삽입한 다음 해당 레코드를 읽는 것입니다. 읽기 ID는 원하는 값이 됩니다.

그러면 ID 값을 기준으로 높은 동시성 시나리오를 쉽게 처리할 수 있습니다. 예를 들어 [인스턴트 킬]은 ID가 300보다 작고 6으로 나누어지는 규칙을 사용하여 즉석 킬이 성공한 것으로 간주할 수 있습니다. ID가 300보다 작고 6으로 나누어지는 규칙을 사용하여 즉석 킬이 성공했다고 간주할 수 있습니다. [복권]은 ID가 100(1%)으로 나누어지는 규칙을 당첨으로 사용할 수 있습니다.

직접 구현한다면 소켓 요청을 처리하고 전역 변수를 유지하는 단일 스레드 무한 루프에 지나지 않습니다. 이미 만들어진 mysql을 사용하는 것만큼 편리하고 안정적이지는 않습니다.

java인 경우 전역 AtomicLong이 요구 사항을 충족할 수 있습니다. getAndIncrement 원자 연산과 volatile 수정이 추가되고 다른 언어인 경우에도 유사합니다

redis에서 setnx(id)를 사용하면 단일 스레드가 매번 1씩 증가를 보장하고, 메모리 내 데이터베이스이기도 하므로 매우 빠릅니다.

  • 읽기 작업: 캐시 사용

  • 쓰기 작업: 대기열을 사용한 비동기 쓰기

순수 Java에서는 카운터 개체를 싱글톤으로 만들고 filter을 통해 계산기를 1씩 늘리려는 모든 요청을 차단할 수 있습니다(동기화 필요). {n : 100}, n가 데이터베이스에서 가져온다는 것이 무슨 뜻인지 모르겠습니다.

실제로 원하는 것은 요청에 따라 대기열에 추가되고 처리되는 영구 메모리 대기열입니다.
단일 머신에서는 Linux의 /dev/shm에서 SQLite를 읽고 쓸 수 있습니다. 메모리 파일 시스템(tmpfs).
파일을 읽을 때 네트워크를 통과할 필요가 없으며 메모리 상주, 잠금, 자동 증가 및 고유 제약 조건을 구현할 필요가 없습니다.

<code><?php
header('Content-Type: text/plain; charset=utf-8');
// sudo mkdir -m 777 /dev/shm/app
$file = '/dev/shm/app/data.db3';
$ddl = "
BEGIN;
CREATE TABLE IF NOT EXISTS queue (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id      INTEGER
);
CREATE UNIQUE INDEX IF NOT EXISTS queue_user_id_idx ON queue(user_id);
COMMIT;
";
if(!file_exists($file)) {
    //多核下多进程并发时可能都会进入到这个判断分支,所以DDL中要用IF NOT EXISTS
    $db = new PDO('sqlite:'.$file);
    $db->exec($ddl); // pdo_sqlite 的 query 和 prepare 不支持一次执行多条SQL语句
} else {
    $db = new PDO('sqlite:'.$file);
}
$stmt = $db->prepare('INSERT INTO queue(user_id) VALUES(?)');
$stmt->execute(array(time())); //time()换成你的用户ID
echo $stmt->rowCount()."\n";   //查询中受影响(改动)的行数,插入失败时为0
echo $db->lastInsertId();      //插入的自增ID,插入失败时为0
// php -S 127.0.0.1:8080 -t /home/eechen/www >/dev/null 2>&1 &
// ab -c100 -n1000 http://127.0.0.1:8080/</code>
로그인 후 복사

가장 간단한 방법은 자동 증가를 위해 redis의 zset을 사용하는 것인데, 이는 효율적이고 간단합니다. 단일 머신을 사용하는 경우에는omiclong 사용을 고려할 수도 있습니다(종료하고 다시 시작하면 무효화됩니다)

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!