02 | 如何写出你的“hello world”?
下载APP
关闭
渠道合作
推荐作者
02 | 如何写出你的“hello world”?
2019-05-29 温铭 来自北京
《OpenResty从入门到实战》
课程介绍
讲述:温铭
时长09:05大小8.29M
你好,我是温铭。今天起,就要开始我们的正式学习之旅。
每当我们开始学习一个新的开发语言或者平台,都会从最简单的hello world开始,OpenResty 也不例外。让我们先跳过安装的步骤,直接看下,最简单的 OpenResty 程序是怎么编写和运行的:
这应该是你见过的最简单的那种 hello world 代码写法,和 Python 类似:
这背后其实是 OpenResty 哲学的一种体现,代码要足够简洁,也好让你打消“从入门到放弃“的念头。我们今天的内容,就专门围绕着这行代码来展开聊一聊。
上一节我们讲过,OpenResty 是基于 NGINX 的。那你现在是不是有一个疑问:为什么这里看不到 NGINX 的影子?别着急,我们加一行代码,看看 resty背后真正运行的是什么:
我们加了一行 sleep 休眠的代码,让 resty 运行的程序打印出字符串后,并不退出。这样,我们就有机会一探究竟:
终于看了熟悉的 NGINX 进程。看来,resty 本质上是启动了一个 NGINX 服务,那么resty 又是一个什么程序呢?我先卖个关子,咱后面再讲。
你的机器上可能还没有安装 OpenResty,所以,接下来,我们先回到开头跳过的安装步骤,把 OpenResty 安装完成后再继续。
OpenResty 的安装
和其他的开源软件一样,OpenResty 的安装有多种方法,比如使用操作系统的包管理器、源码编译或者 docker 镜像。我推荐你优先使用 yum、apt-get、brew 这类包管理系统,来安装 OpenResty。这里我们使用 Mac 系统来做示例:
不过,这看似简单的安装背后,其实有两个问题:
为什么我不推荐使用源码来安装呢?
为什么不能直接从操作系统的官方仓库安装,而是需要先设置另外一个仓库地址?
对于这两个问题,你不妨先自己想一想。
这里我想补充一句。在这门课程里面,我会在表象背后提出很多的“为什么”,希望你可以一边学新东西一边思考,结果是否正确并不重要。独立思考在技术领域也是稀缺的,由于每个人技术领域和深度的不同,在任何课程中老师都会不可避免地带有个人观点以及知识的错漏。只有在学习过程中多问几个为什么,融会贯通,才能逐渐形成自己的技术体系。
很多工程师都有源码的情节,多年前的我也是一样。在使用一个开源项目的时候,我总是希望能够自己手工从源码开始 configure 和 make,并修改一些编译参数,感觉这样做才能最适合这台机器的环境,才能把性能发挥到极致。
但现实并非如此,每次源码编译,我都会遇到各种诡异的环境问题,磕磕绊绊才能安装好。现在我想明白了,我们的最初目的其实是用开源项目来解决业务需求,不应该浪费时间和环境鏖战,更何况包管理器和容器技术,正是为了帮我们解决这些问题。
言归正传,给你说说我的看法。使用 OpenResty 源码安装,不仅仅步骤繁琐,需要自行解决 PCRE、OpenSSL 等外部依赖,而且还需要手工对 OpenSSL 打上对应版本的补丁。不然就会在处理 SSL session 时,带来功能上的缺失,比如像ngx.sleep这类会导致 yield 的 Lua API 就没法使用。这部分内容如果你还想深入了解,可以参考[官方文档]来获取更详细的信息。
从这里可以看出,OpenResty 不仅维护了自己的 OpenSSL 版本,还维护了自己的 zlib 和 PCRE 版本。不过后面两个只是调整了编译参数,并没有维护自己的补丁。
所以,综合这些因素,我不推荐你自行源码编译 OpenResty,除非你已经很清楚这些细节。
为什么不推荐源码安装,你现在应该已经很清楚了。其实我们在回答第一个问题时,也顺带回答了第二个问题:为什么不能直接从操作系统的官方仓库安装,而是需要先设置另外一个仓库地址?
这是因为,官方仓库不愿意接受第三方维护的 OpenSSL、PCRE 和 zlib 包,这会导致其他使用者的困惑,不知道选用哪一个合适。另一方面,OpenResty 又需要指定版本的 OpenSSL、PCRE 库才能正常运行,而系统默认自带的版本都比较旧。
OpenResty CLI
安装完 OpenResty 后,默认就已经把 OpenResty 的 CLI:resty 安装好了。resty是个 1000 多行的 Perl 脚本,之前我们提到过,OpenResty 的周边工具都是 Perl 编写的,这个是由 OpenResty 作者的技术偏好决定的。
先来看第一个例子。这个示例结合了 NGINX 配置和 Lua 代码,一起完成了一个共享内存字典的设置和查询。dogs 1m 是 NGINX 的一段配置,声明了一个共享内存空间,名字是 dogs,大小是 1m;在 Lua 代码中用字典的方式使用共享内存。另外还有--http-include 和 --main-include来设置 NGINX 配置文件。所以,上面的例子也可以写为:
OpenResty 世界中常用的调试工具,比如gdb、valgrind、sysetmtap和Mozilla rr ,也可以和 resty 一起配合使用,方便你平时的开发和测试。它们分别对应着 resty 不同的指令,内部的实现其实很简单,就是多套了一层命令行调用。我们以 valgrind 为例:
在后面调试、测试和性能分析的章节,会涉及到这些工具的使用。它们不仅适用于 OpenResty 世界,也是服务端的通用工具,让我们循序渐进地来学习吧。
更正式的 hello world
最开始我们使用resty写的第一个 OpenResty 程序,没有 master 进程,也不会监听端口。下面,让我们写一个更正式的 hello world。
写出这样的 OpenResty 程序并不简单,你至少需要三步才能完成:
创建工作目录;
修改 NGINX 的配置文件,把 Lua 代码嵌入其中;
启动 OpenResty 服务。
我们先来创建工作目录。
下面是一个最简化的 nginx.conf,在根目录下新增 OpenResty 的content_by_lua指令,里面嵌入了ngx.say的代码:
请先确认下,是否已经把openresty加入到PATH环境中;然后,启动 OpenResty 服务就可以了:
没有报错的话,OpenResty 的服务就已经成功启动了。你可以打开浏览器,或者使用 curl 命令,来查看结果的返回:
到这里,恭喜你,一个真正的 OpenResty 程序就完成了。
总结
让我们回顾下今天讲的内容。我们通过一行简单的 hello, world 代码,延展到 OpenResty 的安装和 CLI,并在最后启动了 OpenResty 进程,运行了一个真正的后端程序。
其中, resty 是我们后面会频繁使用到的命令行工具,课程中的演示代码都是用它来运行的,而不是启动后台的 OpenResty 服务。
更为重要的是,OpenResty 的背后隐藏了非常多的文化和技术细节,它就像漂浮在海面上的一座冰山。我希望能够通过这门课程,给你展示更全面、更立体的 OpenResty,而不仅仅是它对外暴露出来的 API。
思考
最后,我给你留一个作业题。我们现在的做法,是把 Lua 代码写在 NGINX 配置文件中。不过,如果代码越来越多,那代码的可读性和可维护性就无法保证了。
你有什么方法来解决这个问题吗?欢迎留言和我分享,也欢迎你把这篇文章转发给你的同事、朋友。
分享给需要的人,Ta购买本课程,你将得18元
生成海报并分享
赞 13
提建议
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
01 | 初探OpenResty的三大特性
下一篇
03 | 揪出隐藏在背后的那些子项目
精选留言(58)
- Geek_144c1d2019-05-29先将代码打包成`.lua` 文件 使用配置文件指令 `content_by_lua_file` 引用 类库代码 如果有 reqiure 的需求 可利用 `lua_package_path` 和 `lua_package_cpath` 设定类库加载目录
作者回复: 👍
31 - cylim2019-05-29既然是基础课,应该提醒我们关闭server。 openresty -s quit -p `pwd` -c conf/nginx.conf 把lua代码写在其他文件上,然后带入nginx.conf使用。
作者回复: 欢迎补充:)
共 2 条评论19 - helloworld2019-06-21编译安装PART1: 老师说的对,对于大多数项目来说都没有必要自己折腾编译安装,费时费力。不过有时候自己动手编译安装也是必须的,因为根据具体项目的需要,比如CDN项目,官方的默认编译选项就缺少一些必要的模块,比如ngx_cache_purge模块,如果需要对ipv6做支持,还需要nginx的--with-ipv6编译选项,等等。下面是我根据官方打包文件总结的centos平台下编译安装最新版本的openresty具体流程。centos6下完美运行,7也应该不是问题。给各位小伙伴在需要的时候参考,少走弯路,节省宝贵时间。 # 安装 pcre wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.42.tar.bz2 tar xjf pcre-8.42.tar.bz2 cd pcre-8.42 ./configure --prefix=/usr/local/openresty/pcre \ --disable-cpp --enable-jit \ --enable-utf --enable-unicode-properties make -j24 V=1 > /dev/stderr make install rm -rf /usr/local/openresty/pcre/bin rm -rf /usr/local/openresty/pcre/share rm -f /usr/local/openresty/pcre/lib/*.la rm -f /usr/local/openresty/pcre/lib/*pcrecpp* rm -f /usr/local/openresty/pcre/lib/*pcreposix* rm -rf /usr/local/openresty/pcre/lib/pkgconfig # 安装zlib cd /usr/local/src wget http://www.zlib.net/zlib-1.2.11.tar.xz tar xf zlib-1.2.11.tar.xz cd zlib-1.2.11 ./configure --prefix=/usr/local/openresty/zlib make -j24 \ CFLAGS='-O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -g' \ SFLAGS='-O3 -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -g' > /dev/stderr make install rm -rf /usr/local/openresty/zlib/share/ rm -f /usr/local/openresty/zlib/lib/*.la rm -rf /usr/local/openresty/zlib/lib/pkgconfig/ # 安装openssl cd /usr/local/src wget https://www.openssl.org/source/openssl-1.1.0j.tar.gz wget https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0d-sess_set_get_cb_yield.patch --no-check-certificate wget https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0j-parallel_build_fix.patch --no-check-certificate tar zxf openssl-1.1.0j.tar.gz cd openssl-1.1.0j 继续见PART2展开
作者回复: 👍
13 - helloworld2019-06-21编译安装PART3: # 最后开始编译安装openresty cd /usr/local/src wget https://openresty.org/download/openresty-1.15.8.1.tar.gz # 如果下载出现ssl报错,yum update wget,再下载 tar zxf openresty-1.15.8.1.tar.gz cd openresty-1.15.8.1 ./configure \ --prefix=/usr/local/openresty \ --with-cc-opt="-DNGX_LUA_ABORT_AT_PANIC \ -I/usrl/local/openresty/zlib/include \ -I/usr/local/openresty/pcre/include \ -I/usr/local/openresty/openssl/include" \ --with-ld-opt="-L/usr/local/openresty/zlib/lib \ -L/usr/local/openresty/pcre/lib \ -L/usr/local/openresty/openssl/lib \ -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib" \ --with-pcre-jit \ --without-http_rds_json_module \ --without-http_rds_csv_module \ --without-lua_rds_parser \ --with-stream \ --with-stream_ssl_module \ --with-stream_ssl_preread_module \ --with-http_v2_module \ --without-mail_pop3_module \ --without-mail_imap_module \ --without-mail_smtp_module \ --with-http_stub_status_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_auth_request_module \ --with-http_secure_link_module \ --with-http_random_index_module \ --with-http_gzip_static_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gunzip_module \ --with-threads \ --with-luajit-xcflags='-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT' \ -j24 make -j24 make install rm -rf /usr/local/openresty/luajit/share/man rm -rf /usr/local/openresty/luajit/lib/libluajit-5.1.a [END]展开共 2 条评论5
- helloworld2019-06-21编译安装PART2: patch -p1 < ../openssl-1.1.0d-sess_set_get_cb_yield.patch patch -p1 < ../openssl-1.1.0j-parallel_build_fix.patch ./config \ no-threads shared zlib -g \ enable-ssl3 enable-ssl3-method \ --prefix=/usr/local/openresty/openssl \ --libdir=lib \ -I%/usr/local/openresty/zlib/include \ -L%/usr/local/openresty/zlib/lib \ -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/openssl/lib make -j24 make install_sw rm -f /usr/local/openresty/openssl/bin/c_rehash rm -rf /usr/local/openresty/openssl/lib/pkgconfig 继续见PART3展开共 1 条评论5
- aaron2019-05-30我使用yum安装了openresty之后并没有resty工具,我也没发现-p 'pwd'的意义何在,-c nginx.conf也启动不起来,最后我是用openresty -c /opt/geektime/conf/nginx.conf启动的。。。
作者回复: centos 下需要单独安装:sudo yum install openresty-resty
共 4 条评论5 - MOIC💅2020-02-05openresty -p `pwd` -c ./conf/nginx.conf 启动 openresty -p `pwd` -c ./conf/nginx.conf -s stop 停止 lsof -i:端口号 查看服务状态共 1 条评论4
- 业余草2019-05-29content_by_lua指令看起来非常怪!没有用{}
作者回复: 嗯,可以用 content_by_lua_block
3 - 逗鹅冤2019-06-15老师好,有个问题请教一下 openresty -v nginx version: openresty/1.15.8.1 which openresty /usr/local/bin/openresty which resty /usr/local/bin/resty 这些都没问题 which luajit luajit not found luajit为什么没有呢展开
作者回复: luajit 的可执行文件并没有被拷贝到/usr/local/bin目录下,所有找不到。这个是为了避免了已经安装的 luajit 冲突,毕竟 OpenResty 自带的 LuaJIT 是自己维护的版本
2 - HelloBug2019-06-04温铭老师,你好,有读者问vscode有没有openresty扩展,你说你用的lua扩展,这个是什么意思呢?还有老师你用的是什么IDE呀?
作者回复: 我用的是 vs code,用的是 lua 和 luacheck 两个插件
2 - HelloBug2019-06-04温铭老师好,假设操作系统中已经安装openssl/pcre/zlib,使用openresty的仓库地址,然后使用包管理器安装openresty,这个时候操作系统里有几个openssl/pcre/zlib呢?只有一个的话,是不是openresy维护的openssl/pcre/zlib?如果是的话,升级或者说安装操作系统中的更新版本的openssl(不是升级openresy维护的openssl),能否升级成功呢?如果升级成功,openresty执行的时候是否会出错呢?
作者回复: openresty 维护的 openssl/pcre/zlib 都会安装在 /usr/local/openresty/ 目录下,并不会冲突。
2 - moshufenmo2019-05-29请问老师,开发openresty使用什么IDE? 一直在用sublime,但是lua文件一多,相互间引用关系就很难查看
作者回复: 没有什么特别好用的,我用的是微软的 vscode
2 - 天天向上2019-05-29mac brew安装貌似很费劲 网上很多方法都报错
作者回复: brew 安装也需要先指定 OpenResty 的仓库地址,具体请查看openresty.org 的文档
2 - 沈康2020-09-26因为项目在内部,无法连接互联网 只能使用源码安装完成,我的经验是: 在官网下载源码:http://openresty.org/cn/ 在github对应版本(history中匹配)的打包文件中查找相关库依赖版本,补丁集,而且打包文件里面,安装完成后删除安装路径都有,稍微改成自己的就可以了:https://github.com/openresty/openresty-packaging/tree/master/rpm/SPECS展开1
- Run2020-01-10最近要为公司的Kong开发插件,需要动态创建更新几千条service,router,customer,还特么是并发场景,Kong本身没有批量创建的API,只能手动撸插件加队列了1
- Paradise2021-12-30我觉得至少要整一个文件来搞吧,通过文件来加载
- Leo2021-11-30我尝试用了下--gdb,看来想调试,不编译源码还是不行的
- Leo2021-11-30看了第一页就买了课,只因为文笔,一看就知道是我想要的,文笔简洁明了,准确周全。思路清晰,一看就是有条理的技术天才。 技术之佳作,文笔之生动。1
- 柯察金2021-10-19我发现用 –p 指定 prefix 之后,nginx conf 里面的 include 指令路径就有问题,运行的时候会把 prefix 与 include 指定的路径直接拼接起来。比如 prefix 是 /abc,而 include 指定的是 ~/xyz,结果它直接给我拼接起来,变成了 /abc/~/xyz,然后就 file not found 了。。。
- 19782021-05-10不知道有没有跟我一样,文章最后的 nginx -p `pwd` -c con/nginx.conf 中的pwd不是password,是当前的目录。可以通过nginx -h 查看 -p命令是什么意思。 同时,关于PATH的设置,我的是Mac环境,使用brew安装的openresty, 安装路径应该是在:/usr/local/Cellar/openresty/1.19.3.1_1 原生nginx配置文件地址为:/usr/local/etc/openresty 应该在文件.bash_profile中去设置PATH, 如果不设置PATH,也可以使用/usr/local/Cellar/openresty/1.19.3.1_1/nginx -p `pwd` -c conf/nginx.conf展开共 2 条评论1