jquery中的ajax有個async:false,設為這個屬性就可以同時調用php
創新互聯公司是一家集網站建設,萬秀企業網站建設,萬秀品牌網站建設,網站定制,萬秀網站建設報價,網絡營銷,網絡優化,萬秀網站推廣為一體的創新建站企業,幫助傳統企業提升企業形象加強企業競爭力。可充分滿足這一群體相比中小企業更為豐富、高端、多元的互聯網需求。同時我們時刻保持專業、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們為更多的企業打造出實用型網站。
默認是true:異步,false:同步。
$.ajax({
type: "post",
url: "path",
cache:false,
async:false,
success: function(data){
}
});
在實際應用中,我們要管理一個客戶分類,實現對客戶分類的增加、刪除和修改等操作,如何讓這些操作變得更人性化,讓用戶操作起來更加方便成了我們必須研究的課題。
準備階段
您需要具備HTML和Jquery等前端知識,以及基本的PHP程序和MySql數據庫相關知識。要實現本文中的DEMO示例,首先需要一個mysql數據庫:
CREATE TABLE `catalist` ( `cid` int(11) NOT NULL auto_increment, `title` varchar(100) NOT NULL, `sort` mediumint(6) NOT NULL default '0', PRIMARY KEY (`cid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
其次在頁面中引入jquery庫,以及操作結果提示插件jNotify和刪除確認插件hiAlert。后者兩個插件在本站都有詳細的講解,讀者可以通過鏈接了解下:
將需要準備的文件一并加入到index.php的head之間。
script type="text/javascript" src="js/jquery.js"/script script type="text/javascript" src="js/jNotify.jquery.js"/script script type="text/javascript" src="js/jquery.alert.js"/script script type="text/javascript" src="js/global.js"/script link rel="stylesheet" type="text/css" href="css/alert.css" /
準備完畢我們進入主題。
index.php
index.php是主體頁面,讀取了數據庫中的分類數據,以列表展示,并提供了增加、刪除和修改的功能按鈕。
?php include_once('connect.php'); //連接數據庫 $query = mysql_query("select * from catalist order by cid asc"); while($row=mysql_fetch_array($query)){ $list .= "li rel='".$row['cid']."'span class='del' title='刪除'/span span class='edit' title='編輯'/spanspan class='txt'".$row['title']."/span/li"; } ?
以上代碼通過讀取數據表中的數據,返回一個列表字符串。然后我們要將字符串輸出到對應的列表中,代碼如下:
div class="selectlist" h3客戶類別/h3 ul id="catalist" ?php echo $list;? /ul pa href="javascript:;" onclick="addOpt()"新增一項/a/p /div
試著往數據表中添加幾條數據,可以看到一個分類列表。
CSS
.input{width:160px; padding:2px; border:1px solid #d3d3d3} .cur_tr{background:#ffc} .selectlist{width:280px; margin:30px auto; border:1px solid #ccc;} .selectlist h3{height:32px; line-height:32px; padding:0 4px; border-bottom:1px dotted #d3d3d3; background:#f7f7f7} .selectlist h3 span{float:right; font-weight:500} .selectlist ul{margin-top:4px; margin-left:20px; list-style-type: disc} .selectlist ul li{line-height:26px} .selectlist p{line-height:28px; padding-left:6px} .selectlist ul li span{width:20px; height:20px} .selectlist ul li span.edit{ float:right;background:url(images/edits.gif) no-repeat 0 5px; cursor:pointer} .selectlist ul li span.del,.selectlist ul li span.dels,.selectlist ul li span.cancer{ float:right;background:url(images/del.gif) no-repeat 0 5px; cursor:pointer} .selectlist ul li span.ok,.selectlist ul li span.oks{float:right;background:url(images/ok.gif) no-repeat 0 5px; cursor:pointer}
CSS我就不詳細講解,看下就明白了,最終顯示的效果如圖:
新增項操作
在global.js加入addOpt()函數:
function addOpt(){ var str = "lispan class='dels' title='取消'/spanspan class='ok' title='保存'/span input type='text' class='input' //li"; $("#catalist").append(str); }
通過單擊“新增一項”鏈接,向DOM中添加了一個新增項的輸入框。
當用戶輸入內容后,點擊“保存”,將會觸發一個ajax操作,先看代碼:
$(function(){ //保存新增項 $(".ok").live('click',function(){ var btn = $(this); var input_str = btn.parent().find('input').val(); if(input_str==""){ jNotify("請輸入類別!"); return false; } var str = escape(input_str); $.getJSON("post.php?action=addtitle="+str,function(json){ if(json.success==1){ var li = "li rel='"+json.id+"'span class='del' title='刪除' /spanspan class='edit' title='編輯'/spanspan class='txt'"+ json.title+"/span/li"; $("#catalist").append(li); btn.parent().remove(); jSuccess("恭喜,操作成功!"); }else{ jNotify("出錯了!"); return false; } }); }); });
首先獲取用戶輸入的內容,如果沒有輸入任何內容則提示用戶輸入內容,然后將用戶輸入的內容進行escape編碼,保證中文字符能正確傳輸給后臺程序識別。然后通過$.getJSON方法向后臺post.php發起一個異步的Ajax請求。后臺post.php接收參數值并進行相關處理,前端代碼通過響應后臺返回的JSON數據,如果新增成功,則向列表后面追加一項,并提示用戶“操作成功”,如果失敗則提示用戶“出錯了”。
如果要取消新增項操作,只需當單擊“取消”按鈕時執行以下代碼:
//取消新增項 $(".dels").live('click',function(){ $(this).parent().remove(); //將新增項移除 });
后臺post.php需要處理新增項內容,代碼如下:
include_once('connect.php'); //連接數據庫 $action = $_GET['action']; switch($action){ case 'add': //新增項 $title = uniDecode($_GET['title'],'utf-8'); $title = htmlspecialchars($title,ENT_QUOTES); $query = mysql_query("insert into catalist (cid,title) values (NULL,'$title')"); if($query){ $insertid = mysql_insert_id($link); $arr = array('id'=$insertid,'title'=$title,'success'=1); }else{ $arr = array('success'=2); } echo json_encode($arr); break; case '': break; }
通過接收前端提交的內容,進行解碼后,寫入數據表中,并輸出JSON數據格式供前臺處理。關于uniDecode()函數,讀者可以下載源碼了解,主要是為了正確讀取解析jquery通過異步提交的中文字符串。
添加項操作已經完成,下面請看刪除項操作。刪除項操作
回到global.js,在$(function(){})加入下面的代碼:
//刪除項 $(".del").live('click',function(){ var btn = $(this); var id = btn.parent().attr('rel'); var URL = "post.php?action=del"; hiConfirm('您確定要刪除嗎?', '提示',function(r){ if(r){ $.ajax({ type: "POST", url: URL, data: "id="+id, success: function(msg){ if(msg==1){ jSuccess("刪除成功!"); btn.parent().remove(); }else{ jNotify("操作失敗!"); return false; } } }); } }); });
顯然,通過單擊“刪除”按鈕,同樣是向后臺post.php發送一個ajax請求,將刪除項對應的參數ID發送給后臺并響應后臺處理結果,如果成功,則提示用戶“刪除成功”,并通過remove()將數據項移除,如果失敗,則提示“操作失敗”。
后臺post.php接收參數并作出相應的處理:
case 'del': //刪除項 $id = $_POST['id']; $query = mysql_query("delete from catalist where cid=".$id); if($query){ echo '1'; }else{ echo '2'; } break;
以上這段代碼片段,加在post.php的switch語句中,執行了刪除語句,并輸出執行結果供前端處理。
對于變化頻率非常快的數據來說,如果還選擇傳統的靜態緩存方式(Memocached、File System等)展示數據,可能在緩存的存取上會有很大的開銷,并不能很好的滿足需要,而Redis這樣基于內存的NoSQL數據庫,就非常適合擔任實時數據的容器。
但是往往又有數據可靠性的需求,采用MySQL作為數據存儲,不會因為內存問題而引起數據丟失,同時也可以利用關系數據庫的特性實現很多功能。
所以就會很自然的想到是否可以采用MySQL作為數據存儲引擎,Redis則作為Cache。而這種需求目前還沒有看到有特別成熟的解決方案或工具,因此采用Gearman+PHP+MySQL UDF的組合異步實現MySQL到Redis的數據復制。
MySQL到Redis數據復制方案
無論MySQL還是Redis,自身都帶有數據同步的機制,比較常用的MySQL的Master/Slave模式,就是由Slave端分析Master的binlog來實現的,這樣的數據復制其實還是一個異步過程,只不過當服務器都在同一內網時,異步的延遲幾乎可以忽略。
那么理論上也可以用同樣方式,分析MySQL的binlog文件并將數據插入Redis。但是這需要對binlog文件以及MySQL有非常深入的理解,同時由于binlog存在Statement/Row/Mixedlevel多種形式,分析binlog實現同步的工作量是非常大的。
因此這里選擇了一種開發成本更加低廉的方式,借用已經比較成熟的MySQL UDF,將MySQL數據首先放入Gearman中,然后通過一個自己編寫的PHP Gearman Worker,將數據同步到Redis。比分析binlog的方式增加了不少流程,但是實現成本更低,更容易操作。
Gearman的安裝與使用
Gearman是一個支持分布式的任務分發框架。設計簡潔,獲得了非常廣泛的支持。一個典型的Gearman應用包括以下這些部分:
Gearman Job Server:Gearman核心程序,需要編譯安裝并以守護進程形式運行在后臺
Gearman Client:可以理解為任務的收件員,比如在后臺執行一個發送郵件的任務,可以在程序中調用一個Gearman Client并傳入郵件的信息,然后就可以將執行結果立即展示給用戶,而任務本身會慢慢在后臺運行。
Gearman Worker:任務的真正執行者,一般需要自己編寫具體邏輯并通過守護進程方式運行,Gearman Worker接收到Gearman Client傳遞的任務內容后,會按順序處理。
以前曾經介紹過類似的后臺任務處理項目Resque。兩者的設計其實非常接近,簡單可以類比為:
Gearman Job Server:對應Resque的Redis部分
Gearman Client:對應Resque的Queue操作
Gearman Worker:對應Resque的Worker和Job
這里之所以選擇Gearman而不是Resque是因為Gearman提供了比較好用的MySQL UDF,工作量更小。
安裝Gearman及PHP Gearman擴展
以下均以Ubuntu12.04為例。
apt-get install gearman gearman-server libgearman-dev
檢查Gearman的運行狀況:
/etc/init.d/gearman-job-server status
* gearmand is running
說明Gearman已經安裝成功。
PHP的Gearman擴展可以通過pecl直接安裝
pecl install gearman
echo "extension=gearman.so"/etc/php5/conf.d/gearman.ini
service php5-fpm restart
但是實測發現ubuntu默認安裝的gearman版本過低,直接運行pecl install gearman會報錯
configure: error: libgearman version 1.1.0or later required
因此Gearman + PHP擴展建議通過編譯方式安裝,這里為了簡單說明,選擇安裝舊版本擴展:
pecl install gearman-1.0.3
Gearman + PHP實例
為了更容易理解后文Gearman的運行流程,這里不妨從一個最簡單的Gearman實例來說明,比如要進行一個文件處理的操作,首先編寫一個Gearman Client并命名為client.php:
?php
$client =newGearmanClient();
$client-addServer();
$client-doBackground('writeLog','Log content');
echo '文件已經在后臺操作';
運行這個文件,相當于模擬用戶請求一個Web頁面后,將處理結束的信息返回用戶:
php client.php
查看一下Gearman的狀況:
(echo status ; sleep 0.1)| netcat127.0.0.14730
可以看到輸出為
writeLog ? ? ? ?100.
說明已經在Gearman中建立了一個名為writeLog的任務,并且有1個任務在隊列等待中。
而上面的4列分別代表當前的Gearman的運行狀態:
任務名稱
在等待隊列中的任務
正在運行的任務
正在運行的Worker進程
可以使用watch進行實時監控:
watch -n 1"(echo status; sleep 0.1) | nc 127.0.0.1 4730"
然后我們需要編寫一個Gearman Worker命名為worker.php:
?php
$worker =newGearmanWorker();
$worker-addServer();
$worker-addFunction('writeLog','writeLog');while($worker-work());function writeLog($job){
$log = $job-workload();file_put_contents(__DIR__ .'/gearman.log', $log ."\n", FILE_APPEND | LOCK_EX);}
Worker使用一個while死循環實現守護進程,運行
php worker.php
可以看到Gearman狀態變為:
writeLog ? ? ? ?001
同時查看同目錄下gearman.log,內容應為從Client傳入的值Log content。
通過MySQL UDF + Trigger同步數據到Gearman
MySQL要實現與外部程序互通的最好方式還是通過MySQL UDF(MySQL user defined functions)來實現。為了讓MySQL能將數據傳入Gearman,這里使用了lib_mysqludf_json和gearman-mysql-udf的組合。
安裝lib_mysqludf_json
使用lib_mysqludf_json的原因是因為Gearman只接受字符串作為入口參數,可以通過lib_mysqludf_json將MySQL中的數據編碼為JSON字符串
apt-get install libmysqlclient-dev
wget
unzip master.zip
cd lib_mysqludf_json-master/
rm lib_mysqludf_json.so
gcc $(mysql_config --cflags)-shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
可以看到重新編譯生成了 lib_mysqludf_json.so 文件,此時需要查看MySQL的插件安裝路徑:
mysql -u root -pPASSWORD --execute="show variables like '%plugin%';"+---------------+------------------------+|Variable_name|Value|+---------------+------------------------+| plugin_dir ? ?|/usr/lib/mysql/plugin/|+---------------+------------------------+
然后將 lib_mysqludf_json.so 文件復制到對應位置:
cp lib_mysqludf_json.so /usr/lib/mysql/plugin/
最后登入MySQL運行語句注冊UDF函數:
CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
安裝gearman-mysql-udf
方法幾乎一樣:
apt-get install libgearman-dev
wget
tar -xzf gearman-mysql-udf-0.6.tar.gz
cd gearman-mysql-udf-0.6./configure --with-mysql=/usr/bin/mysql_config
-libdir=/usr/lib/mysql/plugin/
make make install
登入MySQL運行語句注冊UDF函數:
CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';
最后指定Gearman服務器的信息:
SELECT gman_servers_set('127.0.0.1:4730');
通過MySQL觸發器實現數據同步
最終同步哪些數據,同步的條件,還是需要根據實際情況決定,比如將數據表data的數據在每次更新時同步,那么編寫Trigger如下:
DELIMITER $$
CREATE TRIGGER datatoredis AFTER UPDATE ON data
FOR EACH ROW BEGIN
SET @ret=gman_do_background('syncToRedis', json_object(NEW.id as`id`, NEW.volume as`volume`));END$$
DELIMITER ;
嘗試在數據庫中更新一條數據查看Gearman是否生效。
Gearman PHP Worker將MySQL數據異步復制到Redis
Redis作為時下當熱的NoSQL緩存解決方案無需過多介紹,其安裝及使用也非常簡單:
apt-get install redis-server
pecl install redis
echo "extension=redis.so"/etc/php5/conf.d/redis.ini
然后編寫一個Gearman Worker:redis_worker.php
#!/usr/bin/env php?
$worker =newGearmanWorker();
$worker-addServer();
$worker-addFunction('syncToRedis','syncToRedis');
$redis =newRedis();
$redis-connect('127.0.0.1',6379);while($worker-work());function syncToRedis($job){global $redis;
$workString = $job-workload();
$work = json_decode($workString);if(!isset($work-id)){returnfalse;}
$redis-set($work-id, $workString);}
最后需要將Worker在后臺運行:
nohup php redis_worker.php
通過這種方式將MySQL數據復制到Redis,經測試單Worker基本可以瞬時完成。
php 高并發解決思路解決方案,如何應對網站大流量高并發情況。本文為大家總結了常用的處理方式,但不是細節,后續一系列細節教程給出。希望大家喜歡。
一 高并發的概念
在互聯網時代,并發,高并發通常是指并發訪問。也就是在某個時間點,有多少個訪問同時到來。
二 高并發架構相關概念
1、QPS (每秒查詢率) : 每秒鐘請求或者查詢的數量,在互聯網領域,指每秒響應請求數(指 HTTP 請求)
2、PV(Page View):綜合瀏覽量,即頁面瀏覽量或者點擊量,一個訪客在 24 小時內訪問的頁面數量
--注:同一個人瀏覽你的網站的同一頁面,只記做一次 pv
3、吞吐量(fetches/sec) :單位時間內處理的請求數量 (通常由 QPS 和并發數決定)
4、響應時間:從請求發出到收到響應花費的時間
5、獨立訪客(UV):一定時間范圍內,相同訪客多次訪問網站,只計算為 1 個獨立訪客
6、帶寬:計算帶寬需關注兩個指標,峰值流量和頁面的平均大小
7、日網站帶寬: PV/統計時間(換算到秒) * 平均頁面大小(kb)* 8
三 需要注意點:
1、QPS 不等于并發連接數(QPS 是每秒 HTTP 請求數量,并發連接數是系統同時處理的請求數量)
2、峰值每秒請求數(QPS)= (總 PV 數*80%)/ (六小時秒數*20%)【代表 80%的訪問量都集中在 20%的時間內】
3、壓力測試: 測試能承受的最大并發數 以及測試最大承受的 QPS 值
4、常用的性能測試工具【ab,wrk,httpload,Web Bench,Siege,Apache JMeter】
四 優化
1、當 QPS 小于 50 時
優化方案:為一般小型網站,不用考慮優化
2、當 QPS 達到 100 時,遇到數據查詢瓶頸
優化方案: 數據庫緩存層,數據庫的負載均衡
3、當 QPS 達到 800 時, 遇到帶寬瓶頸
優化方案:CDN 加速,負載均衡
4、當 QPS 達到 1000 時
優化方案: 做 html 靜態緩存
5、當 QPS 達到 2000 時
優化方案: 做業務分離,分布式存儲
五、高并發解決方案案例:
1、流量優化
防盜鏈處理(去除惡意請求)
2、前端優化
(1) 減少 HTTP 請求[將 css,js 等合并]
(2) 添加異步請求(先不將所有數據都展示給用戶,用戶觸發某個事件,才會異步請求數據)
(3) 啟用瀏覽器緩存和文件壓縮
(4) CDN 加速
(5) 建立獨立的圖片服務器(減少 I/O)
3、服務端優化
(1) 頁面靜態化
(2) 并發處理
(3) 隊列處理
4、數據庫優化
(1) 數據庫緩存
(2) 分庫分表,分區
(3) 讀寫分離
(4) 負載均衡
5、web 服務器優化
(1) nginx 反向代理實現負載均衡
(2) lvs 實現負載均衡
?php
class?Analytics_SomeConsumer?{
public?function?__construct()?{
$this-socket?=?socket_create(AF_INET,?SOCK_STREAM,?SOL_TCP);
socket_set_nonblock($this-socket);
socket_connect($this-socket,?$this-host,?$this-port);
$this-queue?=?array();
}
public?function?__destruct()?{
$payload?=?json_encode($this-queue);
#?...?//?wait?for?socket?to?be?writeable
socket_write($this-socket,?$payload);
socket_close($this-socket);
}
public?function?track($item)?{
array_push($this-queue,?$item);
}
?
可以全部存儲到服務器。然后服務器做一個隊列,后臺有個單獨線程處理圖片上傳到七牛的任務,圖片處理完成之后進行回調處理后續任務。
前端顯示處理中的類似字樣,然后等待后臺處理完成,前臺頁面再去進行修改。
分享標題:php異步請求數據庫 php如何實現異步進程
文章來源:http://m.kartarina.com/article14/dodedge.html
成都網站建設公司_創新互聯,為您提供企業建站、、企業網站制作、外貿建站、網站營銷、網站收錄
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