You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用资源采集脚本的输出更新Bokeh机器监控时序图?

如何让Bokeh脚本获取外部的CPU/内存使用率数据?

你现在的需求很明确:用Bokeh做一个时序图展示多台机器的CPU和内存使用率,已经有了数据拉取脚本,不想用文件读写这种比较笨重的方式,想找更高效的方案对吧?我给你整理几个实用的思路,结合你提供的示例代码来改就行:

1. 最直接:把数据拉取逻辑集成到Bokeh脚本里

如果你的数据拉取脚本只是一个简单的函数(不是独立运行的服务),那直接把拉取逻辑搬到Bokeh的更新函数里是最省事的,完全不用跨进程通信。比如把示例里的随机数替换成你的拉取函数返回值:

import numpy as np
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear

# 替换成你实际的资源数据拉取函数
def fetch_system_stats():
    # 这里调用你的数据拉取逻辑,返回CPU和内存使用率(0-100的数值)
    cpu_usage = get_cpu_usage()  # 假设这是你原脚本里的拉取函数
    mem_usage = get_mem_usage()
    return cpu_usage, mem_usage

tools = 'pan'

@linear()
def update(step):
    # 用真实数据替换随机数
    cpu, mem = fetch_system_stats()
    ds1.data['x'].append(step)
    ds1.data['y'].append(cpu)
    ds2.data['x'].append(step)
    ds2.data['y'].append(mem)
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)

p = figure(plot_width=400, plot_height=400)
r1 = p.line([], [], color="firebrick", line_width=2, legend='CPU使用率')
r2 = p.line([], [], color="navy", line_width=2, legend='内存使用率')

ds1 = r1.data_source
ds2 = r2.data_source

curdoc().add_root(p)
curdoc().add_periodic_callback(update, 500)

这种方案的好处是没有额外的开销,逻辑也清晰,适合拉取逻辑不复杂的场景。

2. 进程间通信(IPC):用队列传递数据

如果你的数据拉取脚本是独立运行的进程(比如已经在后台持续跑着),那可以用Python的multiprocessing.Queue来做进程间的数据传递,比文件读写高效多了,还不会有IO阻塞和同步问题。

第一步:改造数据拉取脚本为生产者进程

把拉取逻辑封装成一个进程,持续往队列里推送数据:

from multiprocessing import Process, Queue
import time

def stats_producer(queue):
    while True:
        # 你的数据拉取逻辑
        cpu = get_cpu_usage()
        mem = get_mem_usage()
        queue.put((cpu, mem))  # 把数据放进队列
        time.sleep(0.5)  # 和Bokeh的更新频率保持一致

第二步:在Bokeh脚本里启动生产者并消费数据

import numpy as np
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
from multiprocessing import Queue, Process

# 导入你的数据拉取函数或者生产者进程
from stats_producer_script import stats_producer

# 创建队列并启动生产者进程
queue = Queue()
producer = Process(target=stats_producer, args=(queue,))
producer.daemon = True  # 让生产者进程随Bokeh主进程一起退出
producer.start()

tools = 'pan'

@linear()
def update(step):
    # 检查队列里有没有新数据
    if not queue.empty():
        cpu, mem = queue.get()
        ds1.data['x'].append(step)
        ds1.data['y'].append(cpu)
        ds2.data['x'].append(step)
        ds2.data['y'].append(mem)
        ds1.trigger('data', ds1.data, ds1.data)
        ds2.trigger('data', ds2.data, ds2.data)

p = figure(plot_width=400, plot_height=400)
r1 = p.line([], [], color="firebrick", line_width=2, legend='CPU使用率')
r2 = p.line([], [], color="navy", line_width=2, legend='内存使用率')

ds1 = r1.data_source
ds2 = r2.data_source

curdoc().add_root(p)
curdoc().add_periodic_callback(update, 500)

3. 共享内存:适合高频小数据传递

如果你的数据只是简单的数值(比如每次只传最新的CPU和内存值),还可以用multiprocessing的共享内存对象(Value或Array),这种方式的开销比队列还小,适合超高频率的数据更新场景。

比如:

生产者进程部分

from multiprocessing import Process, Value
import time

def stats_producer(cpu_val, mem_val):
    while True:
        cpu_val.value = get_cpu_usage()
        mem_val.value = get_mem_usage()
        time.sleep(0.5)

Bokeh脚本部分

import numpy as np
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
from multiprocessing import Value, Process
from stats_producer_script import stats_producer

# 创建共享内存变量
cpu_usage = Value('d', 0.0)  # 'd'表示双精度浮点数
mem_usage = Value('d', 0.0)

# 启动生产者进程
producer = Process(target=stats_producer, args=(cpu_usage, mem_usage))
producer.daemon = True
producer.start()

tools = 'pan'

@linear()
def update(step):
    # 直接读取共享内存里的最新值
    cpu = cpu_usage.value
    mem = mem_usage.value
    ds1.data['x'].append(step)
    ds1.data['y'].append(cpu)
    ds2.data['x'].append(step)
    ds2.data['y'].append(mem)
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)

# 后面的图表初始化代码和之前一致...

对比一下几种方案

  • 集成拉取逻辑:最简单,无额外开销,适合拉取逻辑不独立的场景。
  • 队列IPC:灵活,支持复杂数据结构,适合拉取进程独立运行的情况。
  • 共享内存:性能最高,适合高频小数据传递,缺点是只能存简单类型。

而你一开始想到的文件读写方案,不仅有IO性能开销,还需要处理文件锁定、读写同步的问题,确实不如上面这几种方案靠谱。

内容的提问来源于stack exchange,提问作者Mr. Fegur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:05:07