Python 为什么web服务器上的bokeh plot加载如此缓慢?

Python 为什么web服务器上的bokeh plot加载如此缓慢?,python,nginx,flask,bokeh,Python,Nginx,Flask,Bokeh,我真的很喜欢博克,我想在我的网站上有一个博克情节。使用bokehserve在本地(Linux上)运行bokeh非常有魅力。但是我很难让它在web服务器上顺利运行 我在DigitalOcean droplet上运行它(Ubuntu18.04,带有LAMP stack和反向代理nginx)。因为我读到《博凯服务》不适合生产,所以我尝试建立一个更安全、更健壮的环境。我用这个开始。经过一次又一次的在线研究和反复试验,我终于让它开始工作了 嗯,至少有点,因为它非常慢。在某种程度上,我花了一段时间才注意到它

我真的很喜欢博克,我想在我的网站上有一个博克情节。使用
bokehserve
在本地(Linux上)运行bokeh非常有魅力。但是我很难让它在web服务器上顺利运行

我在DigitalOcean droplet上运行它(Ubuntu18.04,带有LAMP stack和反向代理nginx)。因为我读到《博凯服务》不适合生产,所以我尝试建立一个更安全、更健壮的环境。我用这个开始。经过一次又一次的在线研究和反复试验,我终于让它开始工作了

嗯,至少有点,因为它非常慢。在某种程度上,我花了一段时间才注意到它一开始就起作用了,而且几乎无法使用。通常需要4秒,有时长达10秒(考虑到我的互联网连接不是很快)

不过,模板中的html加载速度相当快。但是
bokeh.min.js?v=540…
(748KB)
bokeh widgets.min.js?v=409…
(97KB)
bokeh tables.min.js?v=623…
(256KB)
bokeh gl.min.js?v=823…
(62KB)
花很长时间

我检查过了,这也是以我使用的作为起点的网站的情况。 官方的bokeh示例(例如)很快加载了复杂得多的图形,但上面提到的文件也小得多

这是nginx conf文件的一部分:

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/user/myproject/myproject.sock;
    }

    # reverse proxy to embedded bokeh apps
    location /bokeh/ {
        proxy_pass http://127.0.0.1:5100;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:$server_port;
        proxy_buffering off;
    }

这是打印文件
run_bokeh.py

from bokeh.plotting import figure
from bokeh.layouts import column
from bokeh.server.server import Server

def run(doc):

    x = [1, 2, 3, 4, 5]
    y = [6, 7, 2, 4, 5]

    fig = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
    fig.line(x, y, legend="Temp.", line_width=2)

    layout = column(fig)
    doc.add_root(layout)


kws = {'port': 5100, 'prefix': '/bokeh', 'allow_websocket_origin': ['my-domain.com']}
server = Server(run, **kws)
server.start()
if __name__ == '__main__':
    server.io_loop.add_callback(server.show, '/')
    server.io_loop.start()
from flask import Flask, render_template
from bokeh.embed import server_document

app = Flask(__name__)

@app.route("/")

def index():
    tag = server_document(url=r'/bokeh', relative_urls=True)
    return render_template('index.html', tag=tag)
烧瓶文件
myproject.py

from bokeh.plotting import figure
from bokeh.layouts import column
from bokeh.server.server import Server

def run(doc):

    x = [1, 2, 3, 4, 5]
    y = [6, 7, 2, 4, 5]

    fig = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
    fig.line(x, y, legend="Temp.", line_width=2)

    layout = column(fig)
    doc.add_root(layout)


kws = {'port': 5100, 'prefix': '/bokeh', 'allow_websocket_origin': ['my-domain.com']}
server = Server(run, **kws)
server.start()
if __name__ == '__main__':
    server.io_loop.add_callback(server.show, '/')
    server.io_loop.start()
from flask import Flask, render_template
from bokeh.embed import server_document

app = Flask(__name__)

@app.route("/")

def index():
    tag = server_document(url=r'/bokeh', relative_urls=True)
    return render_template('index.html', tag=tag)
