包含关键字 typecho 的文章

作者:辰泉

提示:本文是 AgentRun Browser Sandbox 快速上手实践指南的姊妹篇,专注于高级集成方案、生产环境的最佳实践、性能优化和部署策略。如果您还没有完成基础学习,请先阅读《快速上手:LangChain + AgentRun 浏览器沙箱极简集成指南》

前言

在完成了 Browser Sandbox 的基础集成之后,本文将介绍高级集成方案(如 BrowserUse 框架)以及生产环境部署需要考虑的因素:如何管理 Sandbox 生命周期?如何优化性能和成本?如何保证系统的安全性和可观测性?本文将为您提供全面的高级应用和生产环境最佳实践指南。

基于 BrowserUse 集成 Browser Sandbox

image

效果截图

BrowserUse 是一个专门为 AI Agent 设计的浏览器自动化框架,支持视觉理解和智能决策。通过 AgentRun Browser Sandbox,您可以让 BrowserUse 在云端运行,享受 Serverless 架构的优势。

BrowserUse 架构概览

下图展示了 BrowserUse 与 Browser Sandbox 的集成架构:

image

架构特点:

  1. 智能决策循环: Agent 通过 LLM 分析页面截图,基于视觉理解生成操作指令,执行操作后继续循环,直到任务完成
  2. 无头浏览器控制: 通过 CDP 协议远程控制云端浏览器,Playwright 作为底层驱动,所有操作在云端执行
  3. 实时可视化: VNC 提供实时画面监控,方便调试和验证 Agent 行为

快速开始

安装依赖

pip install browser-use python-dotenv agentrun-sdk[playwright,server]

主要依赖说明:

  • browser-use:BrowserUse 核心库,支持多模态 LLM
  • agentrun-sdk[playwright,server]:AgentRun SDK,用于创建 Sandbox
  • python-dotenv:环境变量管理

配置环境变量

创建 .env 文件:

# DashScope API Key(用于 Qwen 模型)
DASHSCOPE_API_KEY=sk-your-dashscope-api-key
# AgentRun 认证信息
AGENTRUN_ACCOUNT_ID=your-account-id
ALIBABA_CLOUD_ACCESS_KEY_ID=your-access-key-id
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-access-key-secret
# Browser Sandbox 模板名称
BROWSER_TEMPLATE_NAME=sandbox-browser-demo

创建 Sandbox 并使用 BrowserUse

import asyncio
import os
from agentrun.sandbox import Sandbox, TemplateType
from browser_use import Agent, BrowserSession, ChatOpenAI
from browser_use.browser import BrowserProfile
from dotenv import load_dotenv
load_dotenv()
async def main():
    # 创建 Browser Sandbox
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    # 配置 Qwen 多模态模型
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    # 创建浏览器会话
    browser_session = BrowserSession(
        cdp_url=sandbox.get_cdp_url(),
        browser_profile=BrowserProfile(
            headless=False,
            timeout=3000000,
            keep_alive=True
        )
    )
    # 创建 Agent 并执行任务
    agent = Agent(
        task="访问阿里云官网并总结主要产品分类",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result = await agent.run()
    print(f"任务结果: {result.final_result()}")
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
if __name__ == "__main__":
    asyncio.run(main())

BrowserUse 高级配置

自定义浏览器行为

browser_profile = BrowserProfile(
    timeout=3000000,             # 超时时间(毫秒)
    keep_alive=True,             # 保持会话活跃
)

多步骤任务编排

async def complex_task():
    """复杂的多步骤任务"""
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    browser_session = BrowserSession(
        cdp_url=sandbox.cdp_url,
        browser_profile=BrowserProfile(keep_alive=True)
    )
    # 任务 1:信息收集
    agent1 = Agent(
        task="访问阿里云官网,收集产品分类信息",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result1 = await agent1.run()
    # 任务 2:基于第一步结果继续操作
    agent2 = Agent(
        task=f"基于以下信息:{result1.final_result()},访问每个产品分类并提取关键特性",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result2 = await agent2.run()
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
    return result2.final_result()

集成 VNC 实时监控

import webbrowser
import urllib.parse
async def run_with_vnc_monitoring():
    """运行 BrowserUse 并启用 VNC 监控"""
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    # 获取 VNC URL 并打开查看器
    vnc_url = sandbox.get_vnc_url(),
    if vnc_url:
        # 修复 VNC URL 路径
        if vnc_url.endswith('/vnc'):
            vnc_url = vnc_url[:-4] + '/ws/livestream'
        # 在浏览器中打开 VNC 查看器
        encoded_url = urllib.parse.quote(vnc_url, safe='')
        viewer_url = f"file://path/to/vnc-viewer.html?url={encoded_url}"
        webbrowser.open(viewer_url)
        print(f"VNC 查看器已打开,可实时监控浏览器操作")
    # 创建并运行 Agent
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    browser_session = BrowserSession(
        cdp_url=sandbox.get_cdp_url(),
        browser_profile=BrowserProfile(headless=False, keep_alive=True)
    )
    agent = Agent(
        task="访问淘宝首页并搜索商品",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result = await agent.run()
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
    return result.final_result()

BrowserUse 最佳实践

  1. 启用视觉理解: 对于复杂页面,使用 use_vision=True 让 LLM 分析页面截图
  2. 保持会话活跃: 使用 keep_alive=True 避免频繁重建连接
  3. 合理设置超时: 根据任务复杂度调整 timeout 参数
  4. 复用 BrowserSession: 对于多步骤任务,复用同一个 BrowserSession 提高效率
  5. 结合 VNC 调试: 开发阶段启用 VNC 实时查看 Agent 行为

获取完整示例代码

本文中的所有示例代码都可以在以下仓库中找到:

# 克隆示例代码仓库
git clone https://github.com/devsapp/agentrun-sandbox-demos.git
# 进入项目目录
cd agentrun-browseruse-wth-sandbox-demo
# 安装依赖(注意需要安装 server 扩展)
pip install -r requirements.txt

配置环境变量

# 复制环境变量模板
cp env.example .env
# 编辑 .env 文件,填入您的配置信息
# 必需配置项:
# - DASHSCOPE_API_KEY: DashScope API Key(用于 Qwen 模型)
# - AGENTRUN_ACCOUNT_ID: AgentRun 账号 ID
# - ALIBABA_CLOUD_ACCESS_KEY_ID: 阿里云访问密钥 ID
# - ALIBABA_CLOUD_ACCESS_KEY_SECRET: 阿里云访问密钥 Secret
# - BROWSER_TEMPLATE_NAME: Browser Sandbox 模板名称

运行示例(两步运行设计)

本项目采用服务器-客户端的架构设计,需要分两步运行:

第一步:启动 VNC 查看器服务

# 在终端 1 中启动 VNC Web 服务器
python main.py
# 服务启动后会显示:
# VNC 查看器服务已启动: http://localhost:8000
# 访问 http://localhost:8000 可以实时查看浏览器操作

main.py 的作用:

  • 启动本地 Web 服务器,提供 VNC 实时查看界面
  • 提供 WebSocket 代理,连接 AgentRun Sandbox 的 VNC 服务
  • 允许您在浏览器中实时监控 Agent 的操作过程

第二步:运行 BrowserUse 示例

# 在终端 2 中运行示例代码
python examples/01_browseruse_basic.py
# 运行高级示例
python examples/02_browseruse_advanced.py

为什么需要两步运行?

  1. 实时监控: main.py 提供 VNC 查看器,可以实时看到 Agent 在浏览器中的操作
  2. 调试友好: 通过可视化界面,更容易理解 Agent 的决策过程和行为
  3. 服务解耦: VNC 服务和业务逻辑分离,可以同时运行多个示例而共用同一个查看器

运行流程图:

image

仓库内容包括:

  • main.py:VNC Web 服务器,用于实时监控
  • examples/01_browseruse_basic.py:基础集成示例
  • examples/02_browseruse_advanced.py:高级配置示例
  • examples/sandbox_manager.py:Sandbox 生命周期管理
  • vncviewer/:VNC 查看器前端和后端代码
  • 完整的环境配置和最佳实践代码

Sandbox 生命周期管理最佳实践

三种管理模式

根据不同的应用场景,我们推荐三种 Sandbox 管理模式:

image

方案对比:

image

单例模式实现

适合开发调试和多轮对话场景:

class SandboxManager:
    """单例模式 Sandbox 管理器"""
    _instance = None
    _sandbox = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    def get_or_create(self):
        """获取或创建 Sandbox"""
        if self._sandbox is None:
            self._sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=3000
            )
        return self._sandbox
    def destroy(self):
        """销毁 Sandbox"""
        if self._sandbox:
            self._sandbox.delete()
            self._sandbox = None
# 使用
manager = SandboxManager()
sandbox = manager.get_or_create()  # 首次创建
sandbox = manager.get_or_create()  # 复用现有实例

连接池模式实现

适合高并发生产环境:

from queue import Queue
from threading import Lock
class SandboxPool:
    """Sandbox 连接池"""
    def __init__(self, pool_size=5, max_idle_time=300):
        self.pool_size = pool_size
        self.max_idle_time = max_idle_time
        self.pool = Queue(maxsize=pool_size)
        self.lock = Lock()
        self._initialize_pool()
    def _initialize_pool(self):
        """初始化连接池"""
        for _ in range(self.pool_size):
            sandbox = self._create_sandbox()
            self.pool.put(sandbox)
    def _create_sandbox(self):
        """创建 Sandbox 实例"""
        return Sandbox.create(
            template_type=TemplateType.BROWSER,
            template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
            sandbox_idle_timeout_seconds=self.max_idle_time
        )
    def acquire(self, timeout=30):
        """获取 Sandbox 实例"""
        try:
            sandbox = self.pool.get(timeout=timeout)
            if not self._is_alive(sandbox):
                sandbox = self._create_sandbox()
            return sandbox
        except:
            raise RuntimeError("获取 Sandbox 超时")
    def release(self, sandbox):
        """归还 Sandbox 实例"""
        if self._is_alive(sandbox):
            self.pool.put(sandbox)
        else:
            new_sandbox = self._create_sandbox()
            self.pool.put(new_sandbox)
    def _is_alive(self, sandbox):
        """检查 Sandbox 是否存活"""
        try:
            return hasattr(sandbox, 'sandbox_id')
        except:
            return False
# 使用
pool = SandboxPool(pool_size=5)
sandbox = pool.acquire()
try:
    # 使用 sandbox 执行任务
    pass
finally:
    pool.release(sandbox)

会话状态管理

支持多用户多会话场景:

import time
class SessionManager:
    """会话状态管理"""
    def __init__(self):
        self.sessions = {}  # session_id -> sandbox
    def create_session(self, session_id: str):
        """创建会话"""
        if session_id not in self.sessions:
            sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=1800
            )
            self.sessions[session_id] = {
                'sandbox': sandbox,
                'created_at': time.time(),
                'last_used': time.time()
            }
        return self.sessions[session_id]['sandbox']
    def get_session(self, session_id: str):
        """获取会话"""
        if session_id in self.sessions:
            session = self.sessions[session_id]
            session['last_used'] = time.time()
            return session['sandbox']
        return None
    def cleanup_expired_sessions(self, max_idle_time=1800):
        """清理过期会话"""
        current_time = time.time()
        expired_sessions = []
        for session_id, session in self.sessions.items():
            if current_time - session['last_used'] > max_idle_time:
                expired_sessions.append(session_id)
        for session_id in expired_sessions:
            self.destroy_session(session_id)
    def destroy_session(self, session_id: str):
        """销毁会话"""
        if session_id in self.sessions:
            self.sessions[session_id]['sandbox'].delete()
            del self.sessions[session_id]

性能优化

超时时间配置

合理设置超时时间是平衡性能和成本的关键:

# 开发环境(调试用)
sandbox = Sandbox.create(
    template_name="dev-template",
    sandbox_idle_timeout_seconds=7200  # 2 小时
)
# 生产环境(单次任务)
sandbox = Sandbox.create(
    template_name="prod-template",
    sandbox_idle_timeout_seconds=300  # 5 分钟
)
# 长时间任务
sandbox = Sandbox.create(
    template_name="long-task-template",
    sandbox_idle_timeout_seconds=10800  # 3 小时
)

超时策略推荐:

image

Sandbox 复用策略

class SmartSandboxManager:
    """智能 Sandbox 复用管理器"""
    def __init__(self):
        self.sandboxes = {}  # key -> sandbox
        self.usage_count = {}  # key -> count
    def get_sandbox(self, user_id: str, session_id: str):
        """获取或创建 Sandbox(支持复用)"""
        key = f"{user_id}:{session_id}"
        if key not in self.sandboxes:
            self.sandboxes[key] = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=1800
            )
            self.usage_count[key] = 0
        self.usage_count[key] += 1
        return self.sandboxes[key]
    def should_recreate(self, key: str, max_reuse=50):
        """判断是否需要重建(防止状态累积)"""
        return self.usage_count.get(key, 0) >= max_reuse
    def recreate_if_needed(self, key: str):
        """按需重建 Sandbox"""
        if self.should_recreate(key):
            if key in self.sandboxes:
                self.sandboxes[key].delete()
                del self.sandboxes[key]
                self.usage_count[key] = 0

错误处理和重试机制

使用 tenacity 库实现智能重试:

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
class SandboxError(Exception):
    """Sandbox 操作异常"""
    pass
@retry(
    retry=retry_if_exception_type(SandboxError),
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10)
)
def execute_with_retry(sandbox, operation):
    """带重试的操作执行"""
    try:
        return operation(sandbox)
    except ConnectionError:
        raise SandboxError("连接失败")
    except TimeoutError:
        raise SandboxError("操作超时")
    except Exception as e:
        print(f"操作失败: {e}")
        raise SandboxError(f"操作失败: {e}")
# 使用示例
def navigate_page(sandbox):
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
        page = browser.contexts[0].pages[0]
        page.goto("https://example.com", timeout=30000)
        return page.title()
result = execute_with_retry(sandbox, navigate_page)

安全性最佳实践

环境变量保护

import os
from dotenv import load_dotenv
load_dotenv()
# 验证必需的环境变量
required_vars = ["DASHSCOPE_API_KEY", "AGENTRUN_ACCOUNT_ID"]
missing_vars = [var for var in required_vars if not os.getenv(var)]
if missing_vars:
    raise ValueError(f"缺少必需的环境变量: {', '.join(missing_vars)}")
# 敏感信息不要硬编码
API_KEY = os.getenv("DASHSCOPE_API_KEY")
ACCESS_KEY_ID = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
ACCESS_KEY_SECRET = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")

URL 白名单

ALLOWED_DOMAINS = [
    'example.com',
    'aliyun.com',
    'alibaba.com'
]
def is_url_allowed(url: str) -> bool:
    """检查 URL 是否在白名单中"""
    from urllib.parse import urlparse
    domain = urlparse(url).netloc
    return any(allowed in domain for allowed in ALLOWED_DOMAINS)
def safe_navigate(page, url: str):
    """安全导航"""
    if not is_url_allowed(url):
        raise ValueError(f"URL 不在白名单中: {url}")
    page.goto(url)

日志脱敏

import re
def sanitize_log(log_text: str) -> str:
    """日志脱敏"""
    # 脱敏 API Key
    log_text = re.sub(r'sk-[a-zA-Z0-9]{20,}', 'sk-***', log_text)
    # 脱敏 Access Key
    log_text = re.sub(r'LTAI[a-zA-Z0-9]{12,}', 'LTAI***', log_text)
    # 脱敏密码
    log_text = re.sub(r'password["\s:=]+[^"\s,}]+', 'password: ***', log_text, flags=re.IGNORECASE)
    return log_text
# 使用
print(sanitize_log(f"使用 API Key: {API_KEY}"))

可观测性与监控

日志记录最佳实践

import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(f'sandbox_{datetime.now().strftime("%Y%m%d")}.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)
class MonitoredSandboxManager:
    """带监控的 Sandbox 管理器"""
    def create_sandbox(self, **kwargs):
        """创建 Sandbox(带日志)"""
        start_time = time.time()
        logger.info(f"开始创建 Sandbox: {kwargs}")
        try:
            sandbox = Sandbox.create(**kwargs)
            duration = time.time() - start_time
            logger.info(f"Sandbox 创建成功: {sandbox.sandbox_id}, 耗时: {duration:.2f}s")
            return sandbox
        except Exception as e:
            duration = time.time() - start_time
            logger.error(f"Sandbox 创建失败: {e}, 耗时: {duration:.2f}s")
            raise
    def execute_task(self, sandbox, task_name: str, operation):
        """执行任务(带日志)"""
        start_time = time.time()
        logger.info(f"开始执行任务: {task_name}, Sandbox: {sandbox.sandbox_id}")
        try:
            result = operation(sandbox)
            duration = time.time() - start_time
            logger.info(f"任务执行成功: {task_name}, 耗时: {duration:.2f}s")
            return result
        except Exception as e:
            duration = time.time() - start_time
            logger.error(f"任务执行失败: {task_name}, 错误: {e}, 耗时: {duration:.2f}s")
            raise

指标收集

from dataclasses import dataclass
from typing import Dict, List
import json
@dataclass
class SandboxMetrics:
    """Sandbox 指标"""
    sandbox_id: str
    create_time: float
    destroy_time: float = None
    total_requests: int = 0
    failed_requests: int = 0
    total_duration: float = 0.0
class MetricsCollector:
    """指标收集器"""
    def __init__(self):
        self.metrics: Dict[str, SandboxMetrics] = {}
    def record_creation(self, sandbox_id: str):
        """记录创建"""
        self.metrics[sandbox_id] = SandboxMetrics(
            sandbox_id=sandbox_id,
            create_time=time.time()
        )
    def record_request(self, sandbox_id: str, duration: float, success: bool):
        """记录请求"""
        if sandbox_id in self.metrics:
            metric = self.metrics[sandbox_id]
            metric.total_requests += 1
            metric.total_duration += duration
            if not success:
                metric.failed_requests += 1
    def record_destruction(self, sandbox_id: str):
        """记录销毁"""
        if sandbox_id in self.metrics:
            self.metrics[sandbox_id].destroy_time = time.time()
    def export_metrics(self, filepath: str):
        """导出指标"""
        metrics_data = [
            {
                'sandbox_id': m.sandbox_id,
                'create_time': m.create_time,
                'destroy_time': m.destroy_time,
                'total_requests': m.total_requests,
                'failed_requests': m.failed_requests,
                'success_rate': (m.total_requests - m.failed_requests) / m.total_requests if m.total_requests > 0 else 0,
                'avg_duration': m.total_duration / m.total_requests if m.total_requests > 0 else 0,
                'lifetime': m.destroy_time - m.create_time if m.destroy_time else time.time() - m.create_time
            }
            for m in self.metrics.values()
        ]
        with open(filepath, 'w') as f:
            json.dump(metrics_data, f, indent=2)
# 使用
collector = MetricsCollector()
collector.record_creation(sandbox.sandbox_id)
# ... 执行任务 ...
collector.export_metrics('metrics.json')

成本优化

按需创建与销毁

class CostOptimizedManager:
    """成本优化的管理器"""
    def __init__(self, idle_threshold=300):
        self.idle_threshold = idle_threshold
        self.sandboxes = {}
        self.last_used = {}
    def get_sandbox(self, key: str):
        """获取 Sandbox(懒加载)"""
        if key not in self.sandboxes:
            self.sandboxes[key] = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=self.idle_threshold
            )
        self.last_used[key] = time.time()
        return self.sandboxes[key]
    def cleanup_idle(self):
        """清理闲置 Sandbox"""
        current_time = time.time()
        to_remove = []
        for key, last_time in self.last_used.items():
            if current_time - last_time > self.idle_threshold:
                to_remove.append(key)
        for key in to_remove:
            if key in self.sandboxes:
                self.sandboxes[key].delete()
                del self.sandboxes[key]
                del self.last_used[key]
                logger.info(f"清理闲置 Sandbox: {key}")

