生活随笔
收集整理的這篇文章主要介紹了
【nginx+lua高性能web应用开发(二):开发评论模块(ssi+mysql)】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
開(kāi)發(fā)這個(gè)模塊,是為了解決項(xiàng)目中的實(shí)際問(wèn)題,思考設(shè)計(jì)的 。
本文原文連接: http://blog.csdn.NET/freewebsys/article/details/16944917 轉(zhuǎn)載請(qǐng)注明出處!
前言:
參考了下ngx_lua,Node.js,PHP三個(gè)進(jìn)行的壓測(cè)對(duì)比。
http://bluehua.org/demo/php.node.lua.html
ngx_lua ? Time per request: 3.065 [ms]
Node.js ? Time per request: 3.205 [ms]
PHP
? ? ?Time per request: 5.747 [ms]
從各種性能測(cè)試來(lái)說(shuō)ngx_lua似乎在CPU和內(nèi)存上更勝一籌,同時(shí)
ngx_lua出奇的資源消耗比較穩(wěn)定,不像php那樣波動(dòng)比較大。
ngx_lua和Node.js幾乎比php快接近1倍。
同時(shí)ngx_lua模型也是單線程的異步的事件驅(qū)動(dòng)的,工作原理和nodejs相同,
代碼甚至比nodejs的異步回調(diào)更好寫一些。
對(duì)于ngx的運(yùn)維和配置相對(duì)比nodejs來(lái)說(shuō)更加熟悉和有經(jīng)驗(yàn)。
1,總體設(shè)計(jì)思路
完全基于nginx層實(shí)現(xiàn),nginx要開(kāi)啟ssi。
(Server Side Includes:
http://wiki.nginx.org/HttpSsiModule
)
以最快的速度展示頁(yè)面,使用ssi直接讀取數(shù)據(jù),不是ajax返回。
服務(wù)端使用lua讀取數(shù)據(jù)庫(kù)內(nèi)容并顯示。
對(duì)應(yīng)用的評(píng)論,使用mysql分區(qū),按照itme_id進(jìn)行hash。
設(shè)置成1024個(gè)分區(qū),以后方便進(jìn)行拆庫(kù)。保證每一個(gè)表的數(shù)據(jù)都不是很大。
(1024)是mysql能設(shè)置的最大分區(qū)數(shù)量。
流程:
ningx 請(qǐng)求 /blog/201311/127.html(博客內(nèi)容已經(jīng)靜態(tài)化了。)
↓
使用ssi將url里面的參數(shù)獲得調(diào)用lua評(píng)論模塊
↓
lua評(píng)論模塊,讀取數(shù)據(jù)庫(kù)。(如果壓力大,可以進(jìn)行拆庫(kù),做cache)
2,主要代碼
local?mysql=?require("resty.mysql")?? --評(píng)論查詢.?? local?function?query_mysql(sql)?? ????local?db?=?mysql:new()?? ????db:connect{?? ????????host?=?"127.0.0.1",?? ????????port?=?3306,?? ????????database?=?"test",?? ????????user?=?"root",?? ????????password?=?"root"?? ????}?? ????local?res,?err,?errno,?sqlstate?=?db:query(sql)?? ????--使用數(shù)據(jù)庫(kù)連接池。保持連接.?? ????db:set_keepalive(0,?100)?? ????return?res?? end?? ?? local?comment_li?=?[[?? ?? <li?id="cmt_"?class="row_1">?? ????<table?width=""><tr>?? ????????<td?class="portrait">?? ????????????<a?href=""?name="rpl_277051035"?class="ShowUserOutline"><img?src="http://www.oschina.net/img/portrait.gif"></a>?? ????????</td>?? ????????<td?class="body">?? ????????????<div?class="r_title">?? ????????????????%s樓:<b>%s</b>??發(fā)表于%s?? ????????????</div>?? ????????????<div?class="r_content?TextContent">%s</div>?? ????????</td></tr>?? ????</table>?? </li>?? ?? ]]?? ?? --設(shè)置頂部?jī)?nèi)容.?? local?comment_html?=?[[?? ?? <div?class="Comments"?id="userComments">?? <h2>?? ????<a?name="comments"?href="#"?class="more">回到頂部</a>?? ????<a?href="#CommentForm"?class="more"?style="margin-right:10px;color:#ff3;">發(fā)表評(píng)論</a>?? ????網(wǎng)友評(píng)論,共?%s條?? </h2>?? <ul>?? %s?? </ul>?? ????<ul?class="pager">?? ????????%s?? ????</ul>?? </div>?? ?? ]]?? ?? --設(shè)置循環(huán)li?? local?page_li?=?[[?? <li?class="page?%s"><a?href="?start=%s#comments">%s</a></li>?? ]]?? --輸入?yún)?shù)?count?start?limit?,總數(shù),開(kāi)始,分頁(yè)限制?? local?function?page(count,start,limit)?? ????--print(count,start,limit)?? ????local?page?=?math.ceil(count/limit)?? ????local?current_page?=?math.floor(start/limit)?+?1?? ????--判斷當(dāng)前頁(yè)面不超出分頁(yè)范圍.?? ????current_page?=?math.min(current_page,page)?? ????current_page?=?math.max(current_page,1)?? ????local?is_first?=?(?current_page?==?1?)?? ????local?is_last?=?(?current_page?==?page?)?? ????--打印頁(yè)數(shù),開(kāi)始,結(jié)束.?? ????local?page_offset?=?3?? ????local?start_page?=?math.max(current_page?-?page_offset?,1)?? ????local?end_page?=?math.min(current_page?+?page_offset?,page)?? ????local?page_html?=?""?? ????if?not?is_first?then?? ????????page_html?=?page_html..[[<li?class="page?prev"><a?href="?start=]]?? ????????page_html?=?page_html..(current_page-2)*limit?? ????????page_html?=?page_html..[[#comments"><</a></li>?? ????????]]?? ????end?? ????for?i?=?start_page?,?end_page??do?? ????????local?tmp_current?=?""?? ????????if?current_page?==?i?then?? ????????????tmp_current?=?"current"?? ????????end?? ????????local?tmp_div?=?string.format(page_li,tmp_current,(i-1)*limit,i)?? ????????page_html?=?page_html..tmp_div?? ????end?? ????if?not?is_last?then?? ????????page_html?=?page_html..[[<li?class="page?next"><a?href="?start=]]?? ????????page_html?=?page_html..current_page*limit?? ????????page_html?=?page_html..[[#comments">></a></li>?? ????????]]?? ????end?? ????return?page_html?? end?? ?? --接收參數(shù)。?? local?uri?=?ngx.var.arg_uri?? --使用正則過(guò)濾url中的參數(shù)。?? local?year,item_id?=?string.match(uri,"/blog/(%d+)/(%d+).html")?? local?start?=?string.match(uri,"start=(%d+)")?or?"0"?? ?? start?=?tonumber(start)--將字符串轉(zhuǎn)換成數(shù)字。?? local?limit?=?10?? --拼接sql。?? ?? local?count_sql?=?"?select?count(*)?as?count?from?comment?where?item_id?=?"..item_id?? local?count?=?query_mysql(count_sql)?? ?? if?count?and?#count?>?0?then?? ????--對(duì)數(shù)據(jù)進(jìn)行賦值.?? ????count??=?count[1].count?? else?? ????count?=?"0"?? end?? count?=?tonumber(count)--將字符串轉(zhuǎn)換成數(shù)字。?? ?? local?sql?=?"?select?id,uid,content,create_time?from?comment?where?item_id?=?"..item_id.."?limit?"..start..","..limit?? local?res?=?query_mysql(sql)?? ?? local?comment_lis?=?""?? for?key,val?in?pairs(res)?do?? ????local?id?=?val["id"]?? ????local?uid?=?val["uid"]?? ????local?content?=?val["content"]?? ????local?create_time?=?val["create_time"]?? ????--拼接字符串.?? ????comment_lis?=?comment_lis..string.format(comment_li,key,uid,create_time,content)?? end?? ?? local?page_lis?=?page(count,start,limit)?? local?html?=?string.format(comment_html,count,comment_lis,page_lis)?? ngx.say(html)??
代碼將功能實(shí)現(xiàn)了。后續(xù)可以拆分成多個(gè)模塊。其中生成分頁(yè)部分比較復(fù)雜。
運(yùn)行效果:使用了oschina的頁(yè)面樣式。
其中/blog/201311/127.html是靜態(tài)html頁(yè)面。
速度超級(jí)快。
3,nginx配置
參考:
http://wiki.nginx.org/HttpSsiModule
http://wiki.nginx.org/HttpCoreModule
????gzip??on;?? ????ssi?on;?? ????root?/data/comment;?? location?/blog/list_comment?{?? default_type?'text/html';?? content_by_lua_file?'/data/comment/list_comment.lua';?? ????}?? location?/blog/save_comment?{?? default_type?'text/html';?? content_by_lua_file?'/data/comment/save_comment.lua';?? ????}??
在靜態(tài)頁(yè)面中增加ssi代碼,這樣就可以把uri當(dāng)做參數(shù)傳遞了。
<!--# include virtual="/blog/list_comment?uri=$request_uri" -->
4,mysql修改打開(kāi)文件數(shù)
因?yàn)殚_(kāi)啟了分區(qū),所以讀取文件數(shù)量肯定會(huì)多。
用ulimit -n查看打開(kāi)文件數(shù)量。如果是1024,修改配置:
/etc/security/limits.conf 然后重啟系統(tǒng)
* soft ? ?noproc ?65536
* hard ? ?noproc ?65536
* soft ? ?nofile ?65536
* hard ? ?nofile ?65536
然后修改my.conf配置文件:
vi /etc/my.cnf?
[mysqld]
datadir=/var/lib/MySQL
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
open_files_limit=65536
重啟mysql生效,查看參數(shù):
mysql> show variables like 'open%';
+------------------+-------+
| Variable_name ? ?| Value |
+------------------+-------+
| open_files_limit | 65536 |
+------------------+-------+
1 row in set (0.00 sec)
數(shù)據(jù)庫(kù)表,按照設(shè)計(jì)成分區(qū)表。將數(shù)據(jù)分散。
CREATE?TABLE?`comment`?(?? ??`id`?int(11)?NOT?NULL?auto_increment?COMMENT?'主鍵',?? ??`item_id`?int(11)?NOT?NULL?COMMENT?'評(píng)論項(xiàng)id',?? ??`uid`?int(11)?NOT?NULL?default?'0'?COMMENT?'評(píng)論用戶',?? ??`content`?text?NOT?NULL?COMMENT?'內(nèi)容',?? ??`create_time`?datetime?NOT?NULL??COMMENT?'創(chuàng)建時(shí)間',?? ??PRIMARY?KEY??(`item_id`,`id`)?? )?ENGINE=MyISAM?DEFAULT?CHARSET=utf8?? PARTITION?BY?HASH?(`item_id`)?? PARTITIONS?1024;??
插入測(cè)試數(shù)據(jù):
insert into comment(`item_id`,content,create_time) values(127,CONCAT("conent test ",RAND()*1000),now());
源代碼放到github上了。
https://github.com/luapkg/comment/
繼續(xù)完善評(píng)論模塊。
本文原文連接: http://blog.csdn.net/freewebsys/article/details/16944917 轉(zhuǎn)載請(qǐng)注明出處!
來(lái)源:http://blog.csdn.net/freewebsys/article/details/16944917
總結(jié)
以上是生活随笔為你收集整理的【nginx+lua高性能web应用开发(二):开发评论模块(ssi+mysql)】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。