例如,我第一次訪問請求返回json:{"n": 1}
我第100次訪問請求返回json:{"n": 100}
傳統的寫資料庫,再查資料庫返回,在並發大時好像不能保證,我該怎麼辦?這應該是最簡化了的問題了
回覆內容:
例如,我第一次訪問請求返回json:{"n": 1}
我第100次訪問請求返回json:{"n": 100}
傳統的寫資料庫,再查資料庫返回,在並發大時好像不能保證,我該怎麼辦?這應該是最簡化了的問題了
最簡單的方法就是建個自增id主鍵的mysql表,然後每來一次請求就插一條記錄,再讀出這條記錄,讀出的id就是你要的值。
接著就可以根據id值來輕鬆處理高並發的場景了,比如【秒殺】就可用id小於300且能被6整除的規則認為秒殺成功;【抽獎】可以用能被100整除(百分之一機率)作為中獎等等。
如果自己實作也無非就是單線程死循環處理socket請求維護一個全域變量,不如用現成的mysql方便可靠。
如果是java
的話,一個全局的AtomicLong
可以滿足你的需求吧,getAndIncrement
原子操作,再加上volatile
修飾,如果是其他語言,大同小異吧
使用redis中的setnx(id),單執行緒保證每次加1,而且還是記憶體資料庫,速度超快。
讀取操作:使用快取
寫入操作:使用佇列非同步寫入
純粹Java的話,可以把計數器物件做成單例,透過filter
攔截所有請求計算器加1(需要同步)。不知道你說的資料庫是什麼意思,{n : 100}
,n
是資料庫拿的?
其實你要做的是一個常駐內存的隊列,按請求先後做排隊處理.
單機上可以試試Linux內存文件系統(tmpfs)上/dev/shm讀寫SQLite.
讀文件不需要經過網絡,也不需要自行實現記憶體常駐,鎖,自增以及唯一約束.
<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進行自增,效率高,簡單,單機的話也可以考慮使用atomiclong(宕機重啟後失效)

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SublimeText3 Linux新版
SublimeText3 Linux最新版

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版
好用的JavaScript開發工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!