OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
OpenResty 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。
http://openresty.org/cn/
lua 脚本:https://www.runoob.com/lua/lua-tutorial.html
openresty 与nginx 的区别 openresty 底层基于 nginx 实现扩展功能 封装 能够整合lua脚本 实现更加高级灵活的功能
1.对nginx做额外扩展功能 例如 nginx连接 redis、MySQL 、es;
2.动态路由、限流 等高级灵活配置
3.nginx+lua 实现灰度发布
1.安装成功后,我们就可以使用 openresty 直接输出 html 页面。
content_by_lua是内容处理器,接受请求并输出响应,适用于location、location if。
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
default_type text/html;
content_by_lua '
ngx.say("mayikt Hello, World!
")
';
}
–输出响应内容体;(内容体结束后没有换行符;)
ngx.print(“mayikt”)
–输出响应内容体;(内容体结束后,输出一个换行符;)
ngx.say(“mayikt”)
2.cotent_by_lua_file 适应于复杂的 lua 脚本,专门放入一个文件中
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
default_type text/html;
content_by_lua_file lua/mayikt/mayikt01.lua;
}
}
1.连接mysql 数据库插入一条数据
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ", err)
return
end
db:set_timeout(5000)
local ok, err, errno, sqlstate = db:connect{
host = "127.0.0.1",
port = 3306,
database = "mayikt",
user = "root",
password="root",
max_packet_size = 1024 * 1024
}
if not ok then
ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate)
return
end
ngx.say("connected to mysql.");
local res, err, errno, sqlstate =
db:query("INSERT INTO `mayikt`.`mayikt_member` (`id`, `name`, `age`) VALUES (null, 'm', '11');")
if not res then
ngx.say("bad request: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
local cjson = require "cjson"
ngx.say("result: ", cjson.encode(res))
2.获取请求参数插入到数据库中
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ", err)
return
end
db:set_timeout(5000)
local ok, err, errno, sqlstate = db:connect{
host = "127.0.0.1",
port = 3306,
database = "mayikt",
user = "root",
password="root",
max_packet_size = 1024 * 1024
}
if not ok then
ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate)
return
end
ngx.say("connected to mysql.");
local uri_args=ngx.req.get_uri_args()
local name = uri_args["name"]
local age = uri_args["age"]
local insertSql="INSERT INTO `mayikt`.`mayikt_member` (`id`, `name`, `age`) VALUES (null,'"..name.."',"..age..");";
ngx.say(insertSql);
local res, err, errno, sqlstate =
db:query(insertSql)
if not res then
ngx.say("bad request: ", err, ": ", errno, ": ", sqlstate, ".")
return
end
local cjson = require "cjson"
ngx.say("result: ", cjson.encode(res))
“INSERT INTO mayikt
.mayikt_member
(id
, name
, age
) VALUES (null,'”…name…“',”…age…“);”;
nginx →接口→Redis→查询
--设置响应头类型
ngx.header.content_type="application/json;charset=utf8"
--获取请求中的参数ID
local uri_args = ngx.req.get_uri_args();
local id = uri_args["id"];
--获取本地缓存
--加载nginx缓存模块(需要在nginx.conf中定义)
--在nginx.conf中配置lua_shared_dict dis_cache 128m; 缓存模块
local cache_ngx = ngx.shared.dis_cache;
--根据ID 获取本地缓存数据
local adCache = cache_ngx:get('ad_cache_'..id);
ngx.say("adCache: ", adCache)
if adCache == "" or adCache == nil then
--引入mysql库
local mysql = require("resty.mysql");
--创建mysql对象
local db, err = mysql:new()
--连接
local ok, err, errno, sqlstate = db:connect{
host = "127.0.0.1",
port = 3306,
database = "mayikt",
user = "root",
password="root",
max_packet_size = 1024 * 1024
}
--查询db
local select_sql = "select * from mayikt_member where id="..id
local res, err, errno, sqlstate = db:query(select_sql)
if not res then
ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
--输出到返回响应中
local cjson = require "cjson"
local responsejson = cjson.encode(res);
ngx.say("result: ", responsejson)
--关闭连接
mysql:close()
--将redis中获取到的数据存入nginx本地缓存
cache_ngx:set('ad_cache_'..id, responsejson, 10*60); --设置缓存时间10分钟
local adCache1 = cache_ngx:get('ad_cache_'..id);
ngx.say(adCache1);
else
--nginx本地缓存中获取到数据直接输出
ngx.say("nginx缓存中查询",adCache)
end
nginx.conf 里面配置
#定义Nginx缓存模块,模块名字叫dis_cache,容量大小128M(与lua脚本的缓存相对应:local cache_ngx = ngx.shared.dis_cache;)
lua_shared_dict dis_cache 128m;
ngx.var.backend = "127.0.0.1:8081/"
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /agent {
set $backend '';
rewrite_by_lua_file lua/mayikt/agent.lua;
proxy_pass http://$backend;
}
}
先去让一小部分用户测试下 如果没有问题 让所有用户都可以访问。
测试数据----
httpclient
local uri_args=ngx.req.get_uri_args()
local user = uri_args["user"]
local requestBody ="http://127.0.0.1:9001/serviceAddress?user="..user
local http = require("resty.http")
local httpc = http.new()
local resp, err = httpc:request_uri(requestBody ,{
method = "GET"
})
if not resp then
ngx.say("request error :", err)
return
end
ngx.var.backend =resp.body;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.alibaba.nacos.discovery.NacosDiscoveryClient;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author 余胜军
* @ClassName NacosServiceAddress
* @qq 644064779
* @addres www.mayikt.com
* 微信:yushengjun644
*/
@RestController
public class NacosServiceAddress {
@Autowired
private DiscoveryClient discoveryClient;
private AtomicInteger atomicInteger = new AtomicInteger(1);
@Value("${mayikt.grayscaleUserConfig}")
private String[] grayscaleUserConfig;
@Value("${mayikt.grayscale.version}")
private String grayscaleVersion;
@Value("${mayikt.formal.version}")
private String formalVersion;
/**
* 根据服务名称获取接口地址
*
* @return
*/
@RequestMapping("/serviceAddress")
public String serviceAddress(HttpServletRequest request) {
// 判断用户是否是灰度用户
boolean isGrayscale = false;
String user = request.getParameter("user");
if (!StringUtils.isEmpty(user)) {
for (int i = 0; i < grayscaleUserConfig.length; i++) {
if (grayscaleUserConfig[i].equals(user)) {
isGrayscale = true;
break;
}
}
}
List<ServiceInstance> filterInstances = new ArrayList<>();
// 根据服务名称获取对应的接口地址
List<ServiceInstance> instances = discoveryClient.getInstances("mayikt-member");
boolean finalIsGrayscale = isGrayscale;
instances.forEach((serviceInstance -> {
String metadataVersion = serviceInstance.getMetadata().get("version");
//判断是否是灰度发布
String parameterVersion = finalIsGrayscale ? grayscaleVersion : formalVersion;
if (parameterVersion.equals(metadataVersion)) {
filterInstances.add(serviceInstance);
}
}));
int index = atomicInteger.incrementAndGet() % filterInstances.size();
ServiceInstance serviceInstance = filterInstances.get(index);
String resultAddres = serviceInstance.getHost() + ":" + serviceInstance.getPort();
return resultAddres;
}
}
报错找不到lua
拷贝到
D:\path\cloud\openresty-1.19.9.1-win64\openresty\lua\resty
引入 这个两个:
http://static.mayikt.com/http.lua
http:/static.mayikt.com/http_headers.lua
nginx 中需要配置:
location /grayscale {
set $backend '';
rewrite_by_lua_file lua/mayikt/grayscale.lua;
proxy_pass http://$backend;
}