亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在網(wǎng)頁中渲染公式一直是泛學術(shù)工具繞不開的一個功能,最近更新產(chǎn)品功能,正巧遇到了這個需求,于是使用容器方式簡單實現(xiàn)了一個相對靠譜的公式渲染服務。

分享出來,希望能夠幫到有類似需求的同學。

寫在前面

本篇內(nèi)容會分別使用現(xiàn)有開源軟件官方鏡像、定制性能更高的鏡像、進一步搭配 Nginx 來提升整體服務性能以及可靠性。

如果你不熟悉或者不愿意維護 Node 相關(guān)服務,可以將其部署至公有云 Serverless 服務中,搭配緩存服務,更快的獲取產(chǎn)品服務能力,正如軟件描述中所述:Serverless API to render maths using MathJax for Node。

公式渲染服務初體驗

我們先啟動一個開源軟件 Math-API 的官方鏡像容器實例,來先體驗一下使用接口渲染公式。

Docker run --rm -it -p 3000:3000 chialab/math-api

yarn run v1.5.1
$ node bin/server.js
Server running at http://localhost:3000/

接口支持的字段信息在項目文檔中都有,只需根據(jù)自己需求進行調(diào)整即可。為了方便測試,我們這里使用 GET 方式調(diào)用接口,模擬訪問一個能夠動態(tài)渲染圖片的接口。

在服務啟動之后,,使用瀏覽器分別訪問下面的地址:

http://localhost:3000/render?input=latex&inline=0&output=svg&width=256&source=E=mc^2

http://localhost:3000/render?input=latex&inline=0&output=png&width=256&source=E=mc^2

便能看到質(zhì)能方程的公式圖片。

使用 Docker 和 Node 搭建公式渲染服務(前篇)

 

動態(tài)渲染出的質(zhì)能方程公式圖片

如果你是自己個人使用,調(diào)用次數(shù)極少,或者不在意資源消耗可以使用下面的編排文件運行使用。

version: "3.0"

services:

  math-api:
    restart: always
    image: chialab/math-api
    ports:
      - 3000:3000
    logging:
      driver: "json-file"
      options:
        max-size: "1m"

不過如果是要提供公共服務,便需要考慮到各種安全問題、服務性能問題,以及最重要的服務穩(wěn)定性如何。

那么,我們來看看如何提升穩(wěn)定性、并解決基礎(chǔ)安全問題。

思考如何優(yōu)化服務

在優(yōu)化之前,我們先來看看當前國內(nèi)最大的中文社區(qū):知乎,是怎么做的。

我們以 請問你見過的最強的公式是什么? 這篇充滿公式的問題為例,隨便摘取一個公式,觀察圖片內(nèi)容格式:

https://www.zhihu.com/equation?tex=%5Cbegin%7Balign%7D%26%5Cprod_%7Bn%3D1%7D%5E%5Cinfty%5Cfrac%7B%28n%2Ba_1%29%28n%2Ba_2%29...%28n%2Ba_k%29%7D%7B%28n%2Bb_1%29%28n%2Bb_2%29...%28n%2Bb_k%29%7D%5C%5C%26%3D%5Cfrac%7B%5CGamma%281%2Bb_1%29%5CGamma%281%2Bb_2%29...%5CGamma%281%2Bb_k%29%7D%7B%5CGamma%281%2Ba_1%29%5CGamma%281%2Ba_2%29...%5CGamma%281%2Ba_k%29%7D%5Cend%7Balign%7D

可以看到鏈接 tex 參數(shù)后跟著一堆被轉(zhuǎn)碼后的公式內(nèi)容,我們使用 decodeURIComponent 將其解碼,可以看到 LeTax 公式原本內(nèi)容。

decodeURIComponent('%5Cbegin%7Balign%7D%26%5Cprod_%7Bn%3D1%7D%5E%5Cinfty%5Cfrac%7B%28n%2Ba_1%29%28n%2Ba_2%29...%28n%2Ba_k%29%7D%7B%28n%2Bb_1%29%28n%2Bb_2%29...%28n%2Bb_k%29%7D%5C%5C%26%3D%5Cfrac%7B%5CGamma%281%2Bb_1%29%5CGamma%281%2Bb_2%29...%5CGamma%281%2Bb_k%29%7D%7B%5CGamma%281%2Ba_1%29%5CGamma%281%2Ba_2%29...%5CGamma%281%2Ba_k%29%7D%5Cend%7Balign%7D')

