Skip to main content

5 posts tagged with "OpenResty"

View All Tags

· 3 min read
CheverJohn

我的问题描述

  1. 无法跑测试(APISIX 的);
  2. Nginx 会启动多个进程。

然后我复现的命令如下可见

export PERL5LIB=.:$PERL5LIB:/home/api7/dev_cj/apisix

export PATH=/usr/local/openresty/nginx/sbin:$PATH

prove ....../example.t

然后就出现一个问题端口占用

解决办法:当跑测试的时候,因为 APISIX 会启动upstream 端口,所以如果不关闭 openresty 的阿虎,就会遇到端口占用的问题。

然后我运行

netstat -nultp

复现了 多个 nginx 进程的问题,

运行

ps -ef | grep nginx

发现了多个进程,意识到我的 openresty 还开着。

关闭 openresty

openresty -s stop

然后利用kill -9 杀掉了很多个进程。这边我采取了笨方法,一个进程一个进程杀掉了,可以不用 -9 ,这边 remark 一下。

kill -9 76007
kill -9 76008
kill -9 76009

APISIX 重启了一切正常

总结

ps -ef | grep nginx

这个命令还是要记记牢。

2022年 3月 8日

细节问题:没想到已经跑通测试的我,还是在新的开发机上跑测试框架遇到了问题。本次主要问题在于 一个安装包问题,所以说环境是真的无语,还是得设置到代理啊。我设置了git 的代理解决了问题, 详情方法,请参考 link ,我的主要疏忽在于,没注意端口, 因为之前实在 Windows 本上做开发的,用的是 v2ray,端口是 10808,没曾想就照着走错了,离谱啊。此处 mark 一下,需要注意。

然后还有一个点需要注意一下,make depsLUAROCKS_SERVER=https://luarocks.cn make deps 可以混着用,over。

放上遇到问题的图:

我又遇到问题啦呜呜呜

放上解决问题之后的图片:

解决问题就是爽啊!

· 4 min read
CheverJohn

讲真为什么我会遇到这一块的问题呢?主要还是不熟悉开发流程。 虽然我已经安装好了APISIX,且APISIX的基本内容我都有所了解了。 可是在我实操过程中,还是遇到了很多问题,当然最终发现其实都是基本环境没做好(没有上游服务器端口应该算是基本环境吧?)

开干!

淦,拖了好久了,开始!——2022年2月13日

其实就是给 APISIX 的上游( upstream )添加一个服务器,这里边讨巧选择了 OpenResty。

首先我们已经按照 APISIX 的前置教程安装好了 OpenResty 了,这个必须先确定下来。

安装命令如下:

# 添加 OpenResty 源
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

# 安装 OpenResty 和 编译工具
sudo yum install -y openresty curl git gcc openresty-openssl111-devel unzip pcre pcre-devel

# 安装 LuaRocks
curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -

然后这边再强化一下观念,安装之前本地的代理呀、基本软件(如 git、gcc、unzip等)都要先配置好!

然后我们本地的 OpenResty 的地址可以通过以下命令找回:

OpenResty 的位置

开始配置

跟配置 NGINX 一样

cd /usr/local/openresty/nginx/conf/vhost/1980.conf

首先你先在 conf 文件夹里创建 vhost 文件夹,然后在 /usr/local/openresty/nginx/conf/nginx.conf 文件最下面添加。

添加位置如图

NGINX 文件配置

然后添加如下内容

server {
listen 1980;
access_log logs/access-1980.log main;
error_log logs/error.log;
location / {
content_by_lua_block {
ngx.header["Content-Type"] = "text/html"
local headers = ngx.req.get_headers()
ngx.say("---Headers")
for k, v in pairs(headers) do
ngx.say(k .. ":" .. v)
end

local args = ngx.req.get_uri_args()
ngx.say("---Args")
for k, v in pairs(args) do
ngx.say(k .. ":" .. v)
end

ngx.say("---URI")
ngx.say(ngx.var.uri)

ngx.say("---Service Node")
ngx.say("Ubuntu-DEV-1980")
}
}
}

如图 1980 配置文件内容以及文件树

然后就直接

openresty

启动 1980 服务器即可。

可以看到后端端口,基本上应该打开的都打开咯!

所有端口

来一套基本操作

进行一套基本操作,来试试 APISIX 哈

使用 GraphQL 的配置请求说明问题