批量任务处理

async def batch_process_tasks(tasks: List[str], pool_size: int = 5):
    """批量处理任务(复用 Sandbox)"""
    pool = SandboxPool(pool_size=pool_size)
    results = []
    for task in tasks:
        sandbox = pool.acquire()
        try:
            # 处理任务
            result = await process_task(sandbox, task)
            results.append(result)
        finally:
            pool.release(sandbox)
    return results

生产环境部署

环境配置

开发环境 (.env.dev):

# 开发环境配置
BROWSER_TEMPLATE_NAME=dev-browser-template
SANDBOX_IDLE_TIMEOUT=7200
POOL_SIZE=2
LOG_LEVEL=DEBUG

生产环境 (.env.prod):

# 生产环境配置
BROWSER_TEMPLATE_NAME=prod-browser-template
SANDBOX_IDLE_TIMEOUT=300
POOL_SIZE=10
LOG_LEVEL=INFO
ENABLE_METRICS=true
METRICS_EXPORT_INTERVAL=300

高可用架构

image

健康检查

from flask import Flask, jsonify
app = Flask(__name__)
manager = SandboxManager()
@app.route('/health')
def health_check():
    """健康检查端点"""
    try:
        # 检查 Sandbox 是否可用
        sandbox = manager.get_or_create()
        # 简单的健康检查
        is_healthy = hasattr(sandbox, 'sandbox_id')
        if is_healthy:
            return jsonify({
                'status': 'healthy',
                'sandbox_id': sandbox.sandbox_id,
                'timestamp': time.time()
            }), 200
        else:
            return jsonify({
                'status': 'unhealthy',
                'error': 'Sandbox not available'
            }), 503
    except Exception as e:
        return jsonify({
            'status': 'unhealthy',
            'error': str(e)
        }), 503
@app.route('/metrics')
def metrics():
    """指标端点"""
    collector = MetricsCollector()
    # 返回当前指标
    return jsonify({
        'total_sandboxes': len(collector.metrics),
        'timestamp': time.time()
    })

故障排查与常见问题

连接问题

问题:无法连接到 Sandbox

排查步骤

def diagnose_connection(sandbox):
    """诊断连接问题"""
    print(f"1. 检查 Sandbox ID: {sandbox.sandbox_id}")
    print(f"2. 检查 CDP URL: {sandbox.cdp_url}")
    # 测试 CDP 连接
    try:
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
            print("✓ CDP 连接成功")
            browser.close()
    except Exception as e:
        print(f"✗ CDP 连接失败: {e}")
    # 测试 VNC 连接
    print(f"3. VNC URL: {sandbox.vnc_url}")
    print("提示: 可以在浏览器中打开 VNC URL 测试连接")

超时问题

问题:任务执行超时

解决方案

def handle_timeout(sandbox, operation, max_retries=3):
    """处理超时(带重试)"""
    for attempt in range(max_retries):
        try:
            return operation(sandbox, timeout=30000)
        except TimeoutError:
            logger.warning(f"任务超时(尝试 {attempt + 1}/{max_retries})")
            if attempt == max_retries - 1:
                # 最后一次尝试失败,重建 Sandbox
                logger.error("多次超时,重建 Sandbox")
                sandbox.delete()
                sandbox = Sandbox.create(
                    template_type=TemplateType.BROWSER,
                    template_name=os.getenv("BROWSER_TEMPLATE_NAME")
                )
                return operation(sandbox, timeout=60000)

性能问题

问题:响应速度慢

优化建议

  1. 使用连接池:预先创建多个 Sandbox 实例
  2. 启用 keep_alive:保持浏览器会话,避免重复建立连接
  3. 合理设置超时:根据任务复杂度调整超时时间
  4. 并发控制:限制并发请求数,避免资源竞争
# 性能优化配置示例
browser_session = BrowserSession(
    cdp_url=sandbox.cdp_url,
    browser_profile=BrowserProfile(
        timeout=30000,          # 30秒超时
        keep_alive=True,        # 保持连接
        disable_security=False  # 保持安全检查
    )
)

错误码参考

image

总结

通过本指南,您已经掌握了:

  1. BrowserUse 集成: 如何使用 BrowserUse 框架实现智能浏览器自动化
  2. 生命周期管理: 三种 Sandbox 管理模式的选择和实现
  3. 性能优化: 超时配置、复用策略、错误重试机制
  4. 安全实践: 环境变量保护、URL 白名单、日志脱敏
  5. 可观测性: 日志记录、指标收集、监控告警
  6. 成本优化: 按需创建、闲置清理、批量处理
  7. 生产部署: 高可用架构、健康检查、故障排查

关注「阿里云云原生」公众号,后台回复:BrowserUse

获取参考代码

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

  1. 快速创建:访问控制台(https://functionai.console.aliyun.com/cn-hangzhou/agent/explore),60 秒创建你的第一个 Agent
  2. 深度定制:当需要更复杂功能时,一键转换为高代码
  3. 持续演进:利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号: 134570017218

快速了解函数计算 AgentRun:

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60% 。 

让开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施,让 Agentic AI 真正进入企业生产环境。

推荐阅读:

很多团队在业务发展到一定阶段后,都会认真评估一次:
用户行为分析系统,是继续用现成产品,还是自己搭一套?

实际上,当企业需要埋点分析时,往往已经没有太多时间成本可投入
业务方希望尽快看到数据结果,管理层关注投入产出比,而完全从零自建埋点系统,周期长、风险高、不可控。
因此,基于成熟开源方案快速上线,再按需求自己二开,是目前更常见、也更可控的一种选择。

这篇文章不讨论“埋点的重要性”,只做一件事:
以自建埋点分析系统为参照,给出一个成本参考,并对比基于 ClkLog 开源方案的实际投入。

完全自建一套埋点分析系统成本通常在几十万,且建设周期长、不可控因素多。
基于ClkLog开源方案搭建首期成本可控制在几万最快一周完成部署集成,可以快速交付使用,并具备持续扩展的能力。

一、自建埋点分析系统,通常需要哪些模块?
很多团队低估了“自建”的工作量,下面只列最基础、不可回避的部分
1.数据采集层(SDK + 埋点规范)
这个阶段往往被低估,但实际上 SDK 会长期伴随业务演进,需要持续维护。
2.数据接入与处理层
核心目标是稳定接住数据:常见技术栈包括接入服务 + Kafka / MQ。
3.数据存储层
通常会选择 ClickHouse / Doris / Druid 这类分析型数据库,同时需要设计分区、冷热数据策略。
4.复杂分析计算
这是自建中最耗精力的部分,很多团队会发现:统计不难,难的是保证分析口径正确且性能可用。
5.管理后台与可视化
这部分前端和交互成本往往被严重低估。
6.运维与长期维护
系统上线只是开始,后续还包括各项调优、异常排查等运维工作。

二、为什么很多团队不会选择「完全自建」?
问题不在“能不能做”,而在是否划算
●早期业务验证阶段,数据系统很难直接创造业务价值
●自建系统容错成本高,试错周期长
因此,越来越多团队会选择:
在成熟的开源埋点分析系统基础上建设,而不是从零开始。

三、ClkLog开源方案能解决什么问题?
ClkLog提供了一套可直接落地的开源埋点分析方案,不依赖第三方SaaS服务。全面覆盖了埋点系统中最重、最复杂的核心能力:

1.数据采集层
支持神策SDK与自研鸿蒙SDK
2.数据接受层
进行日志数据接收与存储
3.数据处理层
进行数据处理、归档等服务
4.数据存储层
使用clickhouse进行大量数据查询
5.数据可视化
内置多种成熟分析模型,开箱即用

企业无需从零搭建底层能力,只需要围绕自身业务场景完成部署、运维和少量定制,即可形成一套可用的自有埋点分析系统。

四、基于 ClkLog,企业实际需要投入哪些成本?
1. 基础运行环境(参考)
以 ClkLog 社区版为例,在 1万日活应用规模下,采用Docker方式部署,单台服务器即可满足基础使用需求。
推荐配置参考:8核CPU;32GB内存
在常见的云厂商环境中,约1-2万/年,即可覆盖服务器、云盘、流量、备份等成本。

2. 软件部署与集成
●获取ClkLog代码(Github/Gitee)
●自行部署ClkLog服务(docker部署最快10分钟完成)
●接入埋点SDK(兼容web/小程序/iOS/安卓等)
●常规运维数据库和服务
整体实施周期短,最快一天即可完成部署并交付使用。

3. 业务层面的工作
●埋点规范梳理
●事件与指标定义
●少量业务定制
ClkLog已经内置十几种行业标准分析模型,可供业务直接开箱使用。若还有更多定制业务需要分析,可以通过自定义事件或二次开发来实现,与完全自建相比,省去的是部门团队沟通、大量底层系统设计与长期维护成本。

五、写在最后
对于大多数团队来说,先把系统跑起来、用起来、产生价值,比一开始追求完美更重要。
如果团队希望:
●完全掌控数据
●又不想长期投入基础设施研发
●把精力更多放在业务分析而不是系统本身
那么,基于成熟开源方案搭建自己的埋点分析系统,是一个性价比较高、风险更可控的选择


在企业报表制作中,数据汇总(如行小计、列总计、分组合计)是核心需求之一。传统报表工具的汇总功能往往存在局限:要么只能固定在表格末尾显示总计,要么无法灵活适配复杂的分组布局,导致报表可读性差、分析效率低,难以满足多样化的业务展示需求。

为解决这一痛点,SpreadJS V19.0 报表插件重磅升级「设计器容器支持合计(行和列)」功能,允许开发者在 ReportSheet 容器中灵活添加行、列汇总数据,无需复杂配置即可实现多维度数据聚合,让报表数据更清晰、分析更高效。

在这里插入图片描述

一、核心功能亮点:打破汇总布局限制

SpreadJS V19.0 的设计器容器合计功能,以“灵活适配、高效聚合”为核心,带来三大核心亮点:

1. 多维度汇总支持,覆盖全场景需求

支持在容器中自由添加行汇总、列汇总或全维度汇总,满足不同报表场景:

  • 行汇总:在分组数据下方添加小计、累计值,清晰展示局部数据聚合结果;
  • 列汇总:在数据列右侧添加总计、平均值,直观呈现跨维度数据统计;
  • 全维度汇总:同时启用行、列汇总,构建立体式数据统计视图,适配复杂分析场景。

2. 灵活显示模式,适配自定义布局

支持根据业务需求自定义汇总的展示样式与位置,无需受固定模板限制:

  • 可选择汇总数据的显示位置(如分组内底部、表格末尾、列右侧);
  • 支持与现有报表布局无缝融合,适配主从报表、分组报表等复杂结构;
  • 汇总数据样式可自定义(字体、颜色、边框),与报表整体风格保持一致。

3. 非侵入式设计,不影响原始数据

汇总数据的生成基于原始数据源计算,不会修改或污染基础数据:

  • 自动同步原始数据变化,当报表数据源更新时,汇总结果实时刷新;
  • 汇总行/列独立于数据区,不影响筛选、排序等基础操作;
  • 支持一键隐藏/显示汇总数据,灵活适配不同阅读场景。

二、典型应用场景:让数据汇总更贴合业务

该特性适用于各类需要数据聚合的报表场景,尤其匹配以下业务需求:

  • 区域销售汇总报表:按省份、城市分组展示销售数据,在每组下方添加行小计,右侧添加全国列总计,快速对比区域业绩与整体表现;
  • 部门财务费用报表:按部门、费用类型展示支出数据,通过列汇总计算各费用类型总支出,行汇总展示部门总费用,清晰呈现成本结构;
  • 库存分析报表:按仓库、商品类别展示库存数据,行汇总计算单个仓库库存总量,列汇总统计同类商品总库存,助力库存优化决策;
  • 项目进度汇总报表:按项目、任务阶段展示进度数据,行汇总计算项目整体完成率,列汇总统计各阶段平均进度,直观把控项目进展。

三、技术优势:低代码配置,高效集成

作为 SpreadJS V19.0 报表插件的核心增强特性,设计器容器合计功能延续了产品“低代码、高兼容”的优势:

  • 可视化配置:通过 SpreadJS Designer 设计器即可完成汇总设置,无需编写复杂代码,开发者上手成本低;
  • 高兼容性:无缝兼容 ReportSheet 现有功能(如分组、筛选、分页),不影响已有报表结构;
  • 性能优化:汇总计算基于 SpreadJS 高效的计算引擎,大数据量场景下仍能保持快速响应;
  • 灵活扩展:支持通过 API 自定义汇总计算逻辑(如加权平均、环比增长),满足特殊业务需求。

四、使用注意事项:避坑指南

为确保功能正常使用,需注意以下几点:

  1. 若 List/Summary Groups 中未包含任何表字段,Totals 选项将被禁用,无法添加汇总;
  2. 仅当 Row Groups 或 Column Groups 中包含表字段时,对应的行/列汇总设置才会生效;
  3. 若在容器中手动添加了静态行或列,自动汇总功能将被禁用,需删除静态元素后重新启用;
  4. 当 Summary/List Groups 中包含列表类型字段时:

    1. 仅 Row Groups 有表字段:Row Groups 和 Summary/List Groups 需均为垂直展开;
    2. 仅 Column Groups 有表字段:Column Groups 和 Summary/List Groups 需均为水平展开。

结语

SpreadJS V19.0 推出的“设计器容器支持合计(行和列)”特性,彻底打破了传统报表汇总功能的布局限制,通过灵活的多维度汇总、可视化配置、高效的性能表现,让数据聚合更贴合业务需求,大幅提升报表的可读性与分析效率。

无论是简单的数值统计,还是复杂的分组聚合,该特性都能帮助开发者快速构建专业的汇总报表,无需投入大量开发成本。SpreadJS V19.0 即将正式发布,欢迎持续关注,届时可通过官网 Demo 体验设计器容器合计功能的强大能力,让你的报表数据更具价值!

扩展链接

可嵌入您系统的在线Excel

VMware ESXi 8.0U3h 发布 - 领先的裸机 Hypervisor

同步发布 Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur/IEIT SYSTEMS (浪潮)、H3C (新华三)、Cisco (思科)、Fujitsu (富士通)、Hitachi (日立)、NEC (日电)、Huawei (华为)、xFusion (超聚变) OEM 定制版

请访问原文链接:https://sysin.org/blog/vmware-esxi-8-u3/ 查看最新版。原创作品,转载请保留出处。

作者主页:sysin.org


ESXi 8.0U3h 已于 2025-12-16 发布,今天单独一篇来看一下新增功能。

VMware ESXi - 领先的裸机 Hypervisor

ESXi

产品简介

VMware ESXi:专门构建的裸机 Hypervisor

了解可直接安装到您的物理服务器的、可靠的裸机 Hypervisor。通过直接访问并控制底层资源,VMware ESXi 可有效地对硬件进行分区,以便整合应用并降低成本。它是业界领先的高效体系架构 (sysin),在可靠性、性能和支持方面树立了行业标杆。

新增功能

VMware ESXi 8.0 Update 3h | 15 DEC 2025 | ISO Build 25067014

vCenter 机器 SSL 证书和 ESXi SSL 证书的自动续订

vCenter 8.0 Update 3h 开始,由 VMware Certificate Authority(VMCA)vCenter 以及 8.0 Update 3 及更高版本的 ESXi 签发的 SSL 证书,会在接近到期日期时自动续订。

  • vCenter 机器 SSL 证书 距离到期不足 5 天 时,证书会自动延长 2 年
  • 对于支持 无中断证书续订 的 ESXi 主机,当 SSL 证书 距离到期不足 10 天 时,证书会自动延长 5 年

如果 VMCA 证书模式 设置为 custom,自动续订功能将不会生效。要启用该功能,需要将证书模式更改为 vmca

此补丁包含对以下问题的修复

PR 3599476:托管在 vSAN File Services 上的文件或文件夹可能无法访问

在升级到 vSphere 8.0 Update 3e 或更高版本后,由于 I/O 提交不完整,vSAN 集群中的 vSAN File Services 共享上的文件或文件夹可能会出现可访问性问题。这会导致无效参数错误或文件写入失败,影响在升级过程中经历过状态转换的共享 (sysin)。升级后新创建的共享不受影响。

此问题已在本版本中解决。

PR 3577856:在处理 LSOM 磁盘拥塞时,重新同步时间过长

SSD 磁盘的一个内部标志问题可能会阻止组件被正确标记为缺失,从而在处理 LSOM 磁盘拥塞时导致重新同步时间过长。

此问题已在本版本中解决。

PR 3577827:vSAN 网络告警显示网络错误率超过 100%

在 vSAN 网络告警视图中,某些网络错误率值可能显示为高于 100%。

此问题已在本版本中解决。

PR 3567326:vSAN 健康告警显示加密密钥不一致

在从启用了 vSAN OSA 加密并使用 Native Key Provider 的 vSAN 7.0 Update 3 升级后 (sysin),vSAN 健康告警可能会显示加密密钥不一致。

此问题已在本版本中解决。

PR 3545007:vSAN 原生跟踪对象中,不同 ESXi 主机上的 vSAN 跟踪保留不均衡

清理逻辑会导致 vSAN 原生跟踪对象中,不同 ESXi 主机之间的 vSAN 跟踪保留不均衡。

此问题已在本版本中解决。

PR 3451034:在收集 CPU 使用率统计信息期间,由于竞争条件,ESXi 主机可能出现紫屏(PSOD)

在收集 CPU 使用率统计信息时,VMkernel 可能遇到竞争条件,导致出现带有 #PF Exception 14 error 的紫色诊断屏幕。在堆栈跟踪中,可以看到与 CpuMetricsLoadHistorySnapshotStats 相关的错误。

此问题已在本版本中解决。

PR 3562682:ESXi 主机可能会间歇性地从 Active Directory 域或 vCenter 断开连接

在 Active Directory 操作期间,或在 ESXi 主机上启用智能卡认证时,Likewise 组件可能发生内存泄漏。结果是 Likewise 进程可能耗尽内存,导致 ESXi 主机间歇性地从 Active Directory 域或 vCenter 断开连接。在 /var/log/vmkernel.log 文件中 (sysin),可以看到类似以下的信息:

yyyy-mm-dd In(182) vmkernel: cpu72:2110465)uw.2110464 (44739) requires 1024 KB, asked 1024 KB from likewise (792) which has 93112 KB occupied and 72 KB available.
yyyy-mm-dd In(182) vmkernel: cpu72:2110465)Admission failure in path: host/vim/vmvisor/likewise:lwsmd.2110464:uw.2110464

