開發這個模塊,是為了解決項目中的實際問題,思考設計的 。
本文原文連接: http://blog.csdn.NET/freewebsys/article/details/16944917 轉載請注明出處!
前言:
參考了下ngx_lua,Node.js,PHP三個進行的壓測對比。
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]
從各種性能測試來說ngx_lua似乎在CPU和內存上更勝一籌,同時
ngx_lua出奇的資源消耗比較穩定,不像php那樣波動比較大。
ngx_lua和Node.js幾乎比php快接近1倍。
同時ngx_lua模型也是單線程的異步的事件驅動的,工作原理和nodejs相同,
代碼甚至比nodejs的異步回調更好寫一些。
對于ngx的運維和配置相對比nodejs來說更加熟悉和有經驗。
1,總體設計思路
完全基于nginx層實現,nginx要開啟ssi。
(Server Side Includes:
http://wiki.nginx.org/HttpSsiModule
)
以最快的速度展示頁面,使用ssi直接讀取數據,不是ajax返回。
服務端使用lua讀取數據庫內容并顯示。
對應用的評論,使用mysql分區,按照itme_id進行hash。
設置成1024個分區,以后方便進行拆庫。保證每一個表的數據都不是很大。
(1024)是mysql能設置的最大分區數量。
流程:
ningx 請求 /blog/201311/127.html(博客內容已經靜態化了。)
↓
使用ssi將url里面的參數獲得調用lua評論模塊
↓
lua評論模塊,讀取數據庫。(如果壓力大,可以進行拆庫,做cache)
2,主要代碼
local?mysql=?require("resty.mysql")?? --評論查詢.?? 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)?? ????--使用數據庫連接池。保持連接.?? ????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>??發表于%s?? ????????????</div>?? ????????????<div?class="r_content?TextContent">%s</div>?? ????????</td></tr>?? ????</table>?? </li>?? ?? ]]?? ?? --設置頂部內容.?? 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;">發表評論</a>?? ????網友評論,共?%s條?? </h2>?? <ul>?? %s?? </ul>?? ????<ul?class="pager">?? ????????%s?? ????</ul>?? </div>?? ?? ]]?? ?? --設置循環li?? local?page_li?=?[[?? <li?class="page?%s"><a?href="?start=%s#comments">%s</a></li>?? ]]?? --輸入參數?count?start?limit?,總數,開始,分頁限制?? local?function?page(count,start,limit)?? ????--print(count,start,limit)?? ????local?page?=?math.ceil(count/limit)?? ????local?current_page?=?math.floor(start/limit)?+?1?? ????--判斷當前頁面不超出分頁范圍.?? ????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?)?? ????--打印頁數,開始,結束.?? ????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?? ?? --接收參數。?? local?uri?=?ngx.var.arg_uri?? --使用正則過濾url中的參數。?? local?year,item_id?=?string.match(uri,"/blog/(%d+)/(%d+).html")?? local?start?=?string.match(uri,"start=(%d+)")?or?"0"?? ?? start?=?tonumber(start)--將字符串轉換成數字。?? 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?? ????--對數據進行賦值.?? ????count??=?count[1].count?? else?? ????count?=?"0"?? end?? count?=?tonumber(count)--將字符串轉換成數字。?? ?? 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)??
代碼將功能實現了。后續可以拆分成多個模塊。其中生成分頁部分比較復雜。
運行效果:使用了oschina的頁面樣式。
其中/blog/201311/127.html是靜態html頁面。
速度超級快。
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';?? ????}??
在靜態頁面中增加ssi代碼,這樣就可以把uri當做參數傳遞了。
<!--# include virtual="/blog/list_comment?uri=$request_uri" -->
4,mysql修改打開文件數
因為開啟了分區,所以讀取文件數量肯定會多。
用ulimit -n查看打開文件數量。如果是1024,修改配置:
/etc/security/limits.conf 然后重啟系統
* 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生效,查看參數:
mysql> show variables like 'open%';
+------------------+-------+
| Variable_name ? ?| Value |
+------------------+-------+
| open_files_limit | 65536 |
+------------------+-------+
1 row in set (0.00 sec)
數據庫表,按照設計成分區表。將數據分散。
CREATE?TABLE?`comment`?(?? ??`id`?int(11)?NOT?NULL?auto_increment?COMMENT?'主鍵',?? ??`item_id`?int(11)?NOT?NULL?COMMENT?'評論項id',?? ??`uid`?int(11)?NOT?NULL?default?'0'?COMMENT?'評論用戶',?? ??`content`?text?NOT?NULL?COMMENT?'內容',?? ??`create_time`?datetime?NOT?NULL??COMMENT?'創建時間',?? ??PRIMARY?KEY??(`item_id`,`id`)?? )?ENGINE=MyISAM?DEFAULT?CHARSET=utf8?? PARTITION?BY?HASH?(`item_id`)?? PARTITIONS?1024;??
插入測試數據:
insert into comment(`item_id`,content,create_time) values(127,CONCAT("conent test ",RAND()*1000),now());
源代碼放到github上了。
https://github.com/luapkg/comment/
繼續完善評論模塊。
本文原文連接: http://blog.csdn.net/freewebsys/article/details/16944917 轉載請注明出處!
來源:http://blog.csdn.net/freewebsys/article/details/16944917
總結
以上是生活随笔為你收集整理的【nginx+lua高性能web应用开发(二):开发评论模块(ssi+mysql)】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。