Nginx(四)-- Nginx的扩展-OpenRestry
1. OpenResty 安装及使用
OpenResty 是一个通过 Lua 扩展 Nginx 实现的可伸缩的 Web 平台,内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
安装:
1. 下载安装包 https://openresty.org/cn/download.html
2. 安装软件包 tar -zxvf openresty-1.13.6.2.tar.gz。cd openrestry-1.13.6.2。./configure [默认会安装在/usr/local/openresty 目录] --prefix= 指定路径。make && make install
3. 可能存在的错误,第三方依赖库没有安装的情况下会报错 yum install readline-devel / pcre-devel /openssl-devel
安装过程和 Nginx 是一样的,因为他是基于 Nginx 做的扩展。开始第一个程序,HelloWorld cd /usr/local/openresty/nginx/conf 编辑 nginx 配置文件 nginx.conf
location / {
default_type text/html;
content_by_lua_block {
ngx.say("helloworld");
}
}
在 sbin 目录下执行.nginx 命令就可以运行,访问可以看到 helloworld。
建立工作空间:
为了不影响默认的安装目录,我们可以创建一个独立的空间来练习,先到在安装目录下创建 demo 目录,安装目录为/usr/local/openresty .mkdir demo。然后在 demo 目录下创建三个子目录,一个是 logs 、一个是 conf,一个是 lua。
进接下去演示一个实现 API网关功能的简单demo,然后提供一个算法去计算传入参数a,b的和。入conf 创建配置文件 vim nginx.conf :
worker_processes ;
error_log logs/error.log;
events {
worker_connections ;
}
http {
lua_package_path '$prefix/lua/?.lua'; //这里的¥prefix在启动的时候指定
lua_code_cache off; // lua脚本不需要重新加载
server {
listen ;
// 正则匹配访问路径
location ~ ^/api/([-_a-zA-Z0-]+) {
// 请求过滤一下
access_by_lua_file lua/check.lua;
content_by_lua_file lua/$.lua;
}
}
}
当来到的请求符合 ^/api/([-_a-zA-Z0-9/] 时 会在NGX_HTTP_CONTENT_PHASE HTTP请求内容阶段 交给 lua/$1.lua来处理。比如:
/api/addition 交给 lua/addition.lua 处理。
/api/lua/substraction 交给 lua/substraction .lua 处理。
接下去创建 三个 lua 脚本:params.lua:
local _M ={} // 定义一个模块
//定义一个方法
//该方法用于判断参数是否为数字
function _M.is_number(...)
local args={...}
local num;
for i,v in ipairs(arg) do
num=tonumber(v);
if nil ==num then
return false;
end
end
return true;
end
//将该模块返回出去
return _M;
写一个用于起到网关过滤的检查脚本check.lua:
//导入模块<br>local param=require("params");<br>//获取uri的参数
local args=ngx.req.get_uri_args();<br>//判断a,b是否为空且是否为数字
if not args.a or not args.b or not param.is_number(args.a,args.b) then
ngx.exit(ngx.HTTP_BAD_REQUEST);
return;
end
算法脚本 add.lua:
local args =ngx.req.get_uri_args();
ngx.say(args.a+args.b);
进入nginx的sbin目录执行:./nginx -p /usr/local/openresty/demo 【-p 主要是指明 nginx 启动时的配置目录】,此时会提示一个警告信息,无需理会,有强迫症把对应配置关了就还了:nginx: [alert] lua_code_cache is off; this will hurt performance in /usr/local/openresty/demo/conf/nginx.conf:12。通过访问http://192.168.254.137/api/add?a=1&b=3 能显示最后的值:
库文件使用:通过上面的案例,我们基本上对 openresty 有了一个更深的认识,其中我们用到了自定义的 lua 模块。实际上 openresty 提供了很丰富的模块。让我们在实现某些场景的时候更加方便。可以在 /openresty/lualib 目录下看到;比如在 resty 目录下可以看到 redis.lua、mysql.lua 这样的操作 redis 和操作数据库的模块。更多的库可以去百度,或者查找相关书籍。
4.什么是API网关
从一个房间到另一个房间,必须必须要经过一扇门,同样,从一个网络向另一个网络发送信息,必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”。那什么是 api 网关呢?
在微服务流行起来之前,api 网关就一直存在,最主要的应用场景就是开放平台,也就是 open api; 这种场景大家接触的一定比较多,比如阿里的开放平台;当微服务流行起来以后,api 网关就成了上层应用集成的标配组件.
为什么需要网关?
对微服务组件地址进行统一抽象,API 网关意味着你要把 API 网关放到你的微服务的最前端,并且要让 API 网关变成由应用所发起的每个请求的入口。这样就可以简化客户端实现和微服务应用程序之间的沟通方式.
当服务越来越多以后,我们需要考虑一个问题,就是对某些服务进行安全校验以及用户身份校验。甚至包括对流量进行控制。 我们会对需要做流控、需要做身份认证的服务单独提供认证功能,但是服务越来越多以后,会发现很多组件的校验是重复的。这些东西很明显不是每个微服务组件需要去关心的事情。微服务组件只需要负责接收请求以及返回响应即可。可以把身份认证、流控都放在 API 网关层进行控制。
5. OpenResty 实现灰度发布功能
在单一架构中,随着代码量和业务量不断扩大,版本迭代会逐步变成一个很困难的事情,哪怕是一点小的修改,都必须要对整个应用重新部署。 但是在微服务中,各个模块是是一个独立运行的组件,版本迭代会很方便,影响面很小。同时,为服务化的组件节点,对于我们去实现灰度发布(金丝雀发布:将一部分流量引导到新的版本)来说,也会变的很简单;所以通过 API 网关,可以对指定调用的微服务版本,通过版本来隔离。如下图所示
OpenResty 实现 API 网关限流及登录授权
OpenResty 为什么能做网关?
前面我们了解到了网关的作用,通过网关,可以对 api 访问的前置操作进行统一的管理,比如鉴权、限流、负载均衡、日志收集、请求分片等。所以 API 网关的核心是所有客户端对接后端服务之前,都需要统一接入网关,通过网关层将所有非业务功能进行处理。OpenResty 为什么能实现网关呢? OpenResty 有一个非常重要的因素是,对于每一个请求,Openresty 会把请求分为不同阶段,从而可以让第三方模块通过挂载行为来实现不同阶段的自定义行为。而这样的机制能够让我们非常方便的设计 api 网关。
Nginx 本身在处理一个用户请求时,会按照不同的阶段进行处理,总共会分为 11个阶段。而 openresty 的执行指令,就是在这 11 个步骤中挂载 lua 执行脚本实现扩展,我们分别看看每个指令的作用
init_by_lua : 当 Nginx master 进程加载 nginx 配置文件时会运行这段 lua 脚本,一般用来注册全局变量或者预加载 lua 模块。
init_woker_by_lua: 每个 Nginx worker 进程启动时会执行的 lua 脚本,可以用来做健康检查。
set_by_lua:设置一个变量。
rewrite_by_lua:在 rewrite 阶段执行,为每个请求执行指定的 lua 脚本。
access_by_lua:为每个请求在访问阶段调用 lua 脚本。
content_by_lua:前面演示过,通过 lua 脚本生成 content 输出给 http 响应。
balancer_by_lua:实现动态负载均衡,如果不是走 contentbylua,则走 proxy_pass,再通过 upstream 进行转发。
header_filter_by_lua: 通过 lua 来设置 headers 或者 cookie。
body_filter_by_lua:对响应数据进行过滤。
log_by_lua : 在 log 阶段执行的脚本,一般用来做数据统计,将请求数据传输到后端进行分析。
灰度发布的实现:
1.跟前面一样创建一个新的工作空间 mkdir gray。然后在 demo 目录下创建三个子目录,一个是 logs 、一个是 conf,一个是 lua。
2.编写 Nginx 的配置文件 nginx.conf
worker_processes ; error_log logs/error.log; events{
worker_connections ;
} http{
lua_package_path "$prefix/lualib/?.lua;;";
lua_package_cpath "$prefix/lualib/?.so;;";
//生产环境
upstream prod {//tomcat地址
server 192.168.254.137:;
}
// 预生产环境
upstream pre {//tomcat地址
server 192.168.254.139:;
} server {
listen ;
server_name localhost;
//当访问该路径就会进入lua脚本
location / {
content_by_lua_file lua/gray.lua;
}
// 定义变量在lua中会使用
location @prod {
proxy_pass http://prod;
} location @pre {
proxy_pass http://pre;
}
}
}
3.编写 gray.lua 文件
local redis=require "resty.redis";
local red=redis:new();
red:set_timeout();
local ok,err=red:connect("192.168.254.138",);
if not ok then
ngx.say("failed to connect redis",err);
return;
end
ok, err = red:auth("wuzhenzhao");
local_ip=ngx.var.remote_addr;
local ip_lists=red:get("gray");
if string.find(ip_lists,local_ip) == nil then
ngx.exec("@prod");
else
ngx.exec("@pre");
end
local ok,err=red:close();
4.
1.进入sbin目录 执行命令启动 nginx: ./nginx -p /usr/local/openresty/gray
2. 启动 redis,并设置 set gray 192.168.254.1,由于我这边是访问虚拟机,所以我本地ip去访问就是这个。
3. 通过浏览器运行: http://192.168.254.137/查看运行结果
修改 redis gray 的值, 到 redis 中 set gray 192.168.254.2. 再次运行结果,即可看到访问结果已经发生了变化.
Nginx(四)-- Nginx的扩展-OpenRestry的更多相关文章
- 快速掌握Nginx(四) —— Nginx日志切片和常用配置总结
1.Nginx日志管理 1.日志简单介绍 Nginx提供了日志记录的功能,日志文件在对我们管理网站十分有用,通过访问日志(access_log)我们可以获取请求来源.客户端信息.请求的资源等信息:通过 ...
- Nginx(四) nginx+consul+upasync 在ubnutu18带桌面系统 实现动态负载均衡
1.1 什么是动态负载均衡 传统的负载均衡,如果Upstream参数发生变化,每次都需要重新加载nginx.conf文件,因此扩展性不是很高,所以我们可以采用动态负载均衡,实现Upstream可配置化 ...
- Centos7 编译安装 Nginx PHP Mariadb Memcached 扩展 ZendOpcache扩展 (实测 笔记 Centos 7.3 + Mariadb 10.1.20 + Nginx 1.10.2 + PHP 7.1.0 + Laravel 5.3 )
环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1611.iso 安装步骤: 1.准备 1.0 查看硬 ...
- Centos7 编译安装 Nginx PHP Mariadb Memcached 扩展 ZendOpcache扩展 (实测 笔记 Centos 7.3 + Openssl 1.1.0e + Mariadb 10.1.22 + Nginx 1.12.0 + PHP 7.1.4 + Laravel 5.4 )
环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1611.iso 安装步骤: 1.准备 1.0 查看硬 ...
- Centos7 编译安装 Nginx PHP Mariadb Memcache扩展 ZendOpcache扩展 (实测 笔记 Centos 7.0 + Mariadb 10.1.9 + Nginx 1.9.9 + PHP 5.5.30)
环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1503-01.iso 安装步骤: 1.准备 1.1 ...
- 《nginx 四》双机主从热备
lvs+keepalived+nginx实现高性能负载均衡集群 LVS作用 LVS是一个开源的软件,可以实现传输层四层负载均衡.LVS是Linux Virtual Server的缩写,意思是Linux ...
- [译]深入 NGINX: 为性能和扩展所做之设计
来自:http://ifeve.com/inside-nginx-how-we-designed-for-performance-scale/ 这篇文章写了nginx的设计,写的很仔细全面, 同时里面 ...
- [linux][nginx] 通过nginx扩展nginx-rtmp-module简单做了一个流媒体直播
做的过程出现很多问题,环境其实就需要nginx就可以,然后就是在播放的问题,m3u8的格式,mac直接访问就支持,苹果系统原生H5支持m3u8,还有就是手机直接访问也支持!但是其他其他系统PC端不支持 ...
- nginx支持flv MP4 扩展nginx_mod_h264_streaming,nginx-rtmp-module-master,yamdi
./configure \ --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --conf-path=/usr ...
随机推荐
- hdu 1162 Eddy's picture (prim)
Eddy's pictureTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 力扣(LeetCode)旋转字符串 个人题解
给定两个字符串, A 和 B. A 的旋转操作就是将 A 最左边的字符移动到最右边. 例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' .如果在若干次旋转操作之后,A 能变成B ...
- python:类5——Python 的类的下划线命名有什么不同?
首先是单下划线开头,这个被常用于模块中,在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用 from a_module import * 导入时,这部分变量和函数不会被导入.不过值得注 ...
- ZeroC Ice发送大数据
继上文,我们使用ZeroC Ice传递大块数据时,通常有两种做法,一种是一次请求,另一种就是分多次请求(,这种做法在官方文档有例子).选哪一种根据需要而定. 当分多次请求来完成一大块数据,到底选择每次 ...
- futex-based pthread_cond 源代码分析
pthread_cond的实现使用了几个futex来协同进行同步,以及如何来实现的. 假定你已经明白 futex,futex-requeue,以及 pthread lowlevellock. < ...
- 如何利用快照( snapshot )功能快速定位性能问题
我们常常会遇到这样的困惑,收到用户或者客服的反馈,平台使用有问题,但是测试人员搭建环境后又没办法复现故障,最后导致问题没法解决,眼睁睁地看着用户流失. 这是因为线上生产环境非常复杂.很多时候是偶发性 ...
- web前端开发面试题(Vue.js)
1.active-class是哪个组件的属性?嵌套路由怎么定义? 答:vue-router模块的router-link组件. 2.怎么定义vue-router的动态路由?怎么获取传过来的动态参数? ...
- 学会使用这些,你的Windows可能会焕然一新
星选哥用Windows也已经好多年了,今天用室友的电脑才发现,桌面真可以影响一个人的心情,从而影响工作,学习,生活. 所以准备推荐一些好用且轻量的小工具,让你时时刻刻有个好心情. 室友的桌面(还有很多 ...
- JAVA中字符串常见操作
String str1="hello,world";String str2="Hello,World"; 1.字符串的比较:例,System.out.print ...
- 《程序人生》系列-害敖丙差点被开除的P0事故
你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub https://github.com/JavaFamily上已经收录有一线大厂面试点脑图.个人联系方式和技术交流群,欢迎Star和指教 ...