在 hostd-probe.log 文件中,可以看到类似以下的消息:hostd 被检测为无响应。

此问题已在本版本中解决。

PR 3538241:由于主机上的 SSH 默认值与期望映像不匹配,ESXi 主机可能被报告为不合规

当应用使用 SSH 默认设置的 vSphere 配置文件时,某些 ESXi 主机可能被报告为不合规。这是因为 ESXi 主机不会保存 SSH 设置的默认值,从而导致 vCenter 中的期望配置文件与 ESXi 主机实际配置不匹配,进而使合规性检查失败。

此问题已在本版本中解决。

PR 3567000:第一类磁盘(FCD)任务失败并返回错误 vim.vslm.host.VStorageObjectManager.retrieveVStorageObjectMetadata: :vmodl.fault.ManagedObjectNotFound

在某些情况下,FCD 任务可能会在 vpxa 日志中失败,并显示如下错误:

vim.vslm.host.VStorageObjectManager.retrieveVStorageObjectMetadata: :vmodl.fault.ManagedObjectNotFound

此问题已在本版本中解决。

PR 3562151:当 ESXi 与 NVMe over FC 存储阵列之间的一条或多条路径丢失时,应用程序或虚拟机可能无响应

ESXi 通常对存储阵列使用多路径机制,但即使仍有可用的活动路径,在某些情况下,丢失一条或多条路径也可能导致虚拟机无响应 (sysin)。问题的原因是,一些正在进行的 NVMe 命令可能到达已失效的路径,无法完成或停止,结果这些命令会一直被阻塞,直到路径恢复,从而导致应用程序或虚拟机无响应。

此问题已在本版本中解决。

PR 3547549:如果虚拟机每个插槽的核心数超过 255,快速挂起/恢复(FSR)或迁移任务可能失败

如果虚拟机每个插槽的核心数超过 255,迁移、快速恢复或热插拔等任务会失败。在 vmware.log 中,可以看到类似以下的信息:

2024-09-04T14:33:07.488Z In(05) vmx - [msg.checkpoint.inConsistentCoresPerSocket] The suspended image contains a coresPerSocket value (0) that does not match with VM's actual coresPerSocket value (256).

此问题已在本版本中解决。

PR 3517793:在 vSAN File Service 容器故障切换后,可能会看到一个或多个虚拟机来宾文件系统磁盘空间不足的告警

在极少数情况下,当 vSAN File Service 容器故障切换到另一台 ESXi 主机时,日志文件可能仍保留在源主机上。由于这些陈旧日志未释放磁盘空间,随着时间推移可能会导致磁盘空间占用显著增加,并触发“一个或多个虚拟机来宾文件系统磁盘空间不足”的告警。该问题通常只会在 vSAN File Service 运行较长时间并且发生过多次成功故障切换后出现,并非每次故障切换都会发生。

此问题已在本版本中解决。

PR 3597422:在具有 2 个 DPU 的 ESXi 主机上升级 NSX 可能触发意外的 DPU 故障切换

在具有 2 个 DPU 的 ESXi 主机上执行 NSX 升级期间,可能会触发意外的 DPU 故障切换,从而导致 vSphere Distributed Switch(VDS)失败并阻塞 vSphere vMotion 任务,或者故障切换状态在主机重启后仍然存在 (sysin),并导致 VDS 下线。

此问题已在本版本中解决。

PR 3558631:启用集群 VMDK 时,VMkernel 线程可能在 ESXi 主机上占用 100% CPU

当启用集群 VMDK 时,VSCSISharedVdMainWorld 内核线程可能在 ESXi 主机上消耗过多的 CPU 资源,CPU 使用率可能持续保持在 100%。

此问题已在本版本中解决。

PR 3445897:在传输被分段为大量 scatter-gather 条目(SGE)的大数据包时,可能发生丢包

如果大型 TCP 数据包被拆分为超过 24 个 SGE,数据包传输可能会失败,并显示错误 “Failed to divide TSO packet into 2”。

此问题已在本版本中解决。修复后,大数据包可以被正确分段并正常传输。

PR 3570996:在列出 vSphere Virtual Volumes 数据存储内容时,vSphere Virtual Volumes 服务 vvold 可能因转储而失败

当 VASA Provider 对 queryVirtualVolumeInfo 请求返回部分响应时,vvold 可能会因查询越界而失败。

此问题已在本版本中解决。修复通过避免部分响应来防止 vvold 失败。

PR 3565927:在 ESXi 安装期间,可能无法发现 iSCSI SAN 启动 LUN

在极少数情况下,在 ESXi 安装期间,初始连接尝试可能因某些原因失败,例如 iSCSI 目标地址使用 IPv6,或者无法发现 iSCSI SAN 启动 LUN。结果是网络配置被回滚,后续尝试连接 iSCSI 目标或发现 iSCSI SAN 启动 LUN 都会失败。

此问题已在本版本中解决。

PR 3576783:当源和目标未同时通过同一控制器的活动路径时,NVMe 设备上的硬件加速克隆操作可能失败

如果 NVMe 复制命令的源设备具有活动路径,而目标设备仅通过同一控制器的备用路径连接,则目标可能会使命令失败。当源和目标设备都通过同一控制器的活动路径连接时,复制命令可以正常工作。

此问题已在本版本中解决。

PR 3588199:在某个磁盘上启用了 Changed Block Tracking(CBT)的虚拟机在迁移后可能失败或重启

当虚拟机位于 vSphere Virtual Volumes 数据存储上,并且其某个磁盘启用了 CBT 时,如果 vSphere vMotion 任务在后期阶段失败,虚拟机在迁移后可能无法运行或重启。

此问题已在本版本中解决。如果您已经遇到该问题且未升级到 ESXi 8.0 Update 3h,请在此类情况下禁用 CBT。

PR 3549572:失败的静默快照可能会损坏 vSphere Virtual Volume 或 vSAN 磁盘的磁盘链

如果对使用 vSphere Virtual Volume 或 vSAN 磁盘的虚拟机创建静默快照失败,部分或全部磁盘链可能会被损坏。虚拟机将无法被正确管理,并且可能发生数据丢失,迫使您从备份中恢复。

此问题已在本版本中解决。

PR 3583385:无法看到虚拟机网络接口的丢包统计信息

由于 VNIC 后端错误,环境中的分布式虚拟交换机统计信息可能无法收集丢包数据 (sysin)。结果是,即使通过第三方工具确认存在丢包,在 vSphere Client 或 VMware Aria Operations 中也无法看到相关数据。

此问题已在本版本中解决。修复确保由于 VNIC 后端错误导致的丢包会被纳入分布式虚拟交换机的统计信息中。

PR 3545592:与 SSH 相关的日志出现在 /var/run/log/syslog.log 中,而不是 auth.log

某些与 SSH 相关的日志可能会被记录到 /var/run/log/syslog.log,而不是通常的 /var/run/log/auth.log

此问题已在本版本中解决。

PR 3530277:NVMe 核心层中的一个罕见问题可能导致 ESXi 主机出现紫屏

当 NVMe 控制器与 ESXi 主机断开连接或主机关闭时,NVMe 核心层与 NVMe/TCP 驱动程序之间可能发生竞争条件。NVMe 核心层可能在驱动程序完成队列资源清理之前就开始清理控制器资源,结果驱动程序无法访问控制器对象,从而导致 ESXi 主机出现紫色诊断屏幕。

此问题已在本版本中解决。

PR 3585442:由于缺少图形类型,在 GPU 设备故障后 hostd 服务终止

在某些情况下,hostd 服务的图形管理器无法处理来自 GPU 设备的意外图形类型并发生故障。结果是 ESXi 主机可能会从 vCenter 断开连接。

此问题已在本版本中解决。

PR 3540480:在从 NVMe 驱动器获取 SMART 统计信息时,ESXi 主机可能出现紫屏

如果在从 NVMe 驱动器获取 SMART 统计信息时,由于坏盘或其他原因,同步命令(如 VMK_NVME_ADMIN_CMD_GET_LOG_PAGE)延迟超过 120 秒,ESXi 主机可能会出现紫色诊断屏幕。

此问题已在本版本中解决。

PR 3569856:在 IP 输入访问全局地址列表时发生的竞争条件可能导致 ESXi 主机出现紫屏

在 IP 输入访问全局地址列表时,极少数情况下可能发生竞争条件,使多个 ESXi 主机对 vCenter 无响应,并最终出现紫色诊断屏幕。

此问题已在本版本中解决。

PR 3570676:由于 TCP/IP 定时器实现中的罕见竞争条件,ESXi 主机可能出现紫屏

当 TCP/IP 定时器在已断开的连接上触发时,ESXi 主机可能会出现紫色诊断屏幕。该问题发生概率很低,因为竞争窗口非常小,并且 TCP/IP 定时器检查机制已尽量降低此类风险。

此问题已在本版本中解决。

PR 3576190:TCP/IP 栈中的竞争条件可能导致 ESXi 主机无响应并最终出现紫屏

由于 TCP/IP 栈中数据路径与从接口移除 IP 地址的过程之间存在竞争条件,某些 ESXi 主机可能会随机变得无响应,并最终出现紫色诊断屏幕。结果是,在受影响主机上运行的关键应用程序可能会中断。

此问题已在本版本中解决。

PR 3557350:复制的虚拟机在增量同步期间可能间歇性无响应

在备份操作后的复制虚拟机增量同步期间,如果来宾操作系统发出的 UNMAP 命令处理不当,可能会导致虚拟机对 ping 无响应,并需要重启才能恢复。

此问题已在本版本中解决。

PR 3538148:当 ESXi 主机具有大量存储设备时,任务管理操作(如取消)完成时间过长

如果在具有大量存储设备的 ESXi 主机上,针对某个设备并行运行多个命令 (sysin),则诸如停止该设备上所有命令之类的任务管理操作可能需要很长时间才能完成。

此问题已在本版本中解决。修复增强了在多线程排队情况下存储设备的超时处理机制。

PR 3560144:ESXi 主机上的 I/O 因错误 “Unable to map SG array on path.” 而失败

由于直接内存访问(DMA)限制,某些驱动程序可能会拆分具有较大块大小的 I/O,导致 I/O 无法取得进展并最终失败。在 vmkernel 日志中,可以看到如下错误:

vmkernel: cpu3:29408512)ScsiPath: 3787: Opcode 0x2a(0x45b9977a4040) Unable to map SG array on path vmhba2:C0:T7:L32. Status: DMA mapping could not be completed DMA Error: Can't meet SG element alignment.”

此问题已在本版本中解决。

PR 3572857:在将虚拟机迁移到启用了分布式防火墙规则的 ESXi 主机时,软件竞争条件可能导致紫屏

在 vSphere vMotion 操作期间,目标主机会恢复分布式防火墙规则。由于软件竞争条件,规则恢复过程可能被调用两次,从而导致 ESXi 主机出现紫色诊断屏幕。

此问题已在本版本中解决。

PR 3574732:ESXCLI 命令 esxcli vsan debug object 可能返回错误的 vSAN ESA 对象已用容量值

ESXCLI 命令 esxcli vsan debug object overviewesxcli vsan debug object list 可能会为 vSAN ESA 对象报告错误的已用容量值。

此问题已在本版本中解决。

PR 3573888:由于 vSphere Virtual Volumes 的内存问题,ESXi 主机可能失败并出现错误 “BlueScreen: PANIC bora/vmkernel/main/dlmalloc.c:4944”

如果在未持有锁的情况下修改了 vSphere Virtual Volumes 设备的缓存调度策略,当两个或多个线程同时尝试释放该策略时,ESXi 主机可能会失败,并显示错误 BlueScreen: PANIC bora/vmkernel/main/dlmalloc.c:4944

此问题已在本版本中解决。

PR 3529555:虚拟机迁移或创建快照等操作因 InvalidState 错误而失败

由于身份验证问题,虚拟机迁移或创建快照等操作可能失败,并显示以下错误:

在 hostd.log 中:vim.fault.InvalidState

在 vpxa.log 中:The operation is not allowed in the current state.

此问题已在本版本中解决。

PR 3541320:由于罕见的时间问题,ESXi 许可证可能提前过期

由于 hostd 服务中的一个罕见边界时间问题,ESXi 许可证可能在分配的到期日期之前过期,从而中断虚拟机操作。

此问题已在本版本中解决。

PR 3547590:罕见的内存预分配问题可能导致 ESXi 主机出现紫屏

对于某些类型的虚拟机(如 PCIe 直通虚拟机),ESXi 会在虚拟机上电时尝试预分配内存。如果在内存预分配期间虚拟机同时被 vSphere High Availability 终止,ESXi 主机可能会出现紫色诊断屏幕。

此问题已在本版本中解决。

PR 3557452:在 hostd 日志中看到多条 VMX 记分板不可读的消息

在从克隆或模板创建虚拟机后,vmxstats.filename 可能会重复父虚拟机的名称,导致主机统计注册表无法读取并记录新虚拟机的统计信息。结果是在 hostd 日志中会看到多条类似以下的信息:
Adding VM XXX failed, file /vmfs/volumes/YYY/ZZZ/ZZZ.scoreboard is not readable
该错误不会以任何方式影响新虚拟机的功能。

此问题已在本版本中解决。

PR 3553366:NVMe over Fibre Channel(NVMe/FC)设备在链路重置后无法恢复

在极少数情况下,由于并行发现和连接 NVMe/FC 设备时发生死锁,ESXi 主机在链路重置后可能无法重新连接所有 NVMe/FC 设备,并且已连接设备的性能也可能下降。

此问题已在本版本中解决。

PR 3552793:ESXi 主机在 NVMe UNMAP 操作期间可能发生内存泄漏

如果在 NVMe UNMAP 操作期间,对 NVMe 目标的 identify namespace 调用失败,为 UNMAP 命令分配的内存可能不会被释放。结果是,在重启主机以回收内存之前,该 ESXi 主机可能会显示更高的内存使用率 (sysin)。

此问题已在本版本中解决。

PR 3546519:vmxnet3 虚拟网卡在重新配置后可能停止发送数据

在高流量情况下,vmxnet3 虚拟网卡重新配置与发送路径之间发生的罕见竞争条件,可能会导致虚拟网卡在重新配置后停止发送数据。

此问题已在本版本中解决。

下载地址

VMware vSphere Hypervisor (ESXi) 8.0U3h

下载地址:https://sysin.org/blog/vmware-esxi-8-u3/

  • 发布日期:2025-12-15
  • 若干已知问题修复,详见官方文档或原文链接。
  • VMware vSphere Hypervisor (ESXi ISO) image
    File Name: VMware-VMvisor-Installer-8.0U3h-25067014.x86_64.iso
  • VMware vSphere Hypervisor (ESXi) Offline Bundle
    File Name: VMware-ESXi-8.0U3h-25067014-depot.zip

