使用多级缓存来减少数据库的访问达到加快网页的速度。但是随着用户的继续上涨,系统的压力越来越大。单一的缓存数据减少数据库的访问效果就不是特别的明显了。openresty?能够直接在 nginx 层直接对请求处理,而不需要每次都访问 tomcat,从而减轻服务器的压力。本文介绍?openresty 的相关教程。
更多精彩内容请看 web 前端中文站
http://www.lisa33xiaoq.net 可按 Ctrl + D 进行收藏
为了学习?openresty 我们准备了 3 台服务器,信息如下:
- A:(深圳,Nginx 环境,本地 Redis,tomcat 服务器)
- B:(广州,tomcat 服务器)
- C:(北京,tomact 服务器)
为了减少后端的相应时间,之前使用的是在应用里集成 ehcache 作为一级缓存,redis 作为二级缓存。这种架构存在一种特殊的情况:当 Nginx 将首页的请求分发给北京节点的时候,响应将变得极其缓慢,用户的请求需要从深圳到北京,再从北京回到深圳,光是延时就要耗费 40ms(最好的情况),由于网速是 1M/s,最坏的情况下,响应用户的请求也得耗费几秒。所以,为了减少这种极端情况,设计了这款架构。
步骤:
- 请求到达 nginx 后,openresty 通过 lua 读取本地缓存,如果不命中,则回源到 tomcat 集群。
- tomcat 集群首先从自己的服务器中读取一级缓存 Ehcache,如果没有命中,则继续回源到二级缓存。
- 读取二级缓存 Redis,如果依旧没有命中,则回源到 MySQL 服务器。
Openresty
安装过程可以直接参考官方文档:http://openresty.org/cn/download.html,安装前还需安装以下开发库:
yum install pcre-devel openssl-devel gcc curl
然后进行编译安装:
tar -xzvf openresty-VERSION.tar.gz cd openresty-VERSION/ ./configure make sudo make install
Nginx 相关配置
Openresty自带了 Nginx。所以,只要安装好了Openresty,即可直接使用 nginx 来配置。以下只是部分,需要全部的请查看?mynginxconfig.ngx。
http { include mime.types; default_type application/octet-stream; # 需要添加 lua 的相关库 lua_package_path "/opt/openresty/lualib/?.lua;;"; lua_package_cpath "/opt/openresty/lualib/?.so;;"; ... # web 前端中文站:www.lisa33xiaoq.net access_log logs/access.log main; sendfile on; keepalive_timeout 65; # www.lisa33xiaoq.net upstream backend { #consistent_hash was not configured hash $uri; server 47.95.10.139:8080; server 119.23.46.71:8080; server 119.29.188.224:8080; } server { listen 80; server_name www.lisa33xiaoq.net; # 精确匹配,打开首页的时候进入 location = / { default_type text/html; root html; index index.html index.htm; ... # 关闭缓存 lua 脚本,调试的时候专用 lua_code_cache off; content_by_lua_file /opt/lua/hello.lua; # 此处不要 proxy_pass 了,否则 lua 脚本没用 # proxy_pass http://backend; # web 前端中文站 } # 如果上面的不符合,则匹配下面的 location / { default_type text/html; root html; index index.html index.htm; # 对请求进行反向代理 proxy_pass http://backend; } } ... }
lua 脚本
脚本记得放在 /opt/lua/hello.lua 目录下,对应 nginx 的配置,同时需要引入 redis 模块。
local redis = require "resty.redis" local red = redis:new() -- www.lisa33xiaoq.net local request_uri = ngx.var.request_uri -- web 前端中文站 if (request_uri == "/" or request_uri == "/index.html") then red:set_timeout(1000) -- 1 sec red:connect("119.23.46.71", 6340) local ok, err = red:auth("root") if not ok then ngx.say("failed to connect: ", err) return end --缓存的首页放在 key 为 index 里 local resp, errr = red:get("index") if not resp then return end if resp == ngx.null then resp = "<h1>hello world</h1>" end --如果找到,则输出内容 ngx.print(resp) red:close() return end local pagenum = ngx.req.get_uri_args()["pagenum"] --因为在 nginx 中设置了 proxy_pass_request_headers off,即不讲请求头部传到 lua, --所以头部需要重新设置 ngx.req.set_header("Accept", "text/html,application/xhtml+xml,application/xml;") --这里回源到 tomcat 的时候,Accept-Encoding 默认为 gzip, --即返回来数据已经是 gzip 压缩过了的,返回到用户的时候又被压缩了一次, --会造成一堆乱码。所以将 Accept-Encoding 设置为空。 ngx.req.set_header("Accept-Encoding", "") local respp = ngx.location.capture("/index.do", { method = ngx.HTTP_GET, args = { pagenum = pagenum } }) --打印 ngx.print(respp.body) return
更新首页到 redis
每隔 20 秒直接访问后端进行首页的抓取,然后存储到 redis 里面,简单粗暴。
@Controller @SuppressWarnings("unchecked") public class TimeController { //logger private static final Logger logger = LoggerFactory.getLogger( TimeController.class); @Scheduled(cron = "0/20 * * * * ?") public void refreshIndex() throws Exception { String ip = IPUtils.getServerIp().replaceAll("/n", ""); if (REGULARIP.equals(ip)) { String content = HttpHelper.getInstance().get("http://119.29.188.224:8080"); JedisUtil.getInstance().set("index", content); } } }
以上就是总结了在实际应用中对?Openresty 的使用
【注:本文源自网络文章资源,由站长整理发布】