begin{align}&prod_{n=1}^inftyfrac{(n+a_1)(n+a_2)...(n+a_k)}{(n+b_1)(n+b_2)...(n+b_k)}\&=frac{Gamma(1+b_1)Gamma(1+b_2)...Gamma(1+b_k)}{Gamma(1+a_1)Gamma(1+a_2)...Gamma(1+a_k)}end{align}

相比較前一小節(jié)中直接在鏈接中傳遞 E=mc^2 展示質(zhì)能方程,如果我們將還原的公式直接拼合到公式接口中,會看到接口報錯(通過接口報錯,我們幾乎可以確定知乎使用的就是類似的方案),這是因為公式中如果包含的 & 字符,那么這個字符前后的內(nèi)容會被切割為不同的參數(shù)傳遞給后端,所以為了避免這類字符在傳遞過程中被錯誤解析,我們一般會將內(nèi)容編碼后進行傳輸。

現(xiàn)在,我們得到了第一個線索:讓參數(shù)編碼后傳輸。

此外,如果我們的使用場景類似知乎,只需要在網(wǎng)頁中展示某個固定的方程,而不需要高度定制這個公式的輸出格式、輸出尺寸,那么可以和知乎一樣,將多數(shù)參數(shù)固化、形成常量配置。

一方面,可以減少開源軟件作者對于各種參數(shù)過濾缺失產(chǎn)生的問題,另外一方面,可以減少服務在運行過程中,被枚舉攻擊而造成資源浪費,甚至服務不可用的可能性,進一步提升服務可靠性和安全性。

那么,我們得到了第二個線索,讓暴露參數(shù)盡可能少。

使用 Nginx 快速優(yōu)化服務

有了前面的兩條線索,我們現(xiàn)在開始優(yōu)化服務。

使用 Nginx 處理網(wǎng)絡請求

結(jié)合前文“公式渲染服務初體驗”小節(jié),和前篇《使用容器搭建簡單可靠的容器倉庫》一文中的配置,不難寫出一個簡單的 docker-compose.yml ,容器編排配置文件:

version: "3.0"

services:

  nginx:
    image: nginx:1.19.8-alpine
    restart: always
    ports:
      - 3000:80
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
    networks:
      - formula
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider --proxy off localhost/get-health || exit 1"]
      interval: 10s
      timeout: 1s
      retries: 3
    logging:
      driver: "json-file"
      options:
        max-size: "1m"

  math-api:
    restart: always
    image: chialab/math-api
    expose:
      - 3000
    networks:
      - formula
    logging:
      driver: "json-file"
      options:
        max-size: "1m"

networks:
  formula:

這里我們主要做了兩件事:

  1. 將兩個應用放置相同的容器網(wǎng)絡中。
  2. 由 Nginx 接受公開的網(wǎng)絡請求,然后再轉(zhuǎn)發(fā)給開源公式應用。

如果你想了解如何使用 Nginx 提供 HTTPS 服務,并盡可能減少代碼,可以翻閱前一篇文章;如果你想了解如何搭配 Traefik 一起提供服務,也可以翻閱之前有關(guān) Traefik 的內(nèi)容,這里不做贅述。

接著我們編寫 Nginx 基礎(chǔ)配置:

server {
    listen 80;

    # 限制只渲染最大1K數(shù)據(jù),避免服務被惡意攻擊
    client_max_body_size 1k;
    access_log off;

    location / {
        proxy_pass http://math-api:3000;
    }

    location = /get-health {
        access_log off;
        default_type text/html;
        return 200 'alive';
    }
}

將配置保存為 default.conf,然后使用 docker-compose up 啟動服務。

依舊訪問前文中的本地端口,這次我們可以將公式內(nèi)容替換為前文中知乎公式圖片的內(nèi)容:

http://localhost:3000/render?input=latex&inline=0&output=svg&width=256&source=%5Cbegin%7Balign%7D%26%5Cprod_%7Bn%3D1%7D%5E%5Cinfty%5Cfrac%7B%28n%2Ba_1%29%28n%2Ba_2%29...%28n%2Ba_k%29%7D%7B%28n%2Bb_1%29%28n%2Bb_2%29...%28n%2Bb_k%29%7D%5C%5C%26%3D%5Cfrac%7B%5CGamma%281%2Bb_1%29%5CGamma%281%2Bb_2%29...%5CGamma%281%2Bb_k%29%7D%7B%5CGamma%281%2Ba_1%29%5CGamma%281%2Ba_2%29...%5CGamma%281%2Ba_k%29%7D%5Cend%7Balign%7D
使用 Docker 和 Node 搭建公式渲染服務(前篇)

 