OEM Custom Image:

  • Dell Custom Image for ESXi 8.0U3h Install CD
  • HPE ProLiant Custom Image for ESXi 8.0U3h Install CD
  • HPE Synergy Custom Image for ESXi 8.0U3h Install CD
  • HPE Superdome Flex and Compute Scale-up family of servers Custom Image for ESXi 8.0U3h Install CD
  • IEIT SYSTEMS Custom Image for ESXi 8.0U3h Install CD
  • Lenovo Custom Image for ESXi 8.0U3h Install CD
  • H3C Custom Image for ESXi 8.0U3h Install CD
  • Cisco Custom Image for ESXi 8.0U3h Install CD
  • Fujitsu Custom Image for ESXi 8.0U3h Install CD
  • Hitachi Custom Image for 8.0U3h Install CD
  • NEC Custom Image for VMware ESXi 8.0U3h Install CD
  • Huawei Custom Image for VMware ESXi 8.0U3h Install CD
  • xFusion Custom Image for VMware ESXi 8.0U3h Install CD
  • 请访问:VMware ESXi 8.0U3h macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版

本站定制映像

相关产品:

更多:VMware 产品下载汇总

VMware vCenter Server 8.0U3h 发布 - 集中管理 vSphere 环境

Server Management Software | vCenter

请访问原文链接:https://sysin.org/blog/vmware-vcenter-8-u3/ 查看最新版。原创作品,转载请保留出处。

作者主页:sysin.org


vSphere 8.0U3h 已于 2025-12-16 发布,今天单独一篇来看一下新增功能。

VMware vCenter Server 是一款高级服务器管理软件,提供了一个集中式平台来控制 vSphere 环境,以实现跨混合云的可见性。

简化且高效的服务器管理

vCenter Server Appliance

什么是 vCenter Server?

实现集中式可见性、简化且高效的大规模管理,以及在整个混合云中的可延展性,所有这一切,均可通过单一控制台来实现。VMware vCenter Server 是高级服务器管理软件,提供了一个集中式平台来控制您的 VMware vSphere 环境,使您可以充满信心地在整个混合云中自动部署并交付虚拟基础架构。

新增功能

vCenter 8.0 Update 3h | 15 DEC 2025 | ISO Build 25092719

  • 本版本包含 Resolved Issues(已解决问题)章节中列出的错误修复(见下文)。

默认日志分区为 50 GB

从 vCenter 8.0 Update 3h 开始,任何 vCenter 部署的日志分区默认大小均为 50 GB

更新失败时的错误信息改进

vCenter 8.0 Update 3h 针对由于 vCenter 服务无法启动而导致的更新失败,增强了错误提示信息。在 虚拟设备管理界面(VAMI) 中,不再显示通用错误提示,而是会显示导致问题的具体服务信息,方便您在联系技术支持时提供更详细的排查依据。

vCenter 机器 SSL 证书和 ESXi SSL 证书的自动续期

从 vCenter 8.0 Update 3h 开始,VMware 证书颁发机构(VMCA) 为 vCenter 以及版本为 8.0 Update 3 及以上的 ESXi 所签发的 SSL 证书,会在接近过期时自动续期。

  • 当 vCenter 机器 SSL 证书距离过期时间不足 5 天 时,会自动延长 2 年
  • 对于支持无中断证书续期的 ESXi 主机,当 SSL 证书距离过期时间不足 10 天 时,会自动延长 5 年

如果 VMCA 证书模式设置为 custom,自动续期功能将无法生效,需要将模式更改为 vmca 才能启用该功能。

Resolved Issues(已解决的问题)

Miscellaneous Issues(其他问题)

PR 3571785:在 HP 主机上,分布式电源管理(DPM)操作耗时异常长

当在 HP 服务器上取消选择 IPMI/DCMI over LAN access 选项,并且关闭 HTTP 80 端口时,针对此类服务器上的 ESXi 主机执行 DPM 操作可能会耗费异常长的时间。例如,对主机执行 Enter Standby Mode(进入待机模式)或 Power On(开机)操作时,可能会额外延迟最长达 40 分钟。

此问题已在本版本中解决。

PR 3565605:Workspace ONE Access 服务的 syslog 配置指向了错误的目录,仍然引用旧名称 VMware Identity Manager

Workspace ONE Access 服务 vc-ws1a-broker 的 syslog 配置错误地指向日志目录 /opt/vmware/idm/logs/,而不是正确的 /var/log/vmware/vc-ws1a-broker。因此 (sysin),Workspace ONE Access 的日志不会被转发到 syslog 服务器。

此问题已在本版本中解决。

vSphere Client and vCenter Issues(vSphere Client 与 vCenter 问题)

PR 3541415:将 vSphere 配置配置文件应用到集群时因无效的 base64 编码字符串而失败

如果你的 vCenter 实例配置了长证书链,将 vSphere 配置配置文件应用到集群时可能会失败,并在日志中出现如下错误:

Configuration Profile error: Invalid base64-encoded string: number of data characters (5177) cannot be 1 more than a multiple of 4

此问题已在本版本中解决。

PR 3597653:当 /storage/log 分区空间不足时,就地更新 vCenter 时不会显示警告

如果 /storage/log 分区大小小于 50GB,在执行就地更新的预检查过程中 (sysin),不会显示提示要求增加日志分区大小的警告。

此问题已在本版本中解决。该修复在存储分区需要额外空间时增加了相应提示信息。

PR 3556150:在增强型链接模式(ELM)的 vCenter 实例中,vSphere Client 显示错误 “vCenter server replication status change alarm:”

如果 ELM 模式下某个 vCenter 实例中的复制任务最后一个操作是删除操作(例如删除现有用户),可能会触发错误的复制运行状况告警。结果是在 vSphere Client 中显示错误:

vCenter server replication status change alarm:

尽管复制运行状况实际上是正常的。

此问题已在本版本中解决。

PR 3543578:带有活动告警的 vCenter 集群 Summary 页面可能间歇性闪烁

在 vSphere Client 中,当你点击一个存在活动告警的 vCenter 集群的 Summary(摘要)选项卡时,页面可能会间歇性闪烁。该问题是由于 vSphere Client 监控集群子对象(包括告警)的变化,并需要一定时间刷新所导致的。

此问题已在本版本中解决。

PR 3531131:运行用于收集 vCenter 数据的自动化脚本后,vCenter vpxd 服务可能不可用

运行调用 VMODL1 Session Manager Login 并在多个并行 VMODL2 API 调用中使用该会话的自动化脚本 (sysin),有时可能导致 vCenter vpxd 服务失败。

此问题已在本版本中解决。

PR 3582332:在 NSX 用户界面中看到 “Logical Switch State has failed” 告警

在重新配置 NSX 逻辑交换机期间,如果部分 ESXi 主机与 vCenter 断开连接,重新配置可能会失败,并在 NSX 用户界面中触发 Logical Switch State has failed 告警。

此问题已在本版本中解决。

PR 3512033:当 VMware Appliance Management Service 密码过期时,vCenter 的计划备份失败

当 applmgmt 服务密码过期时,密码不会被重置,导致 vCenter 的计划备份失败。

此问题已在本版本中解决。该修复会在密码过期时为计划备份重置 applmgmt 服务密码。

PR 3588267:在禁用 SHA-1 的 ESXi 主机上,vSphere Client 中的 Web Console 无法连接虚拟机

如果在 ESXi 主机上将设置 Config.HostAgent.ticketing.thumbprintTypes 配置为 sha256,vSphere Client 中的 Web Console 将无法与这些主机上的虚拟机建立连接,因为控制台依赖主机的 SHA-1 指纹进行服务器验证。

此问题已在本版本中解决。

如果你已经遇到该问题但未升级到 vCenter 8.0 Update 3h,可通过在 vCenter 实例上将高级设置 config.mksdevproxy.enable 设置为 true 来启用 VMware Remote Console(VMRC)代理。

PR 3594615:升级到 vCenter 8.0 Update 3 或更高版本后,会看到许可证即将过期的警告

升级到 vCenter 8.0 Update 3 或更高版本后,即使没有许可证过期或即将过期,也可能在 vSphere Client 中看到如下横幅提示:

There are expired or expiring licenses in your inventory

此问题已在本版本中解决。

PR 3555318:手动 vCenter 备份失败,并显示错误 “Failed to create backup directory on backup server”

使用虚拟设备管理界面创建手动备份时,可能会看到如下错误:

Failed to create backup directory on backup server - ERROR: IS_EXISTS request failed. httpcode: 301

此问题已在本版本中解决。

PR 3574895:在 vSphere Client 中,VASA 5 或更高版本提供程序显示过期的端点证书

如果 VASA 5 或更高版本的提供程序具有一个设置了 retainVasaProviderCertificate=True 的虚拟主机 (sysin),在 vSphere Client 的 Storage Providers 页面中可能会看到该提供程序的过期端点证书。这是一个外观问题,不会影响 VASA 提供程序的功能。

此问题已在本版本中解决。

PR 3574892:注册 VASA 5 或更高版本提供程序时,vCenter 可能无法正确获取端点证书

在注册支持虚拟主机的 VASA 5 或更高版本提供程序时,vCenter 可能会保存默认的 VASA 端点证书,而不是实际的证书。因此,在 vSphere Client 中看到的是默认证书,而不是实际证书,但不会影响 VASA 提供程序的功能。

此问题已在本版本中解决。

PR 3551916:Tbilisi - UTC+04:00 时区的索引显示为负值

在自定义虚拟机并将时区设置为 Tbilisi - UTC+04:00 时,可能会看到诸如 -2147483577 的负值,而不是 Microsoft 时区索引值中定义的索引 170

此问题已在本版本中解决。

Networking Issues(网络问题)

PR 3575427:由于端口与主机关联错误,分布式虚拟交换机(DVS)可能不同步

在某些情况下,vCenter 可能会将分布式交换机端口推送到连接到不存在的虚拟机或未处于活动状态的 ESXi 主机上,导致 DVS 进入持续的不同步状态 (sysin)。

此问题已在本版本中解决。

Upgrade Issues(升级问题)

PR 3586423:升级到 vCenter 8.0 Update 3g 时,在安装 VMware Workspace ONE 容器阶段可能失败

在某些环境中,升级到 vCenter 8.0 Update 3g 时,可能在安装 Workspace ONE 容器过程中失败。

此问题已在本版本中解决。

vSAN Issues(vSAN 问题)

PR 3557847:vSAN 健康状态的 vCenter 日志文件缺少日志

/var/log/vmware/vsan-health/vmware-vsan-health-summary-result.log 文件可能无法按预期收集所有 vCenter 日志。

此问题已在本版本中解决。

Security Issues(安全问题)

PR 3487228:通过 API 或 UI 使用用户名和密码登录可能绕过 MFA 或地理围栏等联合身份策略

如果 vCenter 同时配置了联合身份提供程序和服务于同一域的传统身份提供程序,通过 API、虚拟设备管理界面(VAMI)或 vSphere Client 使用用户名和密码登录联合账户时,可能会被传统提供程序处理,从而绕过联合身份策略。

例如,即使联合身份规则不允许用户名/密码登录,也可以使用 PowerCLI 登录 vCenter。
如果在 VAMI 或 vSphere Client 中选择 use local account 但提供联合账户,也可能发生此类绕过。

此问题已在本版本中解决。
如果你遇到该问题但未升级到 vCenter 8.0 Update 3h,可使用命令行工具 sso-config utility 删除服务于同一域的传统提供程序,以阻止通过 API(如 PowerCLI Get-VIAccount)进行用户和组枚举。

Storage Issues(存储问题)

PR 3568964:容器卷失去同步或从 vCenter 中消失

如果从共享某个容器卷的其中一个集群中移除所有 ESXi 主机,vSphere Cloud Native Storage 可能会将该卷从数据库中移除,即使该卷仍可被连接到其他数据中心的 ESXi 主机访问。结果会导致卷失去同步或从 vCenter 中消失。

此问题已在本版本中解决。

PR 3537457:无法使用 REST API 创建的标签类别和标签来创建基于标签放置的 VM 存储策略

使用 vMODL2 REST API 调用为基于标签放置的 VM 存储策略创建标签时,标签类别可以成功创建 (sysin),但该类别下的标签不会在创建新标签型存储策略时显示为可选项。

此问题已在本版本中解决。

vSphere High Availability Issues(vSphere 高可用性问题)

PR 3528619:由于极少见的时间格式问题,vCenter HA 可能会间歇性发生故障切换

在极少数情况下,vCenter 高可用性健康状态 XML 文件中的日期时间格式在微秒字段中包含空值,可能导致 vCenter HA 间歇性发生故障切换。

此问题已在本版本中解决。

Auto Deploy Issues(Auto Deploy 问题)

PR 3550634:在大型 vCenter 系统中,Auto Deploy 的行为可能不一致

由于大型 vCenter 系统中 Auto Deploy HTTP 连接数及内部 HTTP 连接数存在限制,服务可能无法及时响应请求,导致操作缓慢或 ESXi 主机部署失败。

此问题已在本版本中解决。

PR 3554088:通过 Auto Deploy 启动的 ESXi 主机可能因 DNS 查询失败而无法加入 vCenter

由于 Auto Deploy 按顺序处理 IP 的 DNS 查询,在某些情况下,对非管理流量使用的 VMkernel 端口 IP 进行解析可能会导致 DNS 查询失败。

此问题已在本版本中解决。

vSphere Lifecycle Manager Issues(vSphere 生命周期管理器问题)

PR 3520271:即使 PCI 设备位于硬件兼容性列表(HCL)中,vSphere Lifecycle Manager 仍可能将其报告为不兼容

在极少数情况下,由于 vSAN Health 报告设备约束的方式与 vSphere Lifecycle Manager 解析这些约束的方式不一致,在 vSphere Client 中可能会看到某些 PCI 设备被标记为不兼容,即使它们位于 HCL 中。

此问题已在本版本中解决。

PR 3538803:在对 ESXi 独立主机执行升级前检查时,vSphere Lifecycle Manager 服务可能重启或停止

在通过 API 或 vSphere Client 对 ESXi 独立主机执行升级前检查期间,如果 Hardware Support Manager 报告状态为 FAILED,vSphere Lifecycle Manager 服务可能会重启或停止,需要手动启动该服务。

此问题已在本版本中解决。

下载地址

VMware vCenter Server 8.0U3h

下载地址:https://sysin.org/blog/vmware-vcenter-8-u3/

  • 发布日期:2025-12-15
  • 新增功能:26 多项已知问题修复,详见官方文档或原文链接。
  • VMware vCenter Server Appliance
    File Name: VMware-VCSA-all-8.0.3-25092719.iso
    File Size: 11.67 GB
  • VMware vCenter Server Appliance Patch
    File Name: VMware-vCenter-Server-Appliance-8.0.3.00700-25092719-patch-FP.iso
    File Size: 7.76 GB
  • VMware vCenter Server Appliance Update Bundle
    File Name: VMware-vCenter-Server-Appliance-8.0.3.00700-25092719-updaterepo.zip
    File Size: 8.03 GB

本站定制映像

相关产品:

更多:VMware 产品下载汇总

什么是 RTA?

一句话描述:RTA(Real-Time API)= 实时竞价接口,就是广告平台在每次广告曝光前,实时问飞猪"这个用户要不要投、出多少钱"的关键技术。

引    言

飞猪用户增长广告外部投放(RTA)系统自 2022 年上线以来,对接了头条、小红书、华为等 10+ 头部广告媒体渠道,日均处理千亿级请求(百万级 QPS),对低延迟、高吞吐、强稳定性提出极高要求。随着业务策略复杂度提升与流量规模持续增长,系统面临更高的性能与效率挑战。

为此,我们围绕两大核心目标展开系统性优化:

  • 研发效能提升:通过应用架构解耦、技术栈升级与研发流程优化等,系统性释放工程生产力;

  • 极致性能优化:从网络层、网关层、应用层到业务逻辑层优化,系统性降低响应延迟、减少资源成本、提升参竞率与准确率。

本文将按此结构,系统回顾我们的优化路径与核心成果。

整体链路架构

飞猪 RTA 作为广告投放的实时决策端,接收来自媒体的竞价请求。流量通过两种方式接入:

  • 聚合接入:经由阿里妈妈广告交易平台(Tanx 平台)统一转发;

  • 直连接入:如小红书、vivo 等媒体直接调用飞猪服务。

系统整体分为网关层(承担高并发请求接入与流量路由)和业务逻辑层(在毫秒级窗口内完成设备解析、人群定向、策略召回、频控与出价计算等多阶段实时决策),最终返回竞价结果。

研发效能升级

技术考量

早期 RTA 与多个业务模块共部署于同一应用。随着系统承载流量突破百万级 QPS,一个核心矛盾逐渐凸显:99% 的流量由 RTA 产生,但任何功能迭代都需全量发布,导致资源投入与业务价值配置需要重新审视

这促使我们从两个维度重新审视系统设计:

  • 资源效率维度:在硬件持续演进的背景下,如何通过架构优化释放单机潜能,以更少机器支撑更高吞吐?这不仅是成本问题,更是技术人应该追求的目标;

  • 研发效率维度:效能提升不能仅关注“开发快”,而应覆盖“开发→自测→发布→定位→解决”的完整闭环。尤其在多渠道 RTA 对接场景下,是否存在可复用的范式,能否借助 AI 进一步释放生产力?

基于此,我们决定以 RTA 为突破口,开展系统性效能升级——因其流量占比最高、优化 ROI 最显著,且业务逻辑相对独立,是验证新架构与新工具的理想载体。

优化方案

应用架构解耦 - RTA 独立拆分

识别核心矛盾、评估 ROI

在系统拆分上,优先考虑将 RTA 从原应用中拆出。有以下几点考虑:

  • RTA 依赖较少,后续做单元化更简单,成本更低。

  • 业务逻辑相对清晰,迁移风险可控;

  • 重点是它流量最大、成本最高,可以最大化享受底层技术升级带来的红利,ROI 更高。

在拆分过程中,曾评估切换到 GO(协程)方案,但综合考虑开发成本及后续维护成本后劝退。最终仍采用 Java 技术栈,但是升级了“大保健三件套”:JDK21(虚拟线程) + SpringBoot 3.x(比 2.x 快约 10-20%,依赖模块化初始化改进)+ 网络中间件优化(降低 I/O 开销与堆外内存)。

平滑迁移策略

为保障迁移过程零故障、可回滚,过程中作了以下关键思考:

图片

发布提效

