看了開濤的Nginx+Lua開發教程,非常感興趣。因此,本身也把環境搭建起來玩。html
跟開濤的不一樣,我使用Vagrant + Ansible來搭建(不要問我爲何不使用Docker)。這樣,全部的人只要兩條命令就能夠搭建好了,而不須要手工一條命令一條命令打。java
所謂使用Openresty來作讀服務,是指Openresty直接從數據源讀數據,而後渲染輸出,而不通過應用服務器,好比Tomcat服務器。Openresty 是一個基於Nginx和LuaJIT的動態Web開發平臺。我不知道京東是不是直接使用Openresty仍是本身編譯Nginx + Lua。反正,我直接使用Openresty。nginx
本次文章就是根據開濤的教程,實現使用lua-resty-template 作模塊引擎,使用Redis作數據源。我把Openresty和Redis都安裝在同一臺機器上,以方便作實驗,固然,若是你想裝在不一樣的服務器,只須要修改下配置就行了。如下是架構:git
整個步驟我都寫成了Ansible自動化配置腳本。因此,你已經不須要本身搭建。全部的代碼都託管在:http://git.oschina.net/zacker330/openresty-lab 。github
啓動前,你必須安裝Vagrant 和 Ansible 2.0+。redis
git clone https://git.oschina.net/zacker330/openresty-lab.git cd openresty-lab vagrant up ansible-playbook ./ansible/playbook.yml -i ./ansible/inventory -u vagrant -k >> 輸入ssh密碼 `vagrant`
PS. ansible-playbook須要經過ssh登陸上目標機器來執行咱們的任務。shell
接下來,咱們解釋下代碼。數組
Openresty的配置以下:瀏覽器
## 省去了一些不重要的nginx配置 http { default_type application/octet-stream; ## 省去了一些不重要的nginx配置 ## 初始化所須要對象 init_by_lua ' require "resty.core" redis = require "resty.redis" template = require "resty.template" template.caching(false); -- you may remove this on production '; server{ listen 80; server_name 192.168.8.10; charset utf-8; ## 指定 模板路徑 set $template_root "/usr/local/openresty/nginx/html/templates"; location ~ \.lsp$ { default_type text/html; content_by_lua 'template.render(ngx.var.uri)'; ## 訪問index.lsp,將使用index.lsp模板 } } }
頁面邏輯代碼 index.lsp:服務器
{% layout = "layouts/default.lsp" -- 模板 local blogid= ngx.var.arg_blogId local title = "博客標題" local author = {name = "fooname", gender = "female", level= 3} local description = "<script>alert(1);</script>" local content = "java8的流式處理極大了簡化咱們對於集合、數組等結構的操做,讓咱們能夠以函數式的思想去操做,<br/>本篇文章將探討java8的流式數據處理的基本使用。" local tags = {"life", "lua", "openresty"} local radar = {lua = 90, openresty = 80, nginx = 70} -- 使用nginx的內置變量 local a = ngx.var.arg_a local b = ngx.var.arg_b local ip = ngx.var.remote_addr -- 使用redis讀數據源 local red = redis:new() red:set_timeout(1000) local ok, err = red:connect("127.0.0.1", 6379) if not ok then ngx.say("failed to connect: ", err) return end local ok, err = red:lpush("list", a, b) local member, err = red:llen("list") %} <div> member: {{ member }}<br/> remote ip: {{ ip }} blogId: {{blogid}}<br/> 做者: {{author.name}} {{author.gender}} level: {{author.level}}<br/> description: {{description}} <br/> tags: {% for i = 1, #tags do %} {% if i > 1 then %},{% end %} {* tags[i] *} {% end %}<br/> </div>
最終訪問效果:http://192.168.8.10/index.lsp?a=12&b=asdfasdf&blogId=111
這種不通過應用服務器的方式,讀的速度彷佛更快,畢竟省去了中間的Tomcat服務。可是,誰來填充數據給Redis和什麼時機填充數據,又是另外一回事了。
開發過程彷佛有些麻煩,由於修改nginx配置後,不能像普通的頁面開發那樣立馬看到效果,還要nginx -s reload一下。這個,我想到的解決方案是使用Ruby的guard gem來監控文件變更,而後reload nginx配置,最後使用瀏覽器的livereload來自刷新頁面。https://github.com/guard/guard-livereload 目前尚未時間實現,但願有熱心朋友實現提pr。或者開濤能分享下他們的實踐。但願他本人能看到這篇博客。:P
2016.10 於深圳西麗人民醫院