針對復雜公式的渲染

可以看到圖片渲染的“非常漂亮”。

使用 Nginx 減少請求參數(shù)

減少參數(shù)可以使用非常多的方式,這里選擇一種最基礎(chǔ)的方案,來自 ngx_http_core_module 的 set args 來強制聲明請求參數(shù):

server {
    listen 80;

    # 限制只渲染最大1K數(shù)據(jù),避免服務被惡意攻擊
    client_max_body_size 1k;
    access_log off;

    location / {
        set $args $args&input=latex&inline=0&output=svg&width=256;
        proxy_pass http://math-api:3000;
    }

    location = /get-health {
        access_log off;
        default_type text/html;
        return 200 'alive';
    }
}

重新啟動服務,你會發(fā)現(xiàn)上面的請求參數(shù)可以被簡化為下面這樣:

http://localhost:3000/render?source=%5Cbegin%7Balign%7D%26%5Cprod_%7Bn%3D1%7D%5E%5Cinfty%5Cfrac%7B%28n%2Ba_1%29%28n%2Ba_2%29...%28n%2Ba_k%29%7D%7B%28n%2Bb_1%29%28n%2Bb_2%29...%28n%2Bb_k%29%7D%5C%5C%26%3D%5Cfrac%7B%5CGamma%281%2Bb_1%29%5CGamma%281%2Bb_2%29...%5CGamma%281%2Bb_k%29%7D%7B%5CGamma%281%2Ba_1%29%5CGamma%281%2Ba_2%29...%5CGamma%281%2Ba_k%29%7D%5Cend%7Balign%7D

那么是不是優(yōu)化就到此為止了呢,顯然不是的,如果我們構(gòu)造有風險的參數(shù)、亦或者接收到了被我們固化的參數(shù),參數(shù)類型產(chǎn)生變化,那么服務還是存在一定的隱患。

比如,我們在定義了 output 參數(shù)后,依舊傳遞了這個參數(shù):

http://localhost:3000/render?output=png&...

則會收到諸如 {"message":"Invalid output: png,svg"} 的錯誤提示。

為了避免這類錯誤,所以我們可以進一步改造上面的配置:

server {
    listen 80;

    # 限制只渲染最大1K數(shù)據(jù),避免服務被惡意攻擊
    client_max_body_size 1k;
    access_log off;

    location / {
        if ( $arg_source = '') {
            return 404;
        } 

        set $args source=$arg_source&input=latex&inline=0&output=svg&width=256;
        proxy_pass http://math-api:3000;
    }

    location = /get-health {
        access_log off;
        default_type text/html;
        return 200 'alive';
    }
}

重啟服務,你會發(fā)現(xiàn)即使再構(gòu)造類似下面請求,服務也不會發(fā)生錯誤了。

http://localhost:3000/render?output=png&source=%5Cbegin%7Balign%7D%26%5Cprod_%7Bn%3D1%7D%5E%5Cinfty%5Cfrac%7B%28n%2Ba_1%29%28n%2Ba_2%29...%28n%2Ba_k%29%7D%7B%28n%2Bb_1%29%28n%2Bb_2%29...%28n%2Bb_k%29%7D%5C%5C%26%3D%5Cfrac%7B%5CGamma%281%2Bb_1%29%5CGamma%281%2Bb_2%29...%5CGamma%281%2Bb_k%29%7D%7B%5CGamma%281%2Ba_1%29%5CGamma%281%2Ba_2%29...%5CGamma%281%2Ba_k%29%7D%5Cend%7Balign%7D

以及,是如果未傳遞公式內(nèi)容請求服務,也會由 Nginx 直接返回一個 404 Not Found,而不是直接將錯誤請求透傳到公式應用。

最后

迄今為止,我們已經(jīng)使用 Nginx 和開源軟件 Math-API 搭建了一個基礎(chǔ)的公式服務。

下一篇文章,我們將進一步調(diào)教 Nginx 和應用容器,在盡可能不編碼的情況下繼續(xù)進行性能調(diào)優(yōu)。

分享到:
標簽:Docker
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定