发布不仅是功能上线的终点,更是系统韧性的起点。尤其当单次故障恢复时间直接影响业务收入时,应用重启速度、发布流程确定性、回滚敏捷性,就成为了衡量工程成熟度的关键指标。

为此,我们以“分钟级恢复”为目标,从流程与性能两个维度优化发布链路:

  • 优化发布流程,强化关键验证:移除“安全生产”卡口(测试后置至 Beta)、合并 Beta 与第一批发布,并将 Beta 日志采样改为全量,提升问题发现能力。

  • 加速应用重启,支撑快速回滚:基于 JDK 21 + Spring Boot 3 升级,精简依赖与配置,应用重启时间降低约 80%+,显著提升日常发布效率与故障恢复速度。

发布流程对比:

图片

测试提效

各媒体渠道环境高度异构且封闭,无法向开发或预发环境注入标准化测试流量。这导致传统 Mock 或人工构造用例难以覆盖真实长尾场景,逻辑变更后往往依赖线上验证,成本高、风险大。

针对测试成本大的问题,做了 2 点思考:

线上即标准:线上运行代码已验证可靠,其请求出入参可作为功能正确性的基准——预发环境用相同入参得到相同出参,即可判定代码正常;

真实流量即用例:线上流量天然覆盖最全场景,通过采集请求快照并在预发回放,可自动化完成功能验证与 diff 比对。

基于上面的思考,设计了一套流量采集和回放系统:

图片

开发运维提效

AI Coding 代码重构

在 AI 时代背景下,大家都在尝试进行 AI-Coding 实践,我们也从工具 Claude、Cursor、Qcoder,到框架 BMAD、OpenSpec 基本都用了一遍,沉淀了一些较为可行的范式。

针对 RTA 多渠道接入的场景,通过 AI Coding,我们高效完成了核心链路的代码框架的升级:

  • Pipeline 模式:将业务流程原子化拆分,按语义划分为多个节点,管道式编排,职责单一;

  • 适配层设计:在关键节点开放扩展点,媒体个性化逻辑收敛至适配层,主流程无侵入;

  • 插拔式接入:新媒体只需实现适配接口,即插即用。

最后整体的代码框架如下:

监控体系精细化

原有监控体系已覆盖 iGraph 调用、广告召回等关键链路,但仅提供“成功 / 失败”的二元指标,存在局限:

  • 监控颗粒度不足:无法区分失败根因。例如,iGraph 查询无结果突增时,难以判断是主动熔断、下游超时,还是真实无匹配;

  • 问题排查效率低:依赖人工翻查日志,定位耗时长,影响故障恢复速度。

为此,我们对强依赖接口进行深度可观测性升级:

  • 细化异常码,补齐多维度监控:针对 iGraph、人群召回、策略召回、溢价召回等核心环节,统一定义结构化异常码,并按媒体、地域、设备类型等维度聚合,实现快速定位与精准归因;

  • 构建 Pipeline 实时折损漏斗:基于节点化改造,将全链路拆解为可度量的转化阶段,通过可视化漏斗动态呈现各环节折损率及原因,使业务流转状态与瓶颈节点清晰可见。

优化成果

成本与性能

  • 机器成本大幅降低:在流量不变的情况下,服务器数量降低了 30%,单机 CPU 水位进一步降低 15%

  • 性能显著提升:RTA 接口平均 RT 下降 20%,应用重启速度大幅提升,有效支撑高频发布与快速故障恢复。

研发效率

  • 测试与发布效率大幅提升:通过流量回放能力,测试周期从 3 天缩短至 1 天;发布周期从至少 1 天缩短至约 2 小时

  • 开发与运维效率提升:新媒体渠道接入周期从 5 天缩短至 2 天;新增多维度监控指标,问题发现与定位效率提升 40%,实时折损漏斗让业务流转一目了然。

极致性能优化

面对高并发实时系统,我们摒弃了"头痛医头"的优化方式,构建了从网络层→网关层→应用层→业务层的全链路性能优化体系:

网络层优化:根治跨地域网络耗时

在接入多个外部媒体 RTA 后,跨地域调用问题凸显。由于媒体机房分布广泛(覆盖华北、华东、华南等区域),而飞猪 RTA 服务当时仅中心化部署于单一机房,导致跨地域单元调用时出现严重超时:

  • 现象:深圳 / 南通单元超时率高达 100%,张北单元相对较好

  • 矛盾点:飞猪服务端 P99 延迟仅数毫秒,但端到端仍无法满足媒体严苛的超时要求(如 30~60ms 级别);

  • 根因:每次请求都重新建立 TCP 连接,仅握手建连就要消耗约 30ms,叠加 HTTP 请求的 30ms,极易触发超时。

关键验证:通过 CNAME 切换进行了快速验证——将小红书南通区域流量直接导向张北中心机房,省去南通→张北的网络中转环节,超时率从 30% 骤降至 8% → 证明物理距离是根本瓶颈

HTTP 长连接复用

启用 HTTP 长连接复用,核心收益:节省 TCP 建连时间(~30ms)、RTT 次数从 2 次降为 1 次、减少系统开销(避免频繁握手 / 挥手)。

配置改造

通过调整网关层配置,显式启用 HTTP 长连接(Keep-Alive),并合理设置连接保活时长与单连接最大请求数,确保长连接有效复用。

解决首次请求超时难题

首次请求必须经历 TCP 建连,建连耗时导致 HTTP 超时,超时又导致连接关闭,长连接无法建立。

为此,通过改造 HTTP 客户端底层实现:当 HTTP 协议层超时时,TCP 连接往往已建立完成,若底层 TCP 连接已成功建立,则保留该连接供后续请求复用,打破“超时 → 关连接 → 无法长建连”的恶性循环。

优化后,深圳机房 su121、南通机房 ea120/ea119 的 RTA 超时率大幅降低,但跨地域网络延迟的不确定性仍未根除。

单元化部署

长连接复用虽然缓解了问题,但物理距离带来的 RTT 波动仍是稳定性隐患。RTA 服务完成独立拆分、系统依赖大幅简化后,具备了实施单元化的技术条件。

单元化部署,核心是梳理 RTA 服务的依赖关系,并针对不同的依赖项,制定了不同的改造方案(仅列出部分):

  • 强依赖(如缓存)本地化部署,确保低延迟访问;

  • 弱依赖(如配置类数据库)通过中心化代理 + 异步同步满足最终一致性。

优化成效:

单元化部署彻底解决了跨地域网络延迟问题:

  • 阿里妈妈广告平台侧:深圳、南通单元超时率降为 0.07%。

  • 小红书直连:超时率从 30%→0.01%。

网关层深度调优

作为流量入口,网关的性能直接影响系统整体稳定性。通过火焰图与 TCP 连接状态分析,我们发现异常现象:TIME_WAIT 连接数高达数千,而 ESTABLISHED 连接仅十余个。

这说明 Tengine 到后端应用也在使用短连接,每次请求都创建 / 销毁连接。TIME_WAIT 过多会导致端口耗尽、内存浪费(每个连接 2~4KB)和 CPU 开销增加。

Tegine 后端长连接优化

为了减少建连开销,我们在网关层启用与后端应用的长连接池,核心配置如下:

优化效果:

  • TIME-WAIT 总量下降了 99%

  • 集群 CPU 使用率:CPU 降了近 10pt。

  • 在保障稳定性前提下,缩容 15% 服务器数量后,单机水位仍保持在健康区间。

Tengine 配置精简

全盘梳理 Tengine 配置,针对性优化低效和冗余项:

  • 关闭非必要日志:access_log 单文件达 25G+ 引发磁盘告警,仅保留 error 日志

  • 移除 gzip 压缩:RTA 响应多为小 JSON,gzip 压缩收益低但 CPU 开销高

  • 启用 reuseport:配置 listen 80 reuseport,消除 accept 锁竞争,提升并发处理能力。

  • 优化效果:CPU 水位下降 2 个百分点。

应用层极致优化

应用层的性能瓶颈往往隐藏在非核心路径中,核心业务逻辑通常是经过多次优化的重点,而一些看似不起眼的非核心路径(如日志系统、下游服务调用等)往往成为隐藏的性能瓶颈。通过压测与线上监控,我们发现两个关键问题:日志埋点开销过大与下游长尾请求拖累整体 RT,并针对性实施优化。

日志系统优化

在高并发实时系统中,日志既是可观测性的基石,也可能成为性能瓶颈。通过 Arthas 火焰图分析 CPU 热点,发现日志埋点逻辑核心 RTA 业务逻辑的 CPU 占比居然相当,是两个大头,表明日志系统仍然有优化空间。

鉴于日志埋点对业务监控、链路追踪等的重要性,我们无法简单地关闭或大幅减少日志。因此,从减少日志量和提升日志吞吐效率两个方面进行优化:

  • 协议精简:精简日志的输出格式,采用紧凑型协议格式替代冗余的 JSON 格式,减少了 50% 的日志体积。

  • 批量聚合:通过 StringBuilder 将散落在多处的日志打印收敛到一次日志打印,直接降低了 IO 操作次数。

  • 异步刷盘:通异步日志过配置 Logback 的 AsyncAppender(设置 neverBlock=true)和 RollingFileAppender(设置 immediateFlush=false),以异步方式刷新日志到磁盘,减少了频繁的磁盘同步操作带来的系统开销,增加了日志的吞吐。

  • 分层采样:不同应用环境采取不同的采样策略,在 Beta 环境下进行全量采集以便快速定位问题;而在生产环境中实施千分之一的采样率,确保可观测性的同时大幅减少日志数量。

优化后,CPU 使用率降低了 9pt,整体日志文件大小减少了 60%,直接降低日志存储和分析成本。

主动熔断机制

在完成网络层、网关层的性能优化后,系统 P99 延迟已稳定满足媒体超时要求。但偶发的长尾“毛刺”请求(由瞬时 GC 抖动、资源竞争或下游微突发引起)仍可能影响毫秒级实时决策的稳定性。

为此,我们在核心依赖调用中引入主动超时熔断机制:对关键服务调用设置独立于全局超时的更严格执行时限,一旦超时立即中断并返回降级兜底结果,避免单点延迟拖累整体响应。

优化后,接口 P99 延迟波动显著平滑,各区域机房超时率进一步降低。

业务层优化:参竞率与准确率提升

核心洞察与背景

随着流量规模扩大,设备数量和类型同步增长,设备身份识别的一致性问题被放大,主要体现在以下三方面:

  • 策略一致性挑战:原有 ID 选择采用单一优先级规则(如 Android 优先 OAID → IMEI),当人群包仅包含 CAID 而系统选中 IDFA 时,可能导致匹配失败;

  • 标识歧义风险:采用扁平化的 didMd5 格式,在亿级规模下存在哈希碰撞可能,影响画像准确性;

  • 配置与执行不一致:离线策略(如定向表、溢价表)与实时决策使用不同 ID 格式,造成策略“写一套、用一套”,实际失效。

优化方案

  • 设备标识标准化:摒弃 didMd5 扁平格式,定义 didType_didValue 分层标识体系(如:idfa_{hash}, oaid_{hash}),通过类型前缀彻底消除哈希碰撞歧义,身份识别准确率提升至 99.99%

  • 召回策略重构:废弃单点优先级规则,构建多维身份并行召回引擎,提升召回成功率和准确率。

  • 全链路数据一致性:统一改造定向表、溢价系数表等 8 个核心离线表,确保策略定义与实时执行使用同一套标识体系;同时建立设备身份质量监控,自动过滤 "null"、"-" 等无效设备标识。

优化效果

  • 因 ID 不匹配导致的参竞失败大幅减少,整体参竞效率明显提升;

  • 投放精准度增强,无效拉新显著下降,营销资源更高效地触达目标用户。

总结与展望

总结

通过两阶段的系统性优化,飞猪 RTA 在性能与效能上都有显著的突破:

  • 性能与成本:通过应用拆分、架构升级与网关调优等,在整体 QPS 提升 60%+ 的前提下,服务器资源消耗降低约 30%;

  • 研发效能:通过流量回放、发布流程优化与核心链路重构,测试周期缩短约 65%,发布周期压缩超 80%,新渠道接入效率提升 60%+,问题发现与定位效率提升约 50%;

  • 业务价值:通过设备身份一致性治理,参竞效率显著提升;通过精准定向优化,拉新重复率大幅下降,用户质量明显改善。

展望

未来,RTA 将持续深耕性能与业务双轮驱动:一方面保持对 RTA 极致性能的探索;另一方面深度融合 AI 能力,构建投放效果自动诊断与策略自优化机制,实现从“实时响应”到“智能决策”的跃迁,让 RTA 系统不仅更快,而且更聪明,真正成为驱动业务增长的智能引擎。

WordPress 社区近日遭遇一起严重安全事件:在 LA-Studio Element Kit for Elementor 插件中发现了一个后门漏洞。该插件在超过 20,000 个网站上运行。漏洞编号为 CVE-2026-0920,CVSS 评分高达 9.8(严重),允许未授权攻击者立即创建管理员账号,从而完全接管受影响网站。
但与普通编码错误导致的漏洞不同,这个漏洞似乎是蓄意破坏行为
漏洞被发现后,插件厂商做出了令人震惊的承认:恶意代码是由前员工植入的。
“厂商在回应我们的询问时表示,一名前雇员将后门代码添加到了插件中。”Wordfence 的报告指出。时间点非常关键:该开发者在 12 月底离职,而 “对后门的最后一次修改正是在那个时候”,这表明代码是在其离职前不久被改动的。
后门被隐藏在插件的用户注册处理逻辑中。技术分析显示,ajax_register_handle() 函数包含 “将管理员权限添加到新用户的混淆代码”。
攻击者只需发送一个包含特定参数 lakit_bkrole 的注册请求即可触发该后门。代码被刻意混淆以避免被发现。研究人员指出:“特别值得注意的是,该功能明显经过混淆处理,这似乎是为了逃避检测。”
此次事件的后果极其严重。“一旦攻击者获得 WordPress 网站的管理员权限,他们就能像普通管理员一样操纵目标网站上的任何内容。” 包括上传恶意文件、注入垃圾内容或将访问者重定向到危险网站。
目前已在野外检测到攻击活动。Wordfence 在过去 24 小时内就拦截了 216 次针对该漏洞的攻击。
在 2026 年 1 月 13 日收到 Wordfence 的通知后,LA-Studio 团队迅速采取行动,于次日发布了补丁。
用户被敦促立即升级到 1.6.0 版本以移除后门。这一事件为科技公司敲响了警钟:“它提醒我们必须重视内部威胁,并在员工离职时确保有适当的控制和检查机制。”

Python 生态中出现了一起隐蔽的新型供应链攻击:一个伪装成知名数学库 SymPy 的恶意包正在将开发者的机器悄悄变成加密货币挖矿节点。Socket 威胁研究团队已将这个名为 sympy-dev 的恶意包标记为危险的 “拼写劫持(typosquatting)” 攻击,其目的是诱骗用户下载它而非正版 SymPy。
该攻击利用了开发者对开源仓库的信任。“Socket 威胁研究团队发现了一个恶意 PyPI 包 sympy-dev,它仿冒了 SymPy—— 一个每月下载量约 8500 万次的广泛使用的符号数学库。” 报告指出。
攻击者煞费苦心地让这个伪造包看起来十分逼真。“攻击者将 SymPy 的项目描述和品牌元素复制到 sympy-dev 的页面中,以增加用户误安装的概率。”
通过使用常见的命名方式 —— 在包名后加 -dev 以暗示这是开发版本 —— 攻击者在发布第一天就成功诱骗了 超过 1000 次下载。“下载量不等于实际感染量,但早期的下载数据表明该包很快进入了真实的开发者环境和 CI 系统。”
与粗暴的 “抢即跑” 攻击不同,该恶意软件的行为异常隐蔽。它不会在安装后立即执行,而是 “在特定多项式函数运行时才激活恶意代码;这种更隐蔽的方式能更好地混入正常的 SymPy 使用场景中”。
当开发者调用特定的数学函数(例如 Groebner 基计算)时,隐藏的恶意代码就会被触发。“被调用时,被植入后门的函数会从远程服务器获取 JSON 配置,下载由攻击者控制的 ELF 载荷,并通过匿名的内存文件描述符执行它。”
这种利用 memfd_create 的执行方式可以帮助恶意软件绕过传统的基于磁盘扫描的杀毒软件。
与隐蔽的投放方式相比,载荷本身的行为则毫不掩饰:它是一个 加密货币挖矿程序。“在动态分析中获取的样本显示,下载的载荷是 XMRig 加密挖矿程序,其配置会通过 TLS 连接到挖矿池的 Stratum 端点。”
然而研究人员警告称,该攻击基础设施是模块化的。“在此次攻击中我们观察到的是 XMRig 挖矿行为,但同一执行链可以在 Python 进程权限下执行任意代码。” 这意味着攻击者可以在不修改包的情况下,随时将挖矿程序替换为勒索软件或数据窃取工具。
该恶意包于 2026 年 1 月 17 日 发布,在报告发布时仍存在于 PyPI 上。Socket 已申请将其下架,但这一事件再次提醒人们软件供应链的脆弱性。
“防御者应预期,嵌入分阶段下载器和内存执行的拼写劫持包将会持续存在并不断演变。” 研究人员警告说。他们建议团队 “优先采用依赖项锁定(dependency pinning)和完整性校验”,以避免未来成为类似攻击的受害者。