命令来自于下面的链接:https://www.cheverjohn.xyz/blog/%E5%9F%BA%E7%A1%80%E5%91%BD%E4%BB%A4_graphql%E5%9C%A8APISIX%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8

实现配置 GraphQL 在 APISIX 中

配置

然后发出请求

请求

如此以来,我就配置好了我的一系列测试,新春快乐!

· 9 min read
CheverJohn

文章来自于对极客空间《OpenResty 从入门到实战》课程的学习汇总。

阻塞函数

一个重要原则——避免使用阻塞函数

OpenResty 的高性能的由来,主要是因为 “使用” 了 NGINX 的事件处理和 Lua 的协程机制。如果我 们使用阻塞函数的话,就意味着会有阻塞这一 ”使用“ 的可能性。这就会导致请求无法正常交由 NGINX 和 Lua 进行处理。

在调用外部命令时需要注意的事情

Lua 使用 os.execute函数调用外部命令,如果调用时间需要几百毫秒~几秒钟,那么我们会遇到阻塞,性能会下降!

同样是会有遇到阻塞情况的可能性,我们需要想办法避免阻塞。原课程中,主讲人提出几个实际的场景例子:拷贝文件、使用 OpenSSL 生成密钥等耗时久的操作。针对这些场景,提出了两个具体的方案 FFI 库调用、ngx.pipe 的 lua-resty-shell 库的使用

当然本质上还是没有离开主题——“避免使用阻塞函数

磁盘 I/O

个人理解,磁盘读写向来都是最损耗性能的,我们首先应该要做的就是减少 I/O 读写。

这边我学习到的是,可以通过使用 lua-io-nginx-module 这个第三方的 C 模块提高性能。原理是将 I/O 操作从主线程转移到另外一个线程中处理,降低线程损耗。

这边关于主线程和子线程,我的理解是,主线程意味着是子线程的守门员,但是主线程也有自己跑路的风险——即提前下线,如果主线程依靠 pthread_exit 提前下线,而不是 return,那么其他线程就会继续运行。会变成僵死的状态。这就会对性能造成很大的影响。

luasocket

这边引用作者的原话吧。感觉作者的原话简洁明了

我们来说说 luasocket ,它也是容易被开发者用到的一个 Lua 内置库,经常有人分不清 luasocket 和 OpenResty 提供的 cosocket。luasocket 也可以完成网络通信的功能,但它并没有非阻塞的优势。如果你使用了 luasocket,那么性能也会急剧下降。

字符串

对我有用的一点:在 lua 中,字符串是不可变的

即当你修改一个字符串的值时,其实做的操作是创建了一个新的字符串对象,只不过修改了数据的引用罢了。

Table

优化原则

  1. 尽量复用,避免不必要的 table 的创建
  2. 预先生成数组
  3. 手动计算下标值
  4. 循环使用单个 table
  5. 使用缓存——table 池

调优手段

明确一下,本部分内容主要是 OpenResty 的调试

断电+打日志

断点是必须掌握的

这边有一个经验得记下

两个前提:测试环境,以及稳定复现。

然后有一个工具推荐 Mozilla RR

二分查找+注释

额,二分我自己就很常用啊

动态调试

Dtrace——动态调试!这个是宝藏,我得玩一下去,这边也直接引用作者的语言描述

我就曾经遇到过这样的一个 bug。多年前,我负责的一个系统在每天凌晨 1 点钟左右时,数据库资源就会被耗尽,并导致整个系统雪崩。当时,我们白天排查代码中的计划任务,到了晚上,团队的同学们就蹲守在公司等 bug 复现,复现的时候再去查看各自子模块的运行状态。这样下来,直到第三个晚上才找到了 bug 的元凶。我的这个经历,和 Solaris 几个系统工程师创造 Dtrace 的背景很类似。当时 Solaris 的工程师们,也是花了几天几夜的时间排查一个诡异的线上问题,最后才发现是因为一个配置写错了。但和我不同的是,Solaris 的工程师决定彻底避免这种问题,于是发明了 Dtrace,专门用于动态调试。动态调试,也叫做活体调试。和 GDB 这种静态调试工具不同,动态调试可以调试线上的服务,而对调试的程序而言,整个调试过程是无感知、无侵入的,不用你修改代码,更不用重启。打一个比方,动态调试就像 X 光,可以在病人无感知的情况下检查身体,而不需要抽血和胃镜。Dtrace 便是最早的动态追踪框架,受到它的影响,其他系统中也逐渐出现了类似的动态调试工具。比如,Red Hat 的工程师,就在 Linux 平台上创造了 Systemtap,也就是我接下来要讲的主角。