我不知道如何使
bokeh…..min.js
文件变小,也不知道我的设置是否存在根本性问题。

附言: 我可以找到很多关于如何在开发模式下使用bokeh的教程(甚至是视频教程),以及
bokeh-serve
。但很少有人知道如何在生产中使用它。因此,如果有人能为我指出一个方向,关于如何正确地学习在生产服务器上使用bokeh,我将非常感激

更新
  • 我想我没有正确地表达我的意思。通过将
    bokeh…..min.js
    文件变小,我的意思是在我的设置中加载的文件是官方示例或CDN中的文件的四倍大
    https://my-domain.com/bokeh/static/js/bokeh.min.js?v=547e7d2591695b654def5914bdd697fa
    → 748KB
    https://cdn.bokeh.org/bokeh/release/bokeh-1.3.4.min.js
    → 202 KB
    我想知道怎么去202 KB

  • 我尝试给我们提供CDN,但它不起作用。
    我从bokeh.resources import CDN添加了
    myproject.py
    ,但是我不知道在哪里插入
    CDN
    server\u文档(…)
    需要一个资源字符串)

当我手动将脚本添加到模板文件
index.html
时,它会被阻止(阻止混合内容),其他脚本也会被加载

<link href="https://cdn.bokeh.org/bokeh/release/bokeh-1.3.4.min.css" rel="stylesheet" type="text/css">
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-1.3.4.min.js"></script>

我首先要提到的是,Bokeh的下一个版本(1.4)将支持:

  • 直接SSL终止(即https连接)
  • 为登录/注销提供“身份验证挂钩”
也就是说,有时仍然有很好的理由运行Nginx这样的代理,例如负载平衡

关于您的具体问题:演示站点可能更快地加载这些资源的一个原因是它被配置为从Bokeh CDN加载它们。在这方面,它做到了:

ENV BOKEH_RESOURCES=cdn
因此,在运行BOKEH服务器之前,您还可以尝试设置
BOKEH_RESOURCES
环境变量。从CDN(即AWS Cloudfront)加载:

  • 可能比从DO加载要快
  • 将减轻Bokeh服务器本身的负载
  • 允许用户浏览器缓存JS文件
这是我的第一个建议。如果在那之后,事情仍然太慢,那么我们可以考虑删除不需要的JS文件(例如,如果您不使用WebGL或
DataTables
,则至少不需要其中两个文件)。但这可能需要更多的反复讨论和实验,因为我不确定如果不“以编程方式”使用服务器,这是否可行。所以我想说,这是一个更好的讨论场所

至于:

我不知道如何使bokeh…..min.js文件变小


没有办法让它们变小,它们就是它们的大小。在最近的一个版本中,由于内联CSS,大小确实增加了一些,但这被不再需要加载单独的CSS文件所抵消。总负载大小应该大致相等(如果大小意外增长,我们实际上有CI测试将失败)。

我首先要提到的是,Bokeh的下一个版本(1.4)将支持:

  • 直接SSL终止(即https连接)
  • 为登录/注销提供“身份验证挂钩”
也就是说,有时仍然有很好的理由运行Nginx这样的代理,例如负载平衡

关于您的具体问题:演示站点可能更快地加载这些资源的一个原因是它被配置为从Bokeh CDN加载它们。在这方面,它做到了:

ENV BOKEH_RESOURCES=cdn
因此,在运行BOKEH服务器之前,您还可以尝试设置
BOKEH_RESOURCES
环境变量。从CDN(即AWS Cloudfront)加载:

  • 可能比从DO加载要快
  • 将减轻Bokeh服务器本身的负载
  • 允许用户浏览器缓存JS文件
这是我的第一个建议。如果在那之后,事情仍然太慢,那么我们可以考虑删除不需要的JS文件(例如,如果您不使用WebGL或
DataTables
,则至少不需要其中两个文件)。但这可能需要更多的反复讨论和实验,因为我不确定不使用se是否能够做到这一点