OpenAI 已对部分领导层进行了重组,并挑选了一位 “老熟人” 来领导其向企业客户销售 AI 的业务,因为公司希望在 2026 年赶上竞争对手。
据《The Information》报道,OpenAI 在一份内部备忘录中宣布,任命 Barret Zoph 负责企业业务销售工作。
TechCrunch 已联系 OpenAI 寻求确认和更多信息。
Zoph 上周从 Thinking Machine Labs 回到 OpenAI。他自 2024 年 10 月起在该公司担任联合创始人兼首席技术官,而该公司正是前 OpenAI 首席技术官 Mira Murati 创办的 AI 初创企业。
他离开 Thinking Machine Labs 的具体原因尚不清楚,有传言称 Zoph 和其他几位前 OpenAI 员工是被解雇,也有人说他们是自愿离职,甚至可能早就计划重返 OpenAI。
Zoph 此前在 2022 年 9 月至 2024 年 10 月期间担任 OpenAI 的 训练后推理副总裁。如今他将进入一个完全不同的岗位,并可能在公司中扮演重要角色,因为 OpenAI 正努力扩大其企业业务 —— 这是一个它正逐渐输给竞争对手的领域。
OpenAI 在 2023 年就推出了面向企业的 ChatGPT Enterprise,比 Anthropic 早了一年多,也领先 Google 多年。公司声称该产品拥有超过 500 万企业用户,客户包括 SoftBank、Target 和 Lowe’s 等公司。
但它的市场份额正在下降,而竞争对手正在上升。
在企业级大语言模型使用方面,Anthropic 遥遥领先。根据风投公司 Menlo Ventures 12 月的报告(该公司对 Anthropic 有大量投资),Anthropic 占据了 40% 的市场份额。而在 7 月,该公司的市场份额估计为 32%。
根据 Menlo Ventures 的数据,Google Gemini 的采用率则更为稳定。Google 在去年秋天推出了企业版产品,其企业级 LLM 使用市场份额基本保持不变,从 7 月的 20% 增长到年底的 21%。
相比之下,OpenAI 的市场份额已从 2023 年的 50% 下降到 2025 年底的 27%—— 这一趋势显然让公司感到担忧。几个月前,OpenAI CEO Sam Altman 在一份内部备忘录中特别提到,Google Gemini 的增长开始侵蚀 OpenAI 的市场。
OpenAI 首席财务官 Sarah Friar 在本周日的博客中写道,企业业务增长是公司 2026 年的重点。
此后,公司宣布与 ServiceNow 扩大多年合作关系,ServiceNow 客户将能够使用 OpenAI 的模型。

与(HPE)已向存储管理员发出安全警报,警告其旗舰企业级存储阵列中存在一个高严重性漏洞。该漏洞编号为 CVE-2026-23594,CVSS 评分为 8.8,表明对于依赖这些系统进行关键数据管理的组织来说风险极高。
该漏洞影响 HPE AlletraNimble Storage 阵列,可能允许攻击者未经授权控制操作系统
问题的核心在于存储操作系统在特定配置下如何处理权限。根据安全公告:“在某些 Alletra 6000、Alletra 5000 和 HPE Nimble Storage Array OS 配置中存在一个漏洞,可能导致远程权限提升。”
这意味着远程攻击者 —— 即无需物理进入数据中心的人 —— 可以利用该漏洞提升权限,甚至可能获得存储阵列的管理员控制权。在企业环境中,这种访问权限可能带来灾难性后果,使入侵者能够窃取敏感数据、中断业务运营,或直接在备份与存储基础设施上部署勒索软件。
该漏洞影响 HPE 产品组合中的多条产品线。管理员应立即检查是否正在运行以下硬件:
  • HPE Alletra 6000 & 5000
  • HPE Nimble Storage Hybrid Flash Arrays
  • Nimble Storage All Flash Arrays
所有这些平台上,6.1.2.800 之前的版本以及 6.1.3 系列中 6.1.3.300 之前的版本均受影响。
HPE 已迅速采取行动修复该安全漏洞。存储管理员被敦促立即将阵列 OS 升级到 6.1.2.800 或 6.1.3.300,以降低未授权访问的风险。

第一次接外汇行情接口的时候,大多数人都会觉得这件事不难。
连上 WebSocket,订阅一个 EURUSD,看着 tick 数据持续推送,基本都会下意识地认为:行情模块已经搞定了。
但只要系统开始长时间运行,或者订阅多个货币对,问题很快就会暴露出来。
连接稳定性、推送结构、字段一致性,这些一开始看起来不起眼的细节,往往会在后期变成系统复杂度的来源。

行情模块的特点:不复杂,但很难返工

和策略、风控相比,行情模块本身并不算复杂。
但它有一个明显特点:
一旦被多个模块依赖,就很难再动。
策略可以反复调整,参数可以不断优化,但行情数据如果在多个地方被使用,只要结构有变化,就会影响整条链路。
所以后来我在系统设计里,会刻意把行情模块当成一层基础设施来看,而不是一个普通功能。
标准也很简单:

  • 能跑只是最低要求
  • 能长期稳定跑,而且结构不变,才算可用

    为什么外汇行情更适合用 WebSocket

    如果只是偶尔获取一次行情,用 REST 接口也不是不行。
    但外汇市场的现实情况是:
    数据更新频率非常高。
    用 REST 拉行情,本质是在做高频轮询,系统不断地在问:
    现在有没有新数据?
    WebSocket 的模式正好相反:
    有数据你再推送,没有就保持连接。
    在系统运行时间拉长之后,这种差异会直接体现在:

  • 延迟稳定性
  • 连接抖动
  • 资源占用情况
    尤其是多品种订阅时,这个差别会更加明显。

    接外汇行情接口,关键不是接口而是边界

    接口文档写得再清楚,也解决不了一个核心问题:
    行情模块的职责边界在哪里?
    在我的实践里,行情接入层只做三件事:

  • 建立连接
  • 订阅行情
  • 把数据原样交给下游
    到这里就应该结束。
    如果在行情层里开始做策略判断、交易时间判断,或者业务状态判断,后期维护成本会明显上升,而且很难拆干净。

    一个相对克制的外汇行情接入示例

    下面这段代码是我常用的一种结构,逻辑非常简单,也刻意保持了“不过界”。

import websocket
import json

WS_URL = "wss://stream.alltick.co/ws"

def on_open(ws):
    ws.send(json.dumps({
        "op": "auth",
        "args": {
            "token": "YOUR_API_KEY"
        }
    }))

    ws.send(json.dumps({
        "op": "subscribe",
        "args": [
            {
                "channel": "tick",
                "symbol": "EURUSD"
            }
        ]
    }))

def on_message(ws, message):
    data = json.loads(message)
    if data.get("channel") == "tick":
        forward_tick(data["data"])

def forward_tick(tick):
    # 到这里为止
    # 行情模块已经完成任务
    pass

ws = websocket.WebSocketApp(
    WS_URL,
    on_open=on_open,
    on_message=on_message
)

ws.run_forever()

forward_tick 之后的处理逻辑,并不属于行情模块的职责范围。
行情模块只负责一件事:
稳定地把外汇行情数据交出去。

多品种订阅时,少做判断反而更稳

当开始同时订阅多个货币对时,很容易在行情层写大量分支逻辑:

  • 不同 symbol 不同处理方式
  • 不同品种不同判断条件
    但实践下来会发现,这些判断大多不该出现在行情层。
    我更倾向于一个简单原则:
  • 行情层只处理 symbol 和数据
  • 含义和业务逻辑交给下游
    这样新增或删除品种时,行情模块几乎不用改动,系统结构也更清晰。

    外汇行情 API 的差异,往往体现在结构稳定性上

    很多外汇行情 API 在功能层面看起来差别不大。
    但系统真正跑起来之后,差异通常体现在这些地方:

  • 数据字段是否长期稳定
  • 不同市场是否统一推送结构
  • 多品种订阅时是否保持一致行为
    有些行情服务在设计时,就把外汇、加密资产、股票等行情统一在同一套推送模型中,比如 AllTick API 这一类实时行情接口,在接入外汇行情时整体适配成本会更低,不太容易被细节反复打断。

    行情模块越“安静”,系统反而越可靠

    写到最后,其实只有一个结论。
    一个好的行情模块,不需要有太强的存在感。
    它不承担业务决策,也不表达逻辑判断,只是持续、稳定地输出数据。
    当行情接口选得合适,边界又控制得住,很多系统层面的问题,往往会自然消失。
    如果你正在搭建一个长期运行的外汇交易系统,行情模块这一步,值得多花一点时间想清楚。

GNU InetUtils 的 telnet 守护进程(telnetd)中被披露存在一个严重安全漏洞,该漏洞已隐藏近 11 年未被发现。
此漏洞的 CVE 编号为 CVE-2026-24061,在 CVSS 评分系统中得分为 9.8/10.0(严重级别),影响 GNU InetUtils 从 1.9.3 版本到 2.7 版本(含 2.7 版本)的所有版本。
美国国家标准与技术研究院(NIST)国家漏洞数据库(NVD)对该漏洞的描述为:“GNU Inetutils 2.7 及以下版本中的 telnetd 存在远程身份验证绕过漏洞,攻击者可通过将 USER 环境变量设置为 ‘-f root’ 实现绕过。”
GNU 贡献者 Simon Josefsson 在 oss-security 邮件列表中发文指出,攻击者可利用该漏洞获取目标系统的 root 权限,具体利用方式如下:
  • telnetd 服务器会调用 /usr/bin/login(通常以 root 权限运行),并将从客户端接收的 USER 环境变量值作为最后一个参数传入。
  • 若客户端构造特殊的 USER 环境变量值(即字符串 “-f root”),并通过 telnet (1) 的 -a--login 参数将该 USER 环境变量发送至服务器,即可绕过正常身份验证流程,直接以 root 用户身份自动登录系统。
漏洞成因在于:telnetd 服务器在将 USER 环境变量传递给 login (1) 之前未进行任何净化处理,而 login (1) 工具本身支持通过 -f 参数绕过正常身份验证流程。
Josefsson 还提到,该漏洞源于 2015 年 3 月 19 日的一次源代码提交,并随 2015 年 5 月 12 日发布的 1.9.3 版本正式引入。安全研究员 Kyu Neushwaistein(又名 Carlos Cortes Alvarez)于 2026 年 1 月 19 日发现并报告了该漏洞。

漏洞缓解措施

Josefsson 建议采取以下缓解措施:
  1. 安装最新补丁:及时应用官方发布的修复补丁(优先推荐);
  2. 限制端口访问:仅允许可信客户端访问 telnet 端口(默认 23 端口);
  3. 临时规避方案
    • 直接禁用 telnetd 服务器;
    • 让 InetUtils telnetd 使用自定义的 login (1) 工具,且该工具需禁止使用 -f 参数。

攻击态势监测

威胁情报公司 GreyNoise 收集的数据显示,过去 24 小时内已监测到 21 个独立 IP 地址 尝试利用该漏洞发起远程身份验证绕过攻击。这些 IP 地址分别来自中国香港、美国、日本、荷兰、中国内地、德国、新加坡和泰国,且均已被标记为恶意 IP。
觉得这篇文章有价值?关注我们的 Google 新闻、Twitter 和 LinkedIn 账号,获取更多独家内容。

2026 年 1 月 22 日凌晨,随着现代企业沟通与协作的核心平台 Microsoft 365 全面停摆,一波挫败感席卷了办公室、远程工作区和企业会议室。用户在尝试登录邮箱、加入 Teams 会议或编辑 SharePoint 文件时,只能看到错误提示和无限加载的界面。这不是一次小故障,而是一场影响全球数千家企业的大范围服务中断,凸显了依赖云生产力套件的潜在风险。
大约在 UTC 时间 11:40,来自北美、欧洲和亚太地区的用户开始在社交媒体和宕机监测网站上集中反馈问题。根据服务中断监测平台 Downdetector 的数据,Microsoft 365 的故障报告数量在一小时内激增,峰值超过 5,000 条。此次事件不仅扰乱了个人工作流,也影响了从销售演示到高管简报等关键业务运营。
微软通过官方状态页面和社交渠道迅速确认了问题,表示正在调查 Exchange Online、Outlook、Teams 及相关服务的异常。公司在最初的声明中强调工程师正在努力确定根本原因,但细节在早期阶段非常有限,导致 IT 管理员只能仓促寻找临时解决办法。


宕机对全球业务的即时连锁反应

随着中断范围扩大,用户反馈和企业报告逐渐揭示了事件的严重性。在美国,多家大公司报告无法访问收件箱,导致会议推迟、决策延迟。某财富 500 强企业的 IT 经理形容当时的情况是 “有组织的混乱”,团队不得不使用个人邮箱和 Slack、Zoom 等替代工具维持业务运转。
在欧洲,伦敦和柏林正处于业务高峰时段,用户也遭遇了类似问题。高度依赖 Microsoft 365 进行安全文档共享的金融机构出现显著延迟,引发了合规性和数据可访问性方面的担忧。在亚洲,虽然工作日已接近尾声,但影响持续到售后支持时段,波及需要全天候运营的跨国公司。
宕机不仅影响核心应用,还波及 Microsoft Admin Center 等辅助服务,导致系统管理员无法管理用户账户或监控服务状态。这进一步加剧了问题,因为 IT 团队无法获取实时诊断信息,只能依赖外部来源获取更新。


技术故障的根源追踪

初步调查指向微软 Azure 基础设施的潜在问题,该平台是支撑 365 服务的底层云环境。知情人士透露,例行维护期间的一次配置变更可能在数据中心间引发了级联故障。虽然微软尚未证实这一点,但过去类似事件大多源于此类更新操作失误。
Downdetector 等宕机监测服务提供了明显的峰值数据,用户报告中出现了 Excel 和 Outlook 的具体错误提示,例如 “Sorry, our server is temporarily having problems”。社区论坛指出,这与 1 月 21 日(前一天)发生的一次较小规模性能下降事件相似。
微软响应团队迅速行动,采取了包括将流量重新路由到未受影响服务器在内的缓解措施。到 UTC 下午中段,部分用户恢复了服务,但某些地区的完全恢复仍滞后。公司通过服务运行状况仪表板每 30 分钟发布一次更新,这是从以往宕机事件中总结出的提升透明度的做法。


微软可靠性挑战的历史背景

2026 年 1 月的这次事件并非孤立,而是 Microsoft 365 多年来多次中断中的最新一起。早在 2020 年,一次重大宕机导致 Outlook 和 Teams 数小时无法使用,原因是身份验证系统出现问题。最近一次是在 2024 年 7 月,用户遭遇与 Xbox Live 集成相关的邮件访问故障,多家科技媒体对此进行了报道。
行业分析师指出,随着微软不断扩张其云帝国,生态系统的复杂性也增加了此类故障的风险。2026 年 1 月初,Reddit 上的 r/sysadmin 帖子讨论了 365 即将到来的功能变更,包括一些可能在管理不当情况下引入不稳定性的功能退役。参与讨论的用户当时就警告,功能更新可能导致潜在中断。
与 Google Workspace 等竞争对手相比,虽然所有云服务都会发生宕机,但微软的规模使其影响更为广泛。仅在 2025 年,微软就至少经历了三次值得注意的事件,每一次都引发了监管机构和客户对更严格服务等级协议(SLA)的关注。


用户情绪与实时反应

随着宕机持续,社交媒体平台上的讨论热度不断上升。X(原 Twitter)上的帖子记录了用户的挫败感,有人分享错误截图,也有人发布关于生产力停滞的幽默梗图。其中一条热门帖子将此次事件比作 “云决定放雪假”,反映了用户普遍的无奈与调侃。
企业方面的反馈则更为尖锐。在 2026 年 1 月 21 日的 Spiceworks 社区讨论中,IT 专业人士就云服务的可靠性展开了辩论,部分人主张使用混合云或本地部署作为备份方案。这一观点在 X 的实时更新中也得到了呼应,管理员们分享了使用移动应用进行部分访问的权宜之计。
微软官方账号 @MSFT365Status 提供了阶段性更新,向用户保证修复工作正在进行。然而,由于没有给出预计恢复时间,引发了用户猜测,甚至有人推测与网络威胁有关,但没有证据支持这一说法。


经济与业务影响

宕机造成的经济损失难以立即量化,但根据以往类似事件的估计,可能高达数十亿美元的生产力损失。Gartner 2025 年的一项研究指出,大型企业每小时停机成本可能超过 30 万美元,对于全球运营的公司来说,损失会呈指数级增长。
医疗和金融行业受到的冲击尤为严重。依赖 Microsoft 365 存储患者记录和进行沟通的医院报告非关键任务出现延迟,不过紧急系统仍保持运行。无法通过集成工具访问实时数据的金融交易员则面临潜在的市场劣势。
小型企业由于缺乏强大的 IT 支持,受到的影响更为突出。一位初创公司创始人在 X 上分享了宕机如何破坏了他的重要投资者演示,凸显了云依赖带来的民主化优势与风险并存。


微软的缓解与恢复措施

作为回应,微软启动了事件响应协议,包括来自工程、安全和客户支持部门的跨职能团队。公司承诺发布事后分析报告,这是其标准做法,通常会在几周内详细说明原因和预防措施。
《今日美国》等新闻媒体跟踪报道了宕机进展,指出受影响用户数以千计。与此同时,CNBC 报道了针对 Outlook 的修复工作,并将此次事件与数月前的一次长时间中断进行了对比。
到 UTC 1 月 22 日傍晚,微软宣布大多数用户的问题已解决,尽管个别案例仍存在残留影响。公司建议用户重启客户端并清除缓存作为最后的恢复步骤。


云依赖的广泛影响

此次宕机再次引发了关于过度依赖单一供应商的讨论。专家主张采用多云架构等多元化策略来降低风险。Forrester Research 的一份报告强调,企业需要审计供应商依赖关系并投资冗余机制。
监管机构也可能对此关注。在数据主权法律严格的欧盟,此类中断可能加速对云巨头加强监管的呼声。美国联邦贸易委员会此前曾就类似事件的反竞争影响展开调查。
对于微软而言,维护信任至关重要。在其市值超过 3 万亿美元的背景下,即使短暂的宕机也会削弱用户信心。尽管公司已投入巨资开发 AI 驱动的监控系统以预测和预防故障,但此次事件无疑对这些能力构成了考验。


来自一线的经验教训

