【譯文】NginScript – 爲何咱們要實現本身的JS引擎?

在上週的nginx.conf 2015用戶大會上,咱們發佈了全新的JavaScript引擎nginscript的預覽版。歷史上,JavaScript語言已經應用在許多方面,首先是做爲客戶端腳本,而後又被用於服務器後臺開發。至於nginscript,咱們要介紹的是第一種"代理端"的使用狀況,用於知足咱們在會上提出的一系列獨特的要求。消息公佈後,許多人對咱們決定要實現一個新的JavaScript引擎,而不是使用V8SpiderMonkey,或其餘的已有引擎而感到好奇,因此這篇文章用於解釋咱們爲何這麼作。 nginx


咱們正在作什麼?
咱們正在編寫本身的JavaScript引擎,稱爲nginscriptnginscript目前支持解析器ECMAScript 5的一個子集(咱們將在將來進行擴展),採用基於寄存器的虛擬機(VM),運行時將把代碼編譯成字節碼,同時支持 nginxnginx plus。在目前的預覽階段,nginx能夠編譯JavaScript代碼並用在兩個場景:產生nginx的配置,或者在nginx執行階段生成內容。將來的版本將支持更多的使用場景。
編程


爲何要建立本身的JavaScript運行時?
Nginx
有一些特別的需求致使咱們要去創造屬於咱們本身的引擎。爲了擴展請求應的處理流程,咱們須要nginx在處理一個請求時能夠運行nginscript片斷。咱們不尋求創造一個後端JavaScript應用程序執行環境由於Node.js已經作的很好。目前的JavaScript引擎被設計爲運行在一個Web瀏覽器中,他們依靠垃圾收集器的管理內存。若是耗盡內存,JavaScript VM會異常退出;這種行爲對於瀏覽器是能夠容忍的。可是對於持有數千個鏈接的服務器卻不行,總的來講,專門爲瀏覽器設計的引擎不適合服務器,包括v8SpiderMonkey它們沒有供簡單的方法來控制執行(即預防奔潰和恢復虛擬機的機制),同時支持JIT的能力有限。咱們但願能有一種引擎將nginscript的腳本簡單並快速的執行。同時,由此產生的狀態被保存在虛擬機外部。由於腳本簡單,因此全面支持JavaScript語言沒有必要。同時,nginx已經擁有很是精細的事件驅動架構,咱們不想nginx的性能受到垃圾收器的影響。
後端

相反,咱們正在建立一個很是簡單的引擎以知足咱們的要求:
架構使用單線程,字節碼的執行部分將會很是快速。爲每一個請求分配虛擬機。由於沒有複雜的狀態須要初始化,這種簡單的虛擬機能夠快速啓動,同時使用簡單的緩存池管理內存。這種內存管理方案,無需跟蹤和釋放單個對象或使用垃圾回收器,能夠大大提升性能。
輔助功能 –Nginx實現了許多內置操做。例如,複雜的數學運算,哈希函數,當nginscriptnginx結合時,這些操做也會是本地的。你可使用nginscript以編程的方式來驅動nginx的本地方法。
nginx配合 – nginx的事件驅動模型能夠用於調度nginscript VMS的執行。當一個nginscript正在執行阻塞操做(如讀取網絡數據),nginx能夠暫停該VM的執行,當該VM的事件完成後再恢復。這意味着你能夠在編寫一個簡單的腳本, nginx會調度腳本不形成阻塞。最後,用咱們本身的引擎,咱們能夠保證API統一,同時確保咱們的VMnginx支持的平臺範圍一致。
瀏覽器

 

關於性能
如今談論性能還過早,目前咱們正在專一於功能的實現。nginscript編譯爲內部的字節碼而且運行在一個基於寄存器的虛擬機;這種機制使得它和其餘解釋性語言(PHPRuby,等等)性能至關。因此爲了提升性能,咱們想在一些地方增長JIT編譯,但這可能會限制支持的平臺範圍。nginscript只是被設計用來執行一些簡單的內部腳本,咱們不想讓它來執行計算密集型操做,由於nginx內部基於C語言的模塊已經解決這個問題。
緩存

將來
nginscript
目前處於其發展的早期階段,咱們稱當前版本是"預覽"版。咱們將重點放在覈心語言的實現(如增長閉包),並實施許多內置的JavaScript對象(日期,數學,等等)。
咱們還將重點放在如何整合資源,好比nginx的配置如何集成腳本,在哪些方面nginscript能夠訪問和控制nginx內部?如何在腳本之間共享數據,以及跨集羣?用戶如何調試nginscript腳本?
對於長時間運行的腳本(如WebSocket),咱們甚至能夠添加一個垃圾收集器,但那是在將來好久之後。
對於nginscript將來如何發展目前尚未定論。咱們但願獲得您的反饋。請在咱們的郵件列表中分享您的想法和看法,咱們將共同開發這個功能。謝謝你。
服務器

相關文章
相關標籤/搜索