有助于我更快理解 Dtrace 是什么。

Systemtap

※这个对我来说也是新鲜事物,可以学习!

其他的动态追踪框架

跟不上了跟不上了,引用作者原话吧,方便我日后理解呢

当然,对于内核和性能分析工程师来说,只有 Systemtap 还是不够用的。首先, Systemtap 并没有默认进入系统内核;其次,它的工作原理决定了它的启动速度比较慢,而且有可能对系统的正常运行造成影响。eBPF(extended BPF)则是最近几年 Linux 内核中新增的特性。相比 Systemtap,eBPF 有内核直接支持、不会死机、启动速度快等优点;同时,它并没有使用 DSL,而是直接使用了 C 语言的语法,所以也大大降低了它的上手难度。除了开源的解决方案外,Intel 出品的 VTune 也是神兵利器之一。它直观的界面操作和数据展示,可以让你不写代码也能分析出性能的瓶颈。

定位性能瓶颈

wrk 和火焰图

缓存

缓存两原则:

一是越靠近用户的请求越好。比如,能用本地缓存的就不要发送 HTTP 请求,能用 CDN 缓存的就不要打到源站,能用 OpenResty 缓存的就不要打到数据库。二是尽量使用本进程和本机的缓存解决。因为跨了进程和机器甚至机房,缓存的网络开销就会非常大,这一点在高并发的时候会非常明显。

shared dict 缓存和 lru 缓存

缓存风暴

解决:lua--resty-* 封装

突发流量

接下来的内容就全是概念性的东西了,google 一下你就知道。

漏桶和令牌桶

动态限流限速

动态

OpenResty 常用的第三方库

· 6 min read
CheverJohn

博客内容简述

本篇博客主要是新手入门OpenResty的必经之路,也将是很多人第一次写lua脚本代码。内容包括如下:

  1. 使用Debian-wsl安装OpenResty。
  2. 在命令行运行输出“HelloWorld”。
  3. 使用VSCode连接Debian-wsl,且运行Helloworld项目,且能够通过OpenResty部署在本地服务器上,然后通过curl命令获取“HelloWorld”。

本地环境

Windows10 Pro: 21H1(OS Build 19043.1415)
Debian: 11(bullseye) x86_64
OpenResty: 因为按照官方文档在Debian系统中添加了OpenResty仓库,这样以后可以随时安装或更新软件包(目前我的理解就是一行命令的事情)

Debian-wsl上安装OpenResty

这个其实很是简单,在OpenResty的官方文档里就解释的很是详细,这边再简单过一下哈。

步骤一:安装导入GPG公钥时需要的几个依赖包

sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates

步骤二:导入我们的GPG密钥

wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -

步骤三:添加OpenResty的官方apt仓库

对于 x86_64amd64 系统,可以使用下面的命令:

codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release`

echo "deb http://openresty.org/package/debian $codename openresty" \
| sudo tee /etc/apt/sources.list.d/openresty.list

而对于 arm64aarch64 系统,则可以使用下面的命令:

codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release`

echo "deb http://openresty.org/package/arm64/debian $codename openresty" \
| sudo tee /etc/apt/sources.list.d/openresty.list

这边我需要说一下哈,第一次看到这个其实很难理解。但是我们只需要照做就是了,也就是将这两行命令一次paste进命令行里即可。

我这边因为是上午就完成了,已经找不到了,就先不上图了哈。

步骤四:更新 APT 索引:

sudo apt-get update

然后就可以像下面这样安装软件包,比如 openresty

sudo apt-get -y install openresty

这个包同时也推荐安装 openresty-opmopenresty-restydoc 包,所以后面两个包会缺省安装上。 如果你不想自动关联安装,可以用下面方法关闭自动关联安装:

sudo apt-get -y install --no-install-recommends openresty

PS:这里边就离谱,我都跑完命令了,然后告诉我可以关闭自动关联安装,淦。

命令行跑“Hello world”

第一次跑通的命令是这样的 hhhh

命令行最简单Helloworld

对比一下Python的运行代码

Python与OpenResty的比较

