欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览
- 今天咱们以Java程序员的视角,来聊聊如何用Java来扩展Nginx的能力,全文由以下内容组成:
- 什么是Nginx
- 什么是Nginx扩展
- 扩展Nginx,意义何在?
- 想用Java扩展Nginx会有问题吗?
- 主角登场:nginx-clojure模块,让Java扩展Nginx成为显示
- 总的来说这是一篇从概念到实践的入门文章,接下来,一起开始愉快的nginx-clojure之旅吧!
关于Nginx
- 以欣宸自己为例,nginx对java程序员来说并不陌生,下图应该是最常见的使用场景了:反向代理
关于Nginx扩展
- 除了反向代理,nginx的模块化机制让nginx具备了更多丰富的特性,例如ngx_http_log_module(日志)、ngx_http_rewrite_module(重定向)等
- 除了官方模块,还有很多强大第三方模块可以选择,如下图,更多详情参考:https://www.nginx.com/resources/wiki/modules/
- 大名鼎鼎的OpenResty就是基于 Nginx 扩展的,用Lua做二次开发web功能,得到了广泛的应用
- 如此看来,在nginx上做二次开发并非神秘高深莫测,我们也可以按照自己的需要去定制和扩展nginx的功能
- 作为一名Java程序员,自然就想到了:可以用Java去扩展Nginx的能力吗?
为什么要用java对nginx扩展?
- 把java代码写在nginx上,让nginx与业务耦合的可能性变大,经验丰富的您一定会发现这是个危险的趋势,毕竟nginx已经接近后台服务的最外层了,稳定是首要考虑的,正常情况下,下图这种用法才是生产环境的常见fang方案:将nginx作为反向代理,业务功能独立部署
- 这么看来,在nginx上写java代码是否合适呢?欣宸给不出权威答案,但是可以从大神的作品中得到启示
- 开涛大神的《跟我学Nginx+Lua开发》讲述了如何用OpenResty在Nginx上用Lua进行开发,适用于web应用、接入网关、Web防火墙、缓存服务器等场景下,并且在实体书《亿级流量网站架构核心技术》也有详细说明,例如京东商品详情页,就是在nginx上读取缓存直接返回的
- 综上所述,欣宸不会因为学习了这个技术,就把业务逻辑全部在nginx上实现,但是在缓存、鉴权等场景,可以考虑用熟悉的java在nginx上实现
Java程序员的尴尬
- 定制Nginx,打造高性能Web服务,带着这个美好憧憬,我打开了有关模块开发的Nginx官方资料
- 然后,画风开始剧变,而且是朝着我不想面对的方向,如下图
- 模块开发用的居然是C语言!然而,欣宸只是个精通CRUD的Java程序员啊
- 这可怎么办?随手打开一个网页就让梦想破灭?
nginx-clojure,让Java扩展nginx成为现实
- 经过一番搜索,终于找到了nginx-clojure模块,如下图,是它让java扩展nginx成为现实
- nginx-clojure的作用很好理解:OpenResty支持用Lua扩展nginx,nginx-clojure支持用Java扩展nginx
- nginx-clojure的作用很好理解:OpenResty支持用Lua扩展nginx,nginx-clojure支持用Java扩展nginx
关于nginx-clojure
- nginx-clojure是个第三方Nginx模块,官方的介绍是Nginx module for embedding Clojure / Java / Groovy programs, typically those Ring based handlers
- nginx-clojure模块支持嵌入式Clojure(闭包)、Java、Groovy等基于Ring的处理器(handler),那什么是Ring呢?
- Ring 在 Clojure 中是一个构建 Web 应用的底层接口和库. 它和 Ruby 的 Rack, Python 里面的WSGI 或者 Java Servlet 规范相似
- 从java开发者角度来看,就是开发NginxJavaRingHandler的实现类,然后该类可以在nginx-clojure模块中被运行
- nginx-clojure的最新版本是v0.5.2,官网地址是:https://nginx-clojure.github.io
实战功能介绍
- 尽管nginx-clojure支持很多功能,但是篇幅所限,因此本篇以了解为主,还是经典的Hello world,更多精彩内容留给后续的系列文章
- 今天的实战效果如下图,咱们编写HelloHandler.java并在nginx做好配置,然后用浏览器发起请求后,HelloHandler的代码就会被执行,浏览器会收到HelloHandler返回的内容,这就证实了java代码可以在nginx上运行:
- 为了实现上述功能,接下来的操作步骤如下图:
- 感谢您听我唠叨了这么久,接下来,实战开始
环境信息
- 这里给出我的实战环境信息供您参考,这个环境可以正常运行所有实战:
- 操作系统:macOS Big Sur 11.5.2 (20G95)
- JDK:1.8.0_281
- Maven:3.8.1
下载集成了nginx-clojure模块的nginx包
- 咱们要做的第一件事是下载一个特别的nginx,之所以说它特别,是因为它已集成了nginx-clojure模块,开箱即用
- 下载地址:https://sourceforge.net/projects/nginx-clojure/files/ ,如下图红框,我这里选择的是最新的0.5.2版本:
解压nginx包
- 下载完毕后,解压,得到名为nginx-clojure-0.5.2的文件夹,里面的内容如下
- 接下来根据您的操作系统对可执行文件做重命名,我这边是macOS,所以把nginx-macosx重命名为nginx,如果是linux,把nginx-linux-64重命名为nginx,如果是windows,就把nginx-win64.exe重命名为nginx.exe
- 上述重命名操作是nginx-clojure官方推荐的,统一可执行文件名,这样运行文档中的命令就统一了
- 执行命令./nginx -v,控制台响应如下,可见nginx版本是1.18.0:
./nginx -v
nginx version: nginx/1.18.0
编码,开发java版handler
- 接下来开始写代码,先新建一个maven工程(我这里名叫simple-hello),pom.xml中需要配置repository节点,以及唯一的依赖nginx-clojure,如下所示:
<repositories>
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
</repositories>
<dependencies&