写点什么

Nginx 为什么要造重复的轮子 nginScript

  • 2015-10-14
  • 本文字数:1475 字

    阅读完需:约 5 分钟

前不久,Nginx发布了一种“代理端”的JavaScript 实现 nginScript 。该实现可以提高 Nginx 的脚本能力,使 Nginx 配置更简单、操作更高效,使用户无需编写 C 模块就可以在 Nginx 中做更多的事情。目前, nginScript 解析器仅支持 ECMAScript 5 的一个子集,不过后续还会扩展。在对 JavaScript 求值时,nginScript 会使用一个基于寄存器的虚拟机将 JavaScript 编译成字节码然后在 Nginx(或 Nginx Plus)中运行。

许多人对此都非常好奇,既然已经有了 V8 SpiderMonkey 或其它实现,为什么还要实现一个新的 JavaScript 运行时。 Hacker News 上也出现了大量不同的声音。比如,网友 stanleydrew 就认为这个做法很糟糕,因为它可能让 Nginx 这个原本很棒的工具走上膨胀之路。对此,网友 n42 表示:

任何你不想用的特性都是膨胀,但用到的时候就必要了。

而网友 eknkc 则认为:

它是一个很好的补充。我在高业务量的服务器使用了 Varnish,一个原因就是它有“可视化组件库”,这是一种类 JavaScript 的语言,可以用它来定义请求处理逻辑。nginx 将为熟悉它的人提供许多配置选项。

针对这些疑惑和争论,Nginx 近日专门撰文解释了他们为什么要创建自己的JavaScript 实现。

Nginx 有一些独特的需求,他们希望 nginScript 代码片段可以在 Nginx 处理请求时运行,以此扩展 Nginx 处理请求和响应的能力。但是,他们无意创建一个像 Node.js 那样的持久化的 JavaScript 应用程序运行时环境。

然而,现有的 JavaScript 运行时都是针对 Web 浏览器而设计的,依赖于垃圾收集,很难控制 JavaScript VM 的资源使用。如果内存溢出,它们就会异常退出。这在浏览器端尚可接受,但在服务器端是不可容忍的。他们希望 nginScript 能够提供简洁且可以快速执行的规则,而不是对 JavaScript 的完整支持。而且,Nginx 已经有一个经过充分优化的、事件驱动的架构,所以他们不希望受垃圾收集所带来的性能不可预见性所影响。

出于上述种种考虑,他们实现了一种非常简单但与其需求相匹配的 JavaScript 运行时:

  • 架构——单线程、字节码执行是为了实现快速初始化和处理。由于每个请求会分配一个单独的虚拟机,所以不需要垃圾收集。虚拟机没有复杂的状态或辅助程序初始化,启动速度非常快。
  • 辅助函数——内置操作在 Nginx 本地实现,用户可以将 nginScript 视为一种通过编程驱动 Nginx 本地操作的方式。
  • 预占——Nginx 事件驱动模型负责调度单个 nginScript VM 的执行。当 nginScript 规则执行阻塞操作时,Nginx 会暂停那个虚拟机的执行,待事件完成后再重新调度。这意味着,用户可以采用一种简单线性的方式编写规则,Nginx 会调度它们,而且不会有内部阻塞。

截止目前,nginScript 尚处于早期开发阶段,当前版本为预览版,其团队一直致力于功能的构建,开发主要是围绕完成核心的语言实现以及实现许多内置的 JavaScript 对象(如 Date、Math 等)进行。因此,谈论 nginScript 的性能还为时过早。但测试表明,nginScript VM 的性能同其它解释型语言(PHP、Ruby 等)类似,但不如 JIT 实现快。同时,nginScript 团队还专注于 nginScript VM 与 Nginx 的整合,比如,如何在 Nginx 配置中引用 nginScript 规则,nginScript 如何访问和控制 Nginx 内部构件。对于长时间运行的脚本,他们可能还会引入垃圾收集。nginScript 的完整路线图尚未形成,读者可以通过邮件列表分享自己的想法。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-10-14 19:007535
用户头像

发布了 1008 篇内容, 共 448.4 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

NKD:容器云集群与 OS 一体化运维利器

openEuler

Linux Kubernetes 云原生 操作系统 openEuler

Java日记——使用强大的Elastisearch搜索引擎

java易二三

Java 编程 程序员 计算机

JSP的内置对象

java易二三

编程 程序员 计算机

产业共振 智能涌现!8月16日飞桨携手生态伙伴带来大模型企业应用创新实践

飞桨PaddlePaddle

人工智能 百度飞桨 百度AI 文心大模型

GPT-4助力数据分析:提升效率与洞察力的未来关键技术 | 京东云技术团队

京东科技开发者

数据分析 ChatGPT4 企业号 8 月 PK 榜

质量指标如何发挥作用?构建质量能力是关键

BY林子

质量指标 质量度量 质量能力

山东布谷科技直播系统源码热点分析:不同芯片实现高质量编码与渲染视频的GPU加速功能

山东布谷科技

GitOps 与 DevOps:了解关键差异,为企业做出最佳选择

SEAL安全

DevOps 运维 gitops 企业号 8 月 PK 榜

分享实录 | 将 NGINX 打造成功能强大的 API 网关(上)

NGINX开源社区

nginx 微服务 k8s API api 网关

买量业务福音:自有App运行小游戏

FinFish

小游戏 App运行小游戏 游戏买量

SSM框架——使用MyBatis Generator自动创建代码

java易二三

编程 程序员 mybatis 计算机

持续赋能 AI 应用,和鲸 ModelWhale 入选“2023 数字生态500强”优秀案例&解决方案榜单

ModelWhale

人工智能 大模型 数字生态 AIGC

Java中final、finally和finalize的区别

java易二三

Java 程序员 计算机 final

国产 etl engine 监控面板 为管理者掌握平台运行情况,决策执行方案提供即时数据支撑

weigeonlyyou

数据库 数据交换 物联网 ETL 云数据迁移

MES和ERP的区别

优秀

ERP mes mes和erp区别

英特尔CEO称AI PC时代于今秋开启 联想将首批发布

E科讯

OpenSSL 3.0.0 设计(二)|Core 和 Provider 设计

铜锁开源密码库

开源 开发者 算法 信息安全 密码学

透过源码,捋清楚循环依赖到底是如何解决的!

江南一点雨

Java spring

一文详述流媒体传输网络MediaUni

阿里云CloudImagine

云计算 视频云

内卷和躺平之外,职场还有其他选择

老张

职场成长

明道云联合Kyligence结合示范性场景应用

明道云

选择FastAPI或Flask:Python Web开发框架的终极指南

Apifox

Python flask 框架 web开发 FastApi

北航基于openEuler构建工业机器人操作系统,打造“开箱即用”的机器人基础软件平台

openEuler

Linux 操作系统 机器人 嵌入式 openEuler

移动云操作系统改造技术实践分享,跨操作系统云主机迁移优化(一)

openEuler

Linux centos 操作系统 迁移 openEuler

研发提测前测试到底能做些什么 | 京东云技术团队

京东科技开发者

测试 测试开发 企业号 8 月 PK 榜

spring多数据源动态切换的实现原理及读写分离的应用 | 京东云技术团队

京东科技开发者

spring 读写分离 企业号 8 月 PK 榜 AbstractRouting 动态切换

鸿蒙智联再出发,携手伙伴共赢空间智能化,创造无限可能

HarmonyOS开发者

HarmonyOS

Nginx为什么要造重复的轮子nginScript_JavaScript_谢丽_InfoQ精选文章