IT 领导者已经开始从此次宕机中总结经验。逐渐形成的最佳实践包括定期进行停机场景演练,以及使用微软生态之外的第三方监控工具。
Reddit 和 Spiceworks 等用户社区也在进行事后分析。Spiceworks 社区的一个帖子讨论了 1 月 21 日的前兆事件,认为那是许多人忽视的警告信号。
展望未来,微软可能会推出增强措施,甚至可能加速 1 月初更新中宣布的高级故障转移机制等功能。


应对数字基础设施的未来不确定性

随着企业逐步恢复,此次事件提醒人们,互联系统中固有的脆弱性始终存在。虽然云计算提供了可扩展性和效率,但也需要强大的应急计划。
分析师预测,此次宕机可能会影响合同谈判,企业将在服务协议中要求更强的保障和处罚条款。微软的竞争对手也可能借此机会强调自身的可靠性指标。
归根结底,2026 年 1 月的 Microsoft 365 宕机事件凸显了数字依赖的不断演变,促使组织重新评估其技术基础架构,以抵御不可避免的中断。在工作日益虚拟化的时代,确保无缝访问不仅是一种便利,更是维持经济活力的必要条件。

在不断演进的搜索技术领域,Google 再次突破边界,推出了最新创新:集成到 Google 搜索 AI 模式中的「个人智能(Personal Intelligence)」。这项功能于 2026 年 1 月 22 日 发布,标志着人工智能在个性化用户体验方面迈出重要一步 —— 它可以直接从 Gmail、Google Photos 等个人数据源中提取信息。对于追踪 AI 发展的行业专业人士来说,这一进展意味着用户上下文与搜索能力的深度融合,可能重塑用户互动方式以及数据隐私规范。
该功能的核心是:在用户主动授权的前提下,Google 的 AI 可以访问并分析其电子邮件和照片库,从而提供高度个性化的搜索结果。想象一下,当你搜索 “周末短途旅行” 时,系统不仅会推荐目的地,还会参考你过去的旅行邮件和度假照片,推荐符合你偏好的地点。这不仅是为了方便,更是 Google 的一项战略举措 —— 让搜索更直观、更 “黏用户”,从而鼓励用户留在其生态系统内。
此次功能首先面向 Google AI Pro 与 Ultra 订阅用户推出,在美国地区作为 Google Labs 的实验性功能上线。根据 Google 博客文章中的信息,该技术基于 Gemini 模型构建,能够提供 “真正属于你个人” 的回答。早期用户反馈显示,它在规划、购物和个性化推荐类查询中表现突出,因为这些场景能充分利用个人上下文信息。

解锁用户数据,让搜索更智能

此次集成是 Google 在 2026 年 1 月初首次在独立 Gemini 应用中推出的 Personal Intelligence 功能的延伸。正如另一篇 Google 博客所概述的那样,该功能将 AI 与多个 Google 应用连接,使建议更贴合用户真实习惯。在搜索的 AI 模式中,这意味着回答不再停留在通用层面,而是可以融入个人经历,例如从相册中识别你喜欢的餐厅,或从邮件中提取航班信息。
不出所料,隐私问题成为关注焦点。Google 强调该功能为可选开启,并且尽可能在设备端处理数据以降低风险。然而,批评者指出,Gmail 和 Photos 中包含大量敏感信息,潜在漏洞依然存在。行业分析师认为,这可能会触及监管红线,尤其是在 GDPR 等对数据处理要求严格的地区。
从技术角度看,Personal Intelligence 利用了 Gemini 的高级多模态能力,能够无缝处理文本、图像和元数据。这使得复杂交互成为可能,例如询问 “我应该穿什么去参加表妹的婚礼?”AI 会根据你的照片库中的穿搭风格和邮件邀请函给出建议。相比之前的 AI Overview,这是一次明显的升级。

从 “假设场景” 到 “高度个人化”:真实世界的应用

科技评测者的测试显示,该功能在旅行规划方面表现尤为出色。例如,搜索 “根据我过去的旅行帮我规划一次日本之旅” 时,AI 会根据你照片中体现的偏好(如喜欢安静的地方)以及 Gmail 中的历史预订信息,生成避开拥挤景点的行程。这种个性化能力来自于在聚合用户数据上训练的机器学习模型,不过 Google 强调会通过匿名化保护个人隐私。
购物体验也得到了提升。想象搜索 “给我妹妹的生日礼物”,AI 会参考你邮件中提到的她的喜好或共享照片,推荐更符合她风格的礼物。据 ABC News 报道,这种基于用户习惯和行程的推荐为个性化电商打开了 “新的窗口”。对于电商从业者来说,这可能会颠覆传统推荐引擎,使其更主动、更懂用户。
除了休闲场景,专业用途也同样具有潜力。企业用户可以搜索 “总结我最近的项目邮件,生成状态更新”,AI 会从 Gmail 对话中提炼关键信息。这与 Google 在企业 AI 领域的整体布局一致 —— 让用户无需离开搜索界面即可提升工作效率。

在隐私雷区中谨慎前行

然而,该功能并非没有反对者。正如 WebProNews 所报道的,隐私倡导者对让 AI 访问个人档案表示担忧,即使是在用户自愿开启的情况下。文章指出,虽然设备端处理能降低风险,但随着功能向全球扩展,数据泄露或滥用的可能性仍然存在。
Google 则强调用户拥有控制权,例如随时撤销授权或删除特定数据。尽管如此,对于行业观察者来说,此次推出是对 “创新与信任之间平衡” 的一次考验。与 Apple 的 Private Cloud Compute 或 Meta 的数据共享做法相比,Google 正试图将自己定位为 “负责任的 AI 个性化领导者”。
此外,与 AI Pro/Ultra 绑定的订阅模式也暗示了一种新的商业化策略。免费用户仍可使用基础 AI 模式,但深度个性化功能只对付费用户开放,这可能导致搜索体验的 “分层”。

AI 在搜索中的演进:历史背景

要理解 Personal Intelligence,有必要回顾 AI 模式的发展历程。该功能最初在 Google I/O 2025 上推出,当时主要提供由 Gemini 驱动的对话式回答。随后,它加入了深度搜索和多模态输入等功能,并作为独立标签页向美国用户开放。
科技影响者在 X 上的帖子(例如 Sundar Pichai 在 2025 年 7 月的分享)曾预告过更高级的能力,如用于复杂任务的智能体 AI。而在 2026 年 1 月 22 日,9to5Google 等媒体在 X 上发文,对 Personal Intelligence 如何让搜索 “真正属于你” 表示兴奋,尽管也有用户对数据隐私表达担忧。
这一发展反映了 Google 应对 OpenAI 的 ChatGPT 和 Microsoft 的 Bing AI 的竞争策略。通过将个人数据深度集成到全球使用最广泛的搜索引擎中,Google 旨在巩固其主导地位。

行业影响与竞争压力

对于开发者和网站所有者来说,这一变化带来了连锁反应。Google 的开发者文档解释了 AI 功能如何在个性化回答中展示网站内容,并建议优化网站以提高被收录的概率。这可能会为符合用户上下文的网站带来更多流量,但也可能削弱传统自然搜索结果的重要性。
在竞争层面,这对竞争对手构成了压力。Apple 的 Siri 增强功能或 Amazon 的 Alexa 集成在数据规模上无法与 Google 匹敌。行业内部人士推测,这可能加速并购或合作,因为小型企业需要提升个性化能力以保持竞争力。
在经济层面,该功能与 Google 的收入模式紧密相关。通过 AI Pro 订阅,Google 可以将高级 AI 变现,从而在个性化搜索可能减少外部网站点击量的情况下,抵消广告收入的下降。

用户采用与未来扩展

从 Jason Howell 等评测者在 2026 年 1 月 22 日发布的 X 帖子来看,早期采用率表现良好。他对旅行规划和穿搭分析的测试显示,AI 输出高度贴合个人偏好,尽管偶尔会出现数据解读错误。
展望未来,Google 暗示可能会将该功能扩展到更多应用,例如 Drive 或 Calendar,这与最初的 Gemini 集成路线一致。最终,它可能演变为搜索内部的 “全功能个人 AI 助手”,能够处理从健康查询(参考健身照片)到财务规划(分析邮件收据)的各种任务。
当然,挑战依然存在,包括确保准确性以及避免个性化 AI 中的偏见。例如,如果用户的照片库偏向某些人群,推荐可能会强化 “信息茧房”。

战略愿景与伦理考量

Google 领导层(包括 Robby Stein 在 2026 年 1 月 22 日的 X 帖子)将这一功能视为打造 “真正理解你” 的搜索的关键一步。这是其更宏大愿景的一部分 —— 让 AI 能够预测需求,将搜索与个人智能无缝融合。
在伦理层面,透明的数据使用至关重要。监管机构可能会审查 Google 如何获取用户同意,尤其是在家庭共享账户中,照片可能包含他人的个人信息。
对于科技行业的管理者来说,这凸显了投资隐私保护型 AI 的重要性。Google 的举措可能会成为行业先例,影响整个领域的标准制定。

开启个性化科技的新时代

随着 Personal Intelligence 的推出,AI 正从通用工具向更 “懂你” 的私人助手转变。行业资深人士将其与移动搜索的兴起相提并论,认为它可能再次改变用户获取信息的方式。
Android Authority 等媒体的反馈显示,对于那些更看重便利而非隐私顾虑的用户来说,这是一项 “改变游戏规则” 的功能,甚至有文章称它 “知道你去年夏天做了什么”。
归根结底,这项创新让人们不得不思考:为了获得更智能的服务,我们愿意牺牲多少隐私?对于行业从业者来说,观察其采用率将有助于理解用户的容忍度,以及搜索技术的未来方向。
总的来说,Personal Intelligence 是 Google 的一次大胆尝试,它将庞大的数据资源与前沿 AI 结合,重新定义了个性化体验。它能否成功,将取决于 Google 是否能在实用性与安全保护之间找到平衡 —— 而这可能会决定下一代智能系统的发展路径。

External Secrets Operator 中发现了一个严重安全漏洞。该工具是 Kubernetes 生态中广泛使用的外部密钥管理组件,用于连接 AWS Secrets Manager、HashiCorp Vault 等外部密钥系统与 Kubernetes 集群。漏洞编号为 CVE-2026-22822,CVSS 评分高达 9.3(严重),意味着攻击者可能借此直接获取敏感数据。
该漏洞导致 不安全的密钥读取(Insecure Secret Retrieval),并破坏了 Kubernetes 中最基本的命名空间隔离机制
问题源于一个名为 getSecretKey 的模板函数。该函数最初是为了支持 senhasegura DevOps Secrets Management (DSM) 提供商而引入的,但后来被发现功能过于强大,从而带来安全隐患。
根据安全公告:“该函数能够在 external-secrets 控制器的 roleBinding 权限下跨命名空间读取密钥,从而绕过我们的安全机制。”
这意味着,一个命名空间中的恶意资源或配置错误的资源,可能读取到另一个命名空间的密钥—— 而这些密钥原本是完全不允许它访问的。“攻击者或配置错误的资源可以从非预期的命名空间中读取密钥。”
这种绕过的影响极为严重。如果攻击者能够读取特权命名空间中的密钥,他们就能轻松进一步提升权限并完全控制集群。报告指出:“未经授权访问密钥可能导致权限提升、数据泄露,或服务账号与凭据被窃取。”
管理员应立即审计其集群。该漏洞影响 External Secrets Operator 从 v0.20.2 到 v1.2.0 的所有版本
维护者采取了果断的修复方式:直接删除了该功能。“该函数已被完全移除,因为它能实现的所有功能都可以通过其他方式完成,同时不会破坏我们的安全防护机制。”
用户被敦促立即升级到 v1.2.0 版本,该版本通过删除问题代码彻底修复了漏洞。
对于暂时无法升级的用户,也有临时缓解方案。管理员可以使用 Kyverno、Kubewarden 或 OPA 等策略引擎来 “阻止在任何 ExternalSecret 资源中使用 getSecretKey 函数”。

一种高度复杂的新型恶意软件攻击正瞄准 macOS 用户,它将社会工程学技术隐蔽性结合得极为致命。这个名为 MacSync 的恶意软件被包装成 “恶意软件即服务”(MaaS),伪装成合法的云存储安装程序,诱骗用户亲手感染自己的设备,并专门窃取加密货币钱包和各类凭据。
该攻击在一次例行威胁狩猎中被发现,采用了 “ClickFix” 诱导手段 —— 即通过伪造错误提示,迫使受害者在终端中粘贴恶意命令来 “修复问题” 或完成安装。
感染通常从伪装成可信下载门户的网站开始。在一个被观察到的案例中,一个 “模仿 Microsoft 登录页面的域名” 将用户重定向到一个伪装成 “合法 macOS 云存储安装程序” 的站点。
与常规下载不同,该网站指示 “高级用户” 进行 “终端安装”。“页面强迫用户复制并粘贴一条具有欺骗性的终端命令。” 报告解释道。
这条看似无害的单行命令实际上会从远程服务器获取脚本,从而绕过 macOS 的安全机制,包括 Gatekeeper软件公证(notarization)。“通过诱使受害者自愿执行恶意 shell 命令,攻击者可以完全绕过 Gatekeeper、公证检查和签名验证。”
一旦进入系统,MacSync 不仅窃取数据,还会进行长期驻留。该恶意软件会 “有条件地植入(trojanize)受害者设备上广泛使用的基于 Electron 的加密货币应用”。
通过覆盖 Ledger Live 或 Trezor Suite 等应用的关键组件,恶意软件会将这些受信任的硬件钱包配套软件变成钓鱼工具。“这两类被植入的应用的主要目标,是呈现一个高度逼真的多步骤钓鱼向导,以窃取设备 PIN 和完整的助记词(recovery phrase)。”
受害者可能会在最初感染数周后看到一个看似友好的 “Something went wrong…” 提示,诱导他们重新输入助记词以 “修复问题”—— 从而交出其加密资产的全部控制权。
MacSync 在地下论坛上被当作一种 “经济实惠” 的恶意软件即服务出售。“由于价格低廉,MacSync 在低级别附属攻击者中迅速流行。”
尽管成本不高,其功能却相当先进。它会系统性地窃取 “浏览器凭据、加密货币钱包数据、钥匙串(Keychain)内容以及敏感文件”,对个人用户和企业组织都构成严重威胁。
报告最后发出警告:技术防御在社会工程学面前作用有限。“MacSync 证明,在 macOS 上,最危险的恶意软件不是利用零日漏洞的那种,而是利用信任的那种。”
最有效的防御仍然很简单:“永远不要将随机命令粘贴到终端中,无论它看起来多么‘官方’。”

一场针对万豪国际(Marriott International)和微软(Microsoft)用户的精密 “视觉相似字符” 钓鱼攻击正在蔓延。攻击者注册了一批将字母 “m” 替换为 “rn”(r + n)组合的恶意域名,搭建出与官方网站几乎一致的伪造页面。
这种技术被称为拼写欺诈(typosquatting)视觉相似字符攻击(homoglyph attack),其核心是利用现代字体的显示特性 —— 在多数字体中,字母 “r” 和 “n” 紧邻组合(rn)的视觉效果与字母 “m”(m)几乎无法区分。
黑客正是借助这一视觉欺诈,绕过人类大脑的错误识别机制。当你快速扫过 rnarriottinternational.com 这类 URL 时,大脑常会 “自动修正” 视觉信息,误判其为官方域名 “Marriott”。

已识别的近期攻击活动

万豪国际成为攻击目标

安全公司 Netcraft 近期监测到一批仿冒万豪集团的恶意域名集群,这些域名疑似被用于窃取会员账户凭证或宾客个人数据:
  • 核心恶意域名:rnarriottinternational.com
  • 衍生变体域名:rnarriotthotels.com(针对特定酒店品牌的定向攻击)

微软用户遭遇精准打击

安全公司 Anagram 的首席执行官哈利・舒格曼(Harley Sugarman)指出,另一波同类攻击正瞄准微软用户。钓鱼邮件通过域名 rnicrosoft.com 发送虚假安全警报或账单通知,具备三大欺诈特征:
  • 完全模仿微软官方 Logo、行文语气与页面布局;
  • 在移动设备上攻击风险极高 —— 小屏幕显示下,“rn” 与 “m” 的差异几乎无法察觉。

威胁指标(IOCs)

以下域名已被标记为恶意,安全团队应立即拦截,用户需警惕任何指向这些域名的链接:
钓鱼域名 仿冒服务 拼写欺诈手段 识别难度
rnarriottinternational.com 万豪国际(Marriott International) “m” 替换为 “rn” 极高(Critical)
rnarriotthotels.com 万豪酒店(Marriott Hotels) “m” 替换为 “rn” 极高(Critical)
rnicrosoft.com Microsoft 365 / 登录服务 “m” 替换为 “rn” 高(移动设备)
micros0ft.com 微软(Microsoft) “o” 替换为数字 “0” 中(Medium)
microsoft-support.com 微软支持(Microsoft Support) 添加连字符 / 后缀 低(Low)

安全防护建议

  1. 展开发件人地址:在移动邮件应用中,点击发件人名称查看完整邮箱地址,仔细甄别是否存在 “rn” 欺诈;
  2. 点击前悬浮验证:在电脑端,将鼠标悬浮于链接上方(不点击),查看浏览器底部显示的真实目标 URL;
  3. 手动输入官网:若收到酒店预订、账户重置等紧急邮件,切勿点击内嵌链接,直接打开浏览器手动输入 marriott.commicrosoft.com 访问官方网站;
  4. 启用密码管理器:密码管理器能识别虚假域名(如 rnicrosoft.com 与真实 microsoft.com 不一致),不会自动填充账号密码,从源头规避信息泄露风险。

Payload Website Template 是 Payload 官方提供的网站模板,适用于搭建从个人到企业级的各类网站、博客或作品集。
该模板内置功能完善的后端系统、企业级管理面板,以及一套设计精美、可直接用于生产环境的前端界面。
如果您计划开展以下项目,本模板将是一个理想选择:

  • 构建个人或企业官网、博客、作品集
  • 搭建具备完整发布流程的内容平台
  • 了解并体验 Payload CMS 的核心功能