一串代码稍稍揭露OpenResty本质

虽然好像还是阻止了进程,但是还是可以一瞥一二的。

OpenResty的本质

VSCode连接Debian-wsl

构建开发工作环境

其实只需要VSCode安装两个插件就行了

VSCode安装两个插件

其中Lua插件甚至还可以给wsl上安装,MS是真的把这个wsl玩透了。

然后就可以继续在Debian-wsl上创建目录,目录如下:

Debian-wsl上的目录

进而在conf文件夹创建nginx.conf

![nginx.conf in conf](/img/2022-01-10-OpenResty_Helloworld_in_Debian/nginx.conf in conf.png)

然后这边一定要注意的是,将OpenResty加入到PATH环境中; 方法如下:

PATH=/usr/local/openresty/nginx/sbin:$PATH
export PATH

这样就可以如愿将OpenResty加入到PATH环境中; 然后启动OpenResty服务

openresty -p `pwd` -c conf/nginx.conf

曲折的启动OpenResty服务

从这张图就可以很容易地看出来,我犯了至少两个错误

  • 没有配置OpenResty的环境变量
  • 代码写错了呢呜呜呜~

但是这串代码其实可以看出来,我们写的第一个OpenResty程序,在根目录下新增OpenResty的content_by_lua指令,里面又嵌入了ngx.say的代码:

然后这个时候我们的OpenResty的服务已经成功启动了,可以使用curl命令,查看结果的返回:

result的返回

(当然前提是我使用openresty -p `pwd` -c conf/nginx.conf命令启动了OpenResty服务)

好嘞,第一个真正的OpenResty程序完成咯。

Inspired by chun's docs(看官方文档果然yyds鸭)

· 4 min read
CheverJohn

入门

三大特性

OpenResty的发展

基于成熟的开源组件——Nginx和LuaJIT。OpenResty诞生于2007年,第一个版本用的是Perl,原因是这跟作者章亦春的技术偏好有很大关系。

详尽的文档和测试用例

OpenResty的文档非常详细,作者把每一个需要注意的点都写在了文档中。

OpenResty还自带了一个命令行工具restydoc,专门用来帮助你通过shell查看文档,避免编码过程被打断。

同步非阻塞

什么是同步非阻塞。

阻塞:特质阻塞操作系统的线程。

动态

我理解为热部署呢,动态加载配置文件,就很棒!跟Nginx相比棒多了!

主要原因是OpenResty是由脚本语言Lua来控制逻辑的,动态是Lua的特性。

列出OpenResty的8重点,才能学好OpenRest

  • 同步非阻塞的编程模式;
  • 不同阶段的作用;
  • LuaJIT和Lua的不同之处;
  • OpenResty API和周边库;
  • 协程和cosocket;
  • 单元测试框架和性能测试工具;
  • 火焰图和周边工具链;
  • 性能优化。

test for github.

写一个helloworld

首先应该配置好环境,我倒是没有想到的是,居然好像不支持windows(emmmmm,当然是我扫了一眼得出的结论啦,不当真不当真)。

这边我看《极客时间》温铭老师提出了两个值得思考的问题 问题

  • 为什么不推荐源码编译安装呢?

    • 在我们日常操作中,其实就有这么一种操作,比如nginx,我们就自行编译打包运行,甚至也会使用一些额外的小命令-g 啦之类的,做一些很细致化的操作。
    • official 回答:老师给出的建议是,不是很建议是因为我们的日常目标是在生产环境中快速部署,所以理应使用更稳妥的方法。
    • 我的回答:淦,这不是明摆着的嘛,具体问题具体分析,亘古不变的道理,如果是玩票,随便你咋安装(事实上我刚开始肯定自己编译安装:) ,想好好了解这个东西呢!)
  • 为什么官方不接受第三方维护的包呢?

    • 这个问题我要小小解释一下,说不定我亲爱的读者们连题目都没有读得懂呢?第三方维护的包,一般是指为了加快源库的下载安装速度(网速为啥会变慢,就不由我多说了哈),国内会有一些公益性质的组织自行维护一些常见的包库,通过定时从国外的官方源库中下载下来,发布在国内的服务器上,这样国内用户自然而然就可以有很快的下载速度啦。此处可以举例清华tuna的清华源,就是这么个道理。

      official回答:为了避免第三方和官方之间的冲突,导致后期的项目