Python 3.x 远程使用Jupyter笔记本时,Pyviz Panel app.show()不起作用

Python 3.x 远程使用Jupyter笔记本时,Pyviz Panel app.show()不起作用,python-3.x,jupyter-notebook,bokeh,ssh-tunnel,pyviz,Python 3.x,Jupyter Notebook,Bokeh,Ssh Tunnel,Pyviz,我在Ubuntu服务器上的CentOS虚拟机上安装了Anaconda。然后,我在这个VM上为所有python数据科学库创建了一个conda环境。我的笔记本电脑上有一个匹配的conda环境 然后,我遵循本指南,使用笔记本电脑上的Jupyter笔记本远程执行服务器上的数据分析: 我能够成功地将我的Jupyter笔记本加载到我的笔记本电脑上,并在服务器上执行分析。我还可以在笔记本中将已完成的应用程序标记为.servable(),然后在虚拟机终端上使用面板服务--show…,通过web浏览器将已完成的交

我在Ubuntu服务器上的CentOS虚拟机上安装了Anaconda。然后,我在这个VM上为所有python数据科学库创建了一个conda环境。我的笔记本电脑上有一个匹配的conda环境

然后,我遵循本指南,使用笔记本电脑上的Jupyter笔记本远程执行服务器上的数据分析:

我能够成功地将我的Jupyter笔记本加载到我的笔记本电脑上,并在服务器上执行分析。我还可以在笔记本中将已完成的应用程序标记为
.servable()
,然后在虚拟机终端上使用
面板服务--show…
,通过web浏览器将已完成的交互式应用程序提供给局域网用户

我的问题是,当我用
.show()
标记我的应用程序以允许我在笔记本中查看当前正在处理的应用程序/报告时,我会输出以下消息:
,但该应用程序没有按预期加载到新的浏览器选项卡中

在远程而非本地使用Jupyter笔记本时,如何使
app.show()
工作


针对@Sandervandeoord的回答,于20年1月23日更新: “您需要指定.show()的端口,并确保用户可以访问远程服务器上的该端口”

为了说明这个问题(不是实际情况),假设我的服务器VM是地址192.168.0.1,我的笔记本电脑是192.168.0.2,我想与
app.show()一起使用的端口是3333

1. 设置端口:

在服务器上(192.168.0.1):

  • 检查端口3333是否未被使用:
    sudolsof-i:3333
  • 检查iptables是否未将端口显示为打开状态:
    sudo iptables保存| grep 3333
  • 将端口添加到/etc/services文件:
    sudo nano/etc/services
  • 我将以下行添加到文件顶部并保存:
#服务名称端口/协议[别名…][#注释]
bokeh服务器3333/tcp#打开端口以允许app.show()在远程执行的Jupyter笔记本上工作
  • 启用防火墙:
    sudo systemctl启用防火墙d
  • 启动防火墙:
    sudo systemctl启动防火墙d
  • 检查防火墙的状态:
    sudo systemctl状态防火墙d

  • 确认此端口现在已打开:
    sudo iptables保存| grep 3333

    输出:
    -A IN_public\u allow-p tcp-m tcp--dport 3333-m conntrack--ctstate NEW-j ACCEPT


  • 测试用户是否可以访问服务器上的端口:
我在服务器上安装了ncat192.168.0.1):
sudo yum安装nmap ncat-y

然后,我在服务器和笔记本电脑之间设置消息:

  • 在服务器上:
    nc-l 3333
  • 在笔记本电脑上:
    nc 192.168.0.1 3333
在笔记本电脑和服务器之间:

  • 在笔记本电脑上:
    nc-l 3333
  • 在服务器上:
    nc 192.168.0.2 3333

  • 消息成功地从服务器发送到笔记本电脑,反之亦然

  • 确认这两个连接:
    sudolsof-i:3333

输出:

命令PID用户FD类型设备大小/关闭节点名称
nc 1776 XXX 5u IPv4 23627 0t0 TCP vmserver:bokeh服务器->192.168.0.2:55358(已建立)
nc 1846 XXX 3u IPv4 22895 0t0 TCP vmserver:33658->192.168.0.2:bokeh服务器(已建立)
显示端口3333上的服务器可以在不同端口与笔记本电脑通信,端口3333上的笔记本电脑可以在不同端口与服务器通信

我不知道如何让它们连接在同一个端口上?都在3333端口?这是我问题的根源吗

  • 然后在我的jupyter笔记本中,我将
    app.show()
    替换为
  • app.show(端口=3333,websocket\u原点=None,线程=False)
    
    然而,我仍然体验到与之前相同的行为,即应用程序没有按预期加载到新的浏览器选项卡中

    然后我尝试了参数
    websocket\u origin
    (尝试了“192.168.0.1”、“192.168.0.2”和“*”)和
    threaded
    (真/假),但更改这些参数并没有在新的浏览器选项卡中加载应用程序的预期结果

    有几个有趣的地方

    1.如果我运行我的笔记本

    app.show(端口=3333,websocket\u原点=None,线程=False)
    
    然后在服务器上运行:
    sudolsof-i:3333

    然后返回以下内容:

    命令PID用户FD类型设备大小/关闭节点名称
    ZMQbg/1 19328 xxx 45u IPv4 83214 0t0 TCP*:bokeh服务器(侦听)
    ZMQbg/1 19328 xxx 54u IPv6 83215 0t0 TCP*:bokeh服务器(侦听)
    
    服务器似乎在等待端口3333上发生什么事情?听?与我在服务器和笔记本电脑之间发送消息(反之亦然)时不同,实际上似乎没有建立起连接

    请注意,以上两行仅在我运行笔记本后出现。

  • 在我执行笔记本后(新选项卡中的应用程序尚未打开),如果我再次尝试执行笔记本,我会在jupyter笔记本中收到以下警告:
    OSError:[Errno 98]地址已在使用中

  • 看来服务器和笔记本电脑之间的连接已经建立了,或者至少是保留了?要解决此问题,我必须关闭与服务器的连接
    Signature: .show(port=0, websocket_origin=None, threaded=False)
    Docstring:
    Starts a bokeh server and displays the Viewable in a new tab
    
    Arguments
    ---------
    port: int (optional, default=0)
      Allows specifying a specific port
    websocket_origin: str or list(str) (optional)
      A list of hosts that can connect to the websocket.
    
      This is typically required when embedding a server app in
      an external web site.
    
      If None, "localhost" is used.
    threaded: boolean (optional, default=False)
      Whether to launch the Server on a separate thread, allowing
      interactive use.
    
    Returns
    -------
    server: bokeh.server.Server or threading.Thread
      Returns the bokeh server instance or the thread the server
      was launched on (if threaded=True)