图片

一、 部署Payload Website Template服务

环境准备

  • Payload Website GitHub:查看相关文档说明
  • 任何 JavaScript 包管理器(pnpm、npm 或 yarn - 推荐使用 pnpm)
  • Node.js 版本 20.9.0+
  • 任何兼容的数据库(MongoDB、Postgres 或 SQLite)

重要提示:在继续操作之前,请确保您已满足上述要求。

1. 准备数据库,首先,本案例采用Postgres数据库进行演示。
图片

2. 安装Postgres数据库成功之后,可以看到我们的数据库运行是正常的
图片

3. 我们接着打开 SQL Shell(psgl) 工具,并执行下面命令创建一个数据库
图片
my-project 后面会用到。
图片

4. 完成上述操作后,数据库准备工作就好了。5. 现在,我们打开CMD窗口,使用create-payload-app命令行界面将此payload模板直接克隆到您的计算机
图片

图片

6. 然后在选择数据库的时候,选择 PostgreSQL(您也可以选择其他的数据库,具体需要您自行摸索)

7. 接着在下方的地址里,把您PostgreSQL的密码输入替换掉原来的<password>8. 然后等待安装完成即可。
图片

9. 完成之后,可以看到上面提示我们进入到对应的目录,我们执行下面的命令
图片

图片

10. 接着,我们执行启动运行命令
图片

图片

注意:这里如果数据库名称没有配置正确,会提示报错,需要重新去创建一个名词的数据即可
图片

11. 访问服务服务启动后,可以通过浏览器访问以下地址:Web界面: http://..:*
图片

12. 点击 Visit the admin dashboard ,将进入配置初始化页面,然后创建您的账号密码
图片

13. 创建完成之后,即可进入到本地 Dashboard 服务页面了
图片

二、 创建 ZeroNews 映射服务

1. 首先,打开 ZeroNews 网站,然后选择您的系统(小编用的是用Win10,选择Windows即可),并按照对应的步骤和命令安装运行 Agent 服务。
注意:Agent 前台运行不能关闭命令窗口
如果您想要开机自启动,可以执行后台运行命令
图片

图片

图片

图片

2. 运行完成之后,您可以在 Agent 页面看到已经在线的 Agent 服务。
图片

3. 接着,我们在域名端口页面,创建一个可用的公网域名(自定义前缀),并勾选HTTPS 协议端口。
图片

4. 域名创建完成之后,我们继续打开映射页面,并按下面的步骤添加映射
a) Agent:选择第一步运行的 Agent
b) 映射协议:选择 HTTPS 协议
c) 域名:选择刚创建好的域名
d) 带宽:根据需要选择带宽大小
e) 内网IP:我们是本地部署,直接使用 127.0.0.1 即可
f) 内网端口:输入本地服务的端口 3000 即可
图片

5. 照上述步骤创建完成之后,我们就可以得到一条可公网访问的映射域名
图片

三、 公网访问您的Payload Website Template服务

1. 我们在任意有网络访问电脑的浏览器上,复制上面的链接并打开访问。
图片

2. 输入刚才本地创建的账号密码后登录
图片

3. 登录成功之后,即可进入管理页面
图片

不要侥幸,35 岁以上的程序员不好找工作, 这是一个既定事实

首先无论是什么渠道, 对于普通人来说 35+ 的程序员, 不好就业, 就是一个既定事实。 甚至都不一定与自己的工作经历、学历 有多大的关系。

甚至我知道很多 35+ 的老哥们, 经验丰富, 985 大学毕业, 依然不好找工作, 这个不是个例。

我们不过多探究为何 35+ 的程序员不好就业, 我们可能需要更多关注, 怎么在这种大背景下「绝地求生」

这些方向可以让 35+ 程序员依然抢手

“35 岁危机”并非绝对,大量 35 岁以上的程序员仍能保持职业竞争力,甚至更受青睐,核心在于是否具备“不可替代性”:


技术深度型:在某一细分领域(如底层架构、算法优化、安全攻防)有深耕,成为行业公认的技术专家。例如,专注于分布式系统设计、AI 大模型工程化的资深工程师,35 岁后反而因经验稀缺而抢手。


业务融合型:熟悉特定行业(如金融、医疗、制造业)的业务逻辑,能将技术与行业需求深度结合。例如,懂银行业务的支付系统架构师、懂医疗流程的医疗信息化专家,年龄增长带来的业务经验反而成为优势。


管理转型型:从技术岗转型为技术管理(如 CTO、技术总监、团队负责人),具备带团队、做决策、对接业务的能力。这类岗位更看重“经验沉淀”和“资源整合能力”,35-45 岁往往是黄金期。


技术管理型 - 有坑

首先看看「管理型」, 我感觉上面三个「绝地求生」方向, 管理方向, 反而是最不考虑的, 其实很简单, 现在大社会都是紧缩模式,只有出局的业务,没有新业务开展了。 那么这个时候, 就出现一个更加严重的问题, 「技术管理系」岗位, 一个萝卜一个坑, 甚至可以说, 你无论技术有多牛逼, 但是没有那个坑位, 可能永远都上不去。

甚至还有一个比较搞笑的现象,都是很多中小公司离开一线很久的技术 leader , 找不到坑位了, 再想着来投递技术岗, 技术上基本上生疏很久了, 基本上很难再就业。 这种人真不在少数。

深耕技术性 - 有利有弊

这个其实是一个非常好的方向, 但是这种人往往都是大头兵, 或者叫做高级工具人。 首先需要花非常多的时间和精力去做深耕技术, 要时刻保持最前沿的技术储备, 最充沛的精力, 最丰富的热情。然后要去干最累的活儿, 干最难的事儿, 但是不一定有好结果。 很简单, 这个业务线没了, 那也只能去找下一份工作。 而且大头兵, 很容易为业务背锅。

都是高级打工仔了, 做的好, 是应该的, 做的不好就得背锅。

而且还要想办法跟 AI 做差异性竞争。 很简单, 做了一个非常好的工作架构, 然后 AI 可以用非常低的成本做替代, 那就白干了。

上面说了那么多缺点, 这个方向就真的那么不堪吗?其实也不是, 只要努力, 肯吃苦, 至少下限还是很高的。 因为这个路子, 就跟上大学一样,你只要一直读书, 肯吃苦, 就能上到 博士 。 做深耕技术也是一样的, 只要肯努力, 耐得住寂寞, 一直死磕下去, 基本上在一个方向都能有几刷子的。 对于迷茫型和努力型同学,这个也是最佳直选。

所以有利有弊, 各位同学可自行斟酌。

业务融合型 - 性价比之王

技术的价值最终要落地到业务中,30 + 程序员若能将技术能力与具体行业的业务逻辑深度绑定,会比 “纯技术专家” 更难被替代 —— 因为年轻人可以快速学会技术,但吃透一个行业的业务规则(如金融风控逻辑、医疗流程规范、制造业供应链协同)往往需要 5 年以上的沉淀。

这个才是我真正想跟大家聊一聊的方向。

机-会

技术大厂,前端-后端-测试,全国均有机-会,感兴趣可以试试。待遇和稳定性都还不错~

精通技术的业务专家成长之路

“技术 + 业务” 复合岗,核心是 让技术能力成为 “解读业务、解决业务痛点” 的工具,而非终点。

这种转型的价值在于:业务逻辑的沉淀周期长(5-10 年),年轻人可快速学会技术,但难以短期吃透行业规则,这正是 30 + 程序员的经验红利。以下从 “有价值的业务方向”“业务理解训练方法”“避坑要点” 三个维度展开,附具体实操步骤:

一、值得深耕的“技术+业务”方向(附核心业务逻辑与技术结合点)

选择业务方向的关键标准:业务逻辑复杂(有门槛)、监管严格(需经验规避风险)、技术与业务深度绑定(技术优化能直接带来业务收益)。以下是几个高价值领域:

  1. 金融科技(银行/保险/证券)

核心业务逻辑:金融行业的本质是“风险定价+资金流转”,涉及复杂的监管规则(如央行反洗钱、银保监会合规要求)、用户分层(高净值客户vs大众客户)、业务流程(信贷审批、理赔核保、交易清算)。
技术结合点:


信贷领域:用AI模型优化风控(需理解“逾期率”“不良率”等业务指标,以及征信数据、行为数据如何影响授信);


交易领域:低延迟交易系统(需理解股票/期货的“撮合规则”“涨跌停限制”,技术优化直接影响交易成功率);


保险领域:智能核保系统(需理解“健康告知”“免责条款”等业务规则,技术需实现“用户输入→规则匹配→核保结论”的自动化)。

为什么值得做:金融监管政策每年更新(如2025年央行新规对“消费贷资金用途监控”的要求),技术方案必须跟着业务规则调整,经验越丰富越能快速响应,年轻人易因不懂合规踩坑。


  1. 医疗健康(医院信息化/互联网医疗)

核心业务逻辑:医疗行业的核心是“患者诊疗全流程”,涉及医院内部流程(挂号、分诊、问诊、检查、缴费、取药)、医保政策(医保目录、报销比例、异地结算规则)、医疗安全(病历隐私、药品溯源)。
技术结合点:


医院信息系统(HIS):需理解“门诊/住院流程”(如门诊的“医生开单→药房发药”环节,技术需对接收费系统、药品库存系统);


互联网医疗:在线问诊平台需符合《互联网诊疗管理办法》(如“首诊不能线上”“电子处方流转规则”),技术架构要支持“医患身份核验→问诊记录留存→处方合规性校验”;


医疗大数据:医疗影像AI辅助诊断(需理解“CT/MRI影像的临床意义”,技术模型训练需结合医生诊断逻辑,而非纯数据拟合)。

为什么值得做:医疗流程标准化程度低(不同医院流程差异大),且涉及生命安全,技术方案容错率极低,需要“技术+临床经验”双重积累,30+的耐心和细致更具优势。


  1. 智能制造(工业互联网/工厂数字化)

核心业务逻辑:制造业的核心是“生产效率提升+成本控制”,涉及生产流程(订单排产、物料采购、车间加工、质量检测、物流配送)、设备管理(设备故障率、OEE设备综合效率)、供应链协同(供应商交付周期、库存周转率)。

技术结合点:


工业物联网(IIoT):设备数据采集与分析(需理解“数控机床的主轴温度、转速与产品精度的关系”,技术需将数据转化为“设备维护预警”等业务动作);


MES系统(制造执行系统):生产排产优化(需理解“订单优先级、物料齐套率、设备产能”的制约关系,技术算法要平衡“交付时效”与“生产成本”);


质量追溯系统:需理解“产品不良品的产生环节”(如焊接工艺参数异常导致的缺陷),技术需实现“生产数据→不良原因”的反向追溯。

为什么值得做:制造业数字化转型依赖“懂生产的技术人”,纯技术人员易陷入“为数字化而数字化”(比如盲目上物联网设备却不会分析数据),而有车间经验的技术人员能精准定位痛点(如某环节停机1小时损失5万元,技术优化需优先解决)。


  1. 跨境电商(平台型/品牌型)

核心业务逻辑:跨境电商的核心是“跨区域供需匹配”,涉及海外市场规则(如亚马逊的A+页面规则、TikTok Shop的物流时效要求)、跨境链路(报关、清关、海外仓配送)、本地化运营(语言、支付习惯、合规要求,如欧盟增值税VAT)。

技术结合点:

选品系统:需理解“海外市场需求”(如东南亚雨季对雨具的需求波动),技术通过爬虫+数据分析预测“潜力商品”;
跨境ERP:需对接“多国物流商API”“海关报关系统”,技术需处理“汇率换算”“多语言订单”“合规申报”等业务细节;
本地化营销工具:如TikTok直播带货的“实时翻译+弹幕互动”功能,技术需结合“海外用户互动习惯”(如欧美用户更关注产品参数,东南亚用户更关注价格)。

为什么值得做:跨境业务涉及“多国家、多规则、多链路”,技术方案需灵活适配(比如某国突然调整进口关税,系统需快速支持税率更新),经验能减少试错成本,年轻人易因不了解海外规则导致系统“水土不服”。

二、训练“业务理解能力”的5个实操步骤(从0到1建立业务思维)

技术人员常陷入“只懂代码不懂业务”的误区,核心问题是:习惯用“技术实现”倒推“业务需求”,而非从“业务目标”推导“技术价值”。以下步骤帮你系统性建立业务思维:

步骤1:从“被动接需求”到“主动问目标”——搞懂“业务为什么需要这个功能”

具体做法:每次接需求时,多问3个问题:


    “这个功能要解决用户的什么痛点?”(如“用户反馈支付失败率高”,而非只接“开发新支付渠道”);
    “这个功能的业务指标是什么?”(如“支付成功率从90%提升到99%”,而非“完成开发即可”);
    “如果这个功能上线后不达预期,备选方案是什么?”(理解业务的优先级和容错空间)。


案例:若业务方提“开发一个优惠券系统”,技术人员不应直接设计表结构,而是先问:“发优惠券是为了拉新还是促活?目标是提升客单价10%还是复购率20%?预算多少?”——这些决定了系统是否需要支持“新用户专属券”“满减叠加规则”等细节。

步骤2:画“业务流程图”——用可视化方式梳理业务环节(比写代码更重要)

工具:Figma(画流程图)、Visio(复杂流程)、甚至手绘;
核心要素:每个流程节点包含“谁(角色)→做什么(动作)→输入/输出什么(信息)→遇到异常怎么办(分支)”;
案例:画“电商退款流程”时,需明确:

    角色:用户、客服、财务、仓库;
    动作:用户发起退款→客服审核(是否符合7天无理由)→财务确认退款金额→仓库确认是否收到退货→系统打款;
    异常分支:“用户已拆封商品”是否支持退款?“仓库未收到货但用户说已寄出”如何处理?


价值:流程图能帮你发现“技术设计的盲区”(如漏考虑“退款失败后重试机制”),也能让你在和业务方沟通时“用他们的语言对话”(而非只说“接口、数据库”)。

步骤3:“泡在业务场景里”——亲身体验业务,而非只听业务方描述

具体做法:


    若做电商:自己下单、退货、咨询客服,记录每个环节的体验(如“退款到账时间长”可能是技术链路太长);
    若做医疗系统:去医院门诊“蹲点”,看医生如何开单、护士如何分诊、患者如何缴费(你会发现“医生开单时频繁切换系统”是真实痛点,技术可做集成优化);
    若做金融:假扮客户打电话给银行客服,咨询“信用卡逾期如何处理”(理解业务方常说的“催收流程”实际是怎样的)。


关键:技术人员容易“坐在办公室想当然”,而业务的真相往往藏在一线操作中。比如某团队开发“外卖骑手App”时,程序员亲自骑了3天车,才发现“高峰期导航频繁卡顿”是比“界面美观”更重要的问题。

步骤4:建立“业务知识体系”——像学技术一样系统化学习业务

方法:


    行业基础术语库:整理业务常用词(如金融的“拨备率”“LPR”,医疗的“DRG/DIP”“电子病历互联互通”),每个词注明“定义+业务意义”(如“DRG”是“按疾病诊断分组付费”,影响医院的收费和成本控制);
    监管规则清单:收集行业相关政策(如跨境电商的《跨境电子商务零售进口商品清单》,金融的《个人信息保护法》对数据采集的要求),标注“哪些规则会影响技术方案”(如数据本地化存储要求决定服务器部署位置);
    业务指标公式:搞懂核心KPI的计算逻辑(如“电商GMV=流量×转化率×客单价”,“银行不良率=不良贷款余额/总贷款余额”),理解技术优化如何影响这些指标(如“页面加载速度提升1秒→转化率提升2%→GMV增加X万元”)。


工具:用Notion或Excel整理,定期更新(如政策变动时),避免“业务术语听不懂”的尴尬。

步骤5:输出“业务-技术关联报告”——证明你能“用技术解决业务问题”

核心动作:每完成一个项目,写一份“技术方案如何支撑业务目标”的报告,包含:


    业务背景:项目要解决什么业务痛点(如“工厂因排产不合理,订单交付延迟率达15%”);
    技术方案:用了什么技术(如APS高级排产算法),为什么选这个技术(对比其他方案,该算法在“多品种小批量”场景下更优);
    业务效果:技术上线后,业务指标有何变化(如“交付延迟率从15%降至5%,每月减少违约金100万元”);
    经验沉淀:如果再遇到类似业务问题,技术方案可复用哪些部分(如“排产算法可适配其他工厂的生产模式”)。


价值:这份报告不仅是你“业务+技术”能力的证明(跳槽时可作为案例),更能倒逼你在项目中主动思考“技术的业务价值”,而非只关注“代码写得漂不漂亮”。

三、转型避坑:这3个误区会让你“既不像技术,也不像业务”


误区1:放弃技术深度,单纯“转业务”
复合岗的核心是“技术为根,业务为翼”,而非变成纯业务岗。比如做金融科技,若不懂分布式系统,就无法设计高并发的交易系统;若不懂AI,就无法优化风控模型。保留技术深度,同时叠加业务理解,才是不可替代的关键。


误区2:只学“表面业务”,不懂“业务本质”
比如做电商,知道“优惠券能促单”是表面,理解“不同面额的优惠券对不同客群(新用户vs老用户)的转化差异”才是本质;做医疗,知道“电子病历要存数据”是表面,理解“病历数据如何支持医生诊断决策”才是本质。多问“为什么”,穿透业务动作看目标。


误区3:等待“别人教业务”,而非主动获取
业务方通常很忙,不会系统性教你业务知识。要主动“找信息”:看行业报告(艾瑞、易观)、读专业书籍(如《支付战争》懂支付业务,《精益生产》懂制造流程)、加行业社群(如医疗信息化的“HIT专家网”)、甚至考行业证书(如PMP学项目管理,CFA基础懂金融)。




——转载自:晴小篆