01 . OpenResty简介部署,优缺点,压测,适用场景及用Lua实现服务灰度发布
简介
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 等都进行一致的高性能响应。
下载部署
wget https://openresty.org/download/openresty-1.13.6.2.tar.gz
cd openresty-1.13.6.2
./configure
make && make install
目录结构
[root@server openresty]# ls
bin COPYRIGHT luajit lualib nginx pod resty.index site
# 分析目录结构
# 相比Nginx源代码目录相比少了很多东西,少了的东西在bundle目录下。build是编译后生成的目标中间文件
# 在bundle目录中有很多模块,最核心的是Nginx源代码,nginx-相应的版本中,当前的openresty基于nginx-1.13.6.2这个版本进行二次开发。
/root/openresty-1.13.6.2/configure --help
# 查看configure脚本帮助文件
# 和nginx帮助文件基本没有太大的不同,只不过openresty集成了很多第三方模块
# 前缀带有without是默认是内置在编译版本中的
# 前缀带有with是默认是没有在编译版本中的
添加Lua代码启动
添加lua注意
/*
在nginx.conf 中实际是可以直接添加Lua代码,但是不能把Lua的语法Lua的源代码直接放在conf中,因为nginx的解析器它的配置语法是跟Lua代码是不相同的。
在openresty的nginx lua模块中,它提供了几条指令,其中有一条指令是content_by_lua
content_by_lua是在http请求处理的内容生成阶段,我们用Lua代码来处理。
*/
/*
openresty的Lua模块中提供了一些API 如ngx.say,会去生成http响应,浏览器在发起http请求中,它会在User-Agent这样的head中,
去添加当前浏览器的类型,我是xxx,我用了什么样的内核,用ngx.req.ge_headers把用户请求中的头部取出来,然后找出User-Agent,把User-Agent值通过这样一种文本方式返回给浏览器中.
通过openresty的nginx lua模块,我们可以用它提供给我们的API完成很多功能,我们可以利用Lua本身的一些工具库把Lua语言添加进来参加我们生成响应的这样一个过程中。
直接使用openresty提供的API或者Lua代码生成响应,为浏览器客户端提供服务。
我们可以使用Lua语言以及提供的相应的API库直接去访问Redis,Mysql,Tomcat等这样的服务,然后把不同的响应通过程序逻辑组成相应的http响应返回给用户
*/
修改配置文件
[root@server nginx]# cat /usr/local/openresty/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /lua {
default_type text/html;
content_by_lua '
ngx.say("User-Agent: ", ngx.req.get_headers()["User-Agent"])
';
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
# 启动
[root@server nginx]# cat /usr/local/openresty/nginx/sbin/nginx
访问
Linux下ab性能测试
下载配置ab
[root@server openresty]# yum -y install httpd-tools
[root@server openresty]# ab -V
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
1W并发压力测试
[root@server openresty]# ab -c 10000 -n 100000 127.0.0.1/lua
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: openresty/1.13.6.2 # 服务器信息和版本
Server Hostname: 127.0.0.1 # 服务器的域名
Server Port: 80 # 端口
Document Path: /lua # 访问的路径
Document Length: 28 bytes # 文档大小
Concurrency Level: 10000 # 并发请求数
Time taken for tests: 5.978 seconds # 整个测试持续的时间
Complete requests: 100000 # 完成的请求数
Failed requests: 196008 # 失败的请求数
(Connect: 0, Receive: 0, Length: 98912, Exceptions: 97096)
Write errors: 0 # 网络连接写入错误数
Total transferred: 511104 bytes # 传输的总数据量
HTML transferred: 81312 bytes # 传输的HTML内容量
Requests per second: 16729.18 [#/sec] (mean) # 平均每秒请求数
Time per request: 597.758 [ms] (mean) # 所有用户请求一次的平均时间
Time per request: 0.060 [ms] (mean, across all concurrent requests) # 单个用户请求一次的时间
Transfer rate: 83.50 [Kbytes/sec] received # 传输速率
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 323 302.4 256 3359
Processing: 64 246 62.9 247 525
Waiting: 0 8 48.8 0 342
Total: 283 570 304.2 512 3566
# 所有服务请求的百分比占用时间,这里50%的请求用时512ms, 一般看90%的部分
Percentage of the requests served within a certain time (ms)
50% 512
66% 541
75% 545
80% 547
90% 556
95% 1463
98% 1524
99% 1555
100% 3566 (longest request)
1.5W并发压力测试
[root@server openresty]# ab -c 15000 -n 100000 127.0.0.1/lua
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: openresty/1.13.6.2
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /lua
Document Length: 28 bytes
Concurrency Level: 15000
Time taken for tests: 6.128 seconds
Complete requests: 100000
Failed requests: 201164
(Connect: 0, Receive: 0, Length: 102820, Exceptions: 98344)
Write errors: 0
Total transferred: 291456 bytes
HTML transferred: 46368 bytes
Requests per second: 16317.62 [#/sec] (mean)
Time per request: 919.252 [ms] (mean)
Time per request: 0.061 [ms] (mean, across all concurrent requests)
Transfer rate: 46.44 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 471 296.5 409 3498
Processing: 74 380 100.9 383 878
Waiting: 0 7 57.5 0 573
Total: 494 851 303.4 808 4077
Percentage of the requests served within a certain time (ms)
50% 808
66% 818
75% 832
80% 856
90% 888
95% 1750
98% 1812
99% 1832
100% 4077 (longest request)
2W并发压力测试
[root@server openresty]# ab -c 20000 -n 100000 127.0.0.1/lua
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: openresty/1.13.6.2
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /lua
Document Length: 28 bytes
Concurrency Level: 20000
Time taken for tests: 6.101 seconds
Complete requests: 100000
Failed requests: 194710
(Connect: 0, Receive: 0, Length: 97430, Exceptions: 97280)
Write errors: 0
Total transferred: 478720 bytes
HTML transferred: 76160 bytes
Requests per second: 16389.97 [#/sec] (mean)
Time per request: 1220.258 [ms] (mean)
Time per request: 0.061 [ms] (mean, across all concurrent requests)
Transfer rate: 76.62 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 625 432.2 507 3665
Processing: 107 474 149.2 441 1024
Waiting: 0 15 94.3 0 714
Total: 521 1099 443.9 984 4362
Percentage of the requests served within a certain time (ms)
50% 984
66% 1005
75% 1010
80% 1019
90% 1949
95% 1997
98% 2131
99% 2421
100% 4362 (longest request)
通过lua实现灰度发布
nginx.conf
[root@server conf]# cat nginx.conf
user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream up1{
server 127.0.0.1:8081;
}
upstream up2{
server 127.0.0.1:8082;
}
upstream all{
ip_hash;
serever 127.0.0.1:8081;
serever 127.0.0.1:8082;
}
server {
listen 80;
server_name localhost;
# 请求交给lua脚本处理
location / {
lua_code_cache off;
content_by_lua_file /usr/local/nginx/lua/proxy.lua;
}
# location @ 用于nginx内部跳转
location @up1 {
proxy_pass http://up1;
}
location @up2 {
proxy_pass http://up2;
}
location @all {
proxy_pass http://all;
}
}
}
proxy.lua
ngx.header.content_type="text/html;charset=utf8"
redis = require('resty.redis')
redis = redis.new()
redis:set_timeout(1000)
ok,err = redis:connect('127.0.0.1', 6379)
if not ok then
ngx.say('connect to redis failed ! reason: ' .. err)
end
-- 从redis中检查是否存在即将更新的upstream主机
check_up1 = redis:get('update1') --(up1)
check_up2 = redis:get('update2') --(up2)
redis:close()
-- 注意返回的数据类型来判断
if check_up1 == "1" then
ngx.exec("@up2")
elseif check_up2 == "1" then
ngx.exec("@up1")
else
ngx.exec("@all")
end
-- 原理就是利用redis中设置指定key,比如要更新主机1,则redis中添加key=update1,value=1,当浏览器请求进入nginx的content阶段后执行lua脚本,
-- 脚本中检查redis中是否存在要更新的主机,如果发现某个主机要更新则通过Nginx API for Lua中的ngx.exec接口内部跳转到另一台主机。
-- 如果两个都不更新,则根据nginx自己的方式(默认轮询)分发请求。
-- nginx里使用了ip_hash保持会话,主要是为了用户的请求在后端记录的日志中保持完整。
优点
高并发
根据以上的测试来看,一台1核700兆的linux虚拟机即可跑出2W的并发,足以说明OpenResty处理高并发的能力,由于ab工具的限制,只能测试上限2W的并发,因此,这里也只做到了2W的测试。
热更新
Lua属于脚本语言,编译之后即可运行;Nginx具备优雅重启的功能;因此,线上业务如果出现问题需要及时修复的,更新修改Lua脚本之后,重启Nginx即可完成更新发布;如果没有配置Lua缓存功能的话,只要更新Lua脚本即可更新修复线上问题,不重启Nginx也可以。
缺点
不适合处理复杂的业务逻辑
由于功能性的东西主要使用Lua进行开发,受Lua语言特性的影响,不太适合做业务比较复杂的功能。
互联网上资料少
互联网上可以找的资料比较少;不过,本身Lua的学习过程不是特别的复杂,所以,这基本不会成为你学习它的障碍
适用场景
高仿问下应用及官网主页
如商城,咨询类的应用首页,会存在大量的请求,由于涉及到的内容比较多;所以可是私用预载入的形式,将主页的数据放置在redis中;使用OpenResty+redis实现首页,官网主页的高并发加载.
商城类的秒杀功能
秒杀功能会存在短时间的请求洪峰,如果处理不当可能会造成down机的风险,可以结合OpenResty+redis实现秒杀的功能.
ip限流
互联网系统可能存在非法用户恶意暴力请求,导致正常的用户无法使用,可以通过OpenResty+redis实现ip的白名单机制,去拦截非法的用户ip
APP灰度升级发布
可以根据系统的数据及条件实现APP的灰度升级测试
01 . OpenResty简介部署,优缺点,压测,适用场景及用Lua实现服务灰度发布的更多相关文章
- 问题追查:QA压测工具http长连接总是被服务端close情况
1. 背景 最近QA对线上单模块进行压测(非全链路压测),http客户端 与 thrift服务端的tcp链接总在一段时间被close. 查看服务端日志显示 i/o timeout. 最后的结果是: q ...
- JMeter分布式压测实战(2020年清明假期学习笔记)
一.常用压力测试工具对比 简介:目前用的常用测试工具对比 1.loadrunner 性能稳定,压测结果及颗粒度大,可以自定义脚本进行压测,但是太过于重大,功能比较繁多. 2.Apache ab(单接口 ...
- Http压测工具wrk使用指南
用过了很多压测工具,却一直没找到中意的那款.最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好. 安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持 ...
- Http压测工具wrk使用指南【转】
用过了很多压测工具,却一直没找到中意的那款.最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好. 安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持 ...
- 腾讯云开放云压测“黑科技“,产品上线从此不再“压力山大"
商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 能否解决"高并发"问题一直是检验一个产品后台是否稳定,架构是否合理,性能是否强大的核心标准.对于产品而言,多高的并发 ...
- 高德全链路压测平台TestPG的架构与实践
导读 2018年十一当天,高德DAU突破一个亿,不断增长的日活带来喜悦的同时,也给支撑高德业务的技术人带来了挑战.如何保障系统的稳定性,如何保证系统能持续的为用户提供可靠的服务?是所有高德技术人面临的 ...
- Jmeter非GUI界面对阿里云服务器压测
一.Jmeter非GUI界面 参数讲解 讲解:非GUI界面,压测参数讲解 -h 帮助 -n 非GUI模式 -t 指定要运行的 JMe ...
- JMeter性能测试9:阿里云服务器压测
第一步准备好jmeter脚本 第二步 将本地的jmeter脚本上传到阿里云进行验证 检验阿里云的jmeter是否能正常运行 将本地的脚本上传到阿里云使用xshell进入到该目录下 使用命令运行刚才上传 ...
- 5. 堪比JMeter的.Net压测工具 - Crank 实战篇 - 接口以及场景压测
目录 堪比JMeter的.Net压测工具 - Crank 入门篇 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识yml 堪比JMeter的.Net压测工具 - Crank 进阶篇 ...
随机推荐
- package_ios
PlistBuddy简单使用 https://www.jianshu.com/p/2167f755c47e xcodebuild 命令 https://www.jianshu.com/p/c32263 ...
- MySQL 数据库中的基础操作
数据库中的表操作 1.创建表 表的表名命名规则: -- 数据库表命名规则重要说明: -- (1)数据库表名称可以支持大写字母A-Z,小写字母a-z,数字0-9,字符包括下划线 _ ,可以组合使用; - ...
- WebLogic12C安装配置文档
jdk版本:1.8; jdk安装路径不准有空格 JDK安装: jdk版本:1.8; jdk安装路径不准有空格 WebLogic安装: 解压安装包 解压JAR 找到fmw_12.2.1.3.0_wls\ ...
- Solon详解(三)- Solon的web开发
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- redis基础数据结构及编码方式
redis基础数据结构和编码方式 一.基础数据结构 1)简单动态字符串 2)双端链表 3)字典 4)跳跃表 5)整数集合 6)压缩列表 二.对象类型与编码 在redis的数据库中创建一个新的键值对时, ...
- Java常用工具类整理
字符数组转String package com.sunsheen.hcc.fabric.utils; /** * 字符数组工具 * @author WangSong * */ public class ...
- 阿里云前端路线 | CSS快速掌握
1.1什么是CSS 翻译为“层叠样式表”或者“级联样式表”, 简称样式表. 1.2CSS的主要作用 它主要是用来给HTML网页来设置外观或者样式 外观或者样式:HTML网页中的文字的大小.颜色.字体, ...
- 关于非标准json格式转变为json对象
eval('(' + tempData + ')') 只需要这一句
- 《Head First 设计模式》:组合模式
正文 一.定义 组合模式允许你将对象合成树形结构来表现"整体/部分"层次结构.组合能让客户以一致的方式处理组合对象以及个体对象. 组合对象:包含其他组件的组件. 个体对象(叶节点对 ...
- python之csrf简介
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功能有分为全 ...