在ubuntu下一键安装 Open WebUI

news2025/1/30 16:27:12

该脚本用于自动化安装 Open WebUI,并支持以下功能:

可选跳过 Ollama 安装:通过 --no-ollama 参数跳过 Ollama 的安装。

自动清理旧目录:如果安装目录 (~/open-webui) 已存在,脚本会自动删除旧目录并重新安装。

完整的依赖安装:包括 Python、Node.js、npm、Git 等依赖的安装。

自动配置系统服务:将 Open WebUI 配置为系统服务,并设置开机自启。

防火墙配置:自动开放端口 8080,以便访问 Open WebUI。

更新后的脚本:
bash
复制


#!/bin/bash

# 遇到错误时退出脚本
set -e

# 检查并设置 Conda
setup_conda() {
    # 如果 conda 命令不可用,但目录存在
    if [ -d "$HOME/miniconda" ]; then
        echo "检测到已存在的 Miniconda 安装,正在配置..."
        # 添加到 PATH
        export PATH="$HOME/miniconda/bin:$PATH"
        
        # 初始化 bash 和 conda
        if [ ! -f "$HOME/.bashrc" ] || ! grep -q "conda initialize" "$HOME/.bashrc"; then
            "$HOME/miniconda/bin/conda" init bash
            source "$HOME/.bashrc"
        fi
    else
        echo "正在安装 Miniconda..."
        # 下载 Miniconda 安装脚本
        wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
        # 安装 Miniconda
        bash miniconda.sh -b -p "$HOME/miniconda"
        
        # 初始化 bash 和 conda
        export PATH="$HOME/miniconda/bin:$PATH"
        "$HOME/miniconda/bin/conda" init bash
        source "$HOME/.bashrc"
    fi
}

# 生成随机密钥的函数
generate_secret_key() {
    python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
}

# 显示脚本用法
usage() {
    echo "用法: $0 [--no-ollama] [--no-download]"
    echo "  --no-ollama: 跳过 Ollama 安装"
    echo "  --no-download: 跳过下载 Open WebUI 代码(如果已经下载)"
    exit 1
}

# 解析参数
SKIP_OLLAMA=false
SKIP_DOWNLOAD=false
while [[ $# -gt 0 ]]; do
    case "$1" in
        --no-ollama)
            SKIP_OLLAMA=true
            shift
            ;;
        --no-download)
            SKIP_DOWNLOAD=true
            shift
            ;;
        *)
            usage
            ;;
    esac
done

# 检查 sudo 权限
check_sudo() {
    if ! sudo -n true 2>/dev/null; then
        echo "需要 sudo 权限来安装系统依赖。"
        echo "请确保你有 sudo 权限,或者以 root 用户运行此脚本。"
        exit 1
    fi
}

echo "开始安装 Open WebUI..."

# 检查 sudo 权限
check_sudo

# 更新系统包
echo "更新系统包..."
if command -v apt-get &> /dev/null; then
    sudo -n apt-get update
    sudo -n apt-get upgrade -y
fi

# 安装基本依赖
echo "安装基本依赖..."
sudo -n apt-get install -y python3 python3-pip git curl python3-venv build-essential || { echo "安装依赖失败"; exit 1; }

# 安装 Node.js
echo "安装 Node.js..."
if ! command -v node &> /dev/null; then
    echo "安装 Node.js 20 LTS..."
    # 添加 NodeSource 仓库
    if [ ! -f "/etc/apt/sources.list.d/nodesource.list" ]; then
        echo "添加 NodeSource 仓库..."
        curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo -n gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
        echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | sudo -n tee /etc/apt/sources.list.d/nodesource.list
        sudo -n apt-get update
    fi
    
    # 安装 Node.js
    sudo -n apt-get install -y nodejs

    # 验证安装
    if ! command -v node &> /dev/null; then
        echo "Node.js 安装失败"
        exit 1
    fi
fi

# 显示 Node.js 版本
echo "Node.js 版本:"
node --version
echo "npm 版本:"
npm --version

# 安装 Ollama(如果不跳过)
if [[ "$SKIP_OLLAMA" = false ]]; then
    echo "安装 Ollama..."
    curl -fsSL https://ollama.com/install.sh | sh || { echo "Ollama 安装失败"; exit 1; }
    sudo systemctl enable ollama
    sudo systemctl start ollama
else
    echo "跳过 Ollama 安装。"
fi

# 检查 CUDA 环境
check_cuda() {
    echo "检查 CUDA 环境..."
    if ! command -v nvidia-smi &> /dev/null; then
        echo "警告: 未检测到 NVIDIA GPU 驱动"
        return 1
    else
        echo "GPU 信息:"
        nvidia-smi --query-gpu=gpu_name,driver_version,memory.total,memory.free,memory.used,temperature.gpu --format=csv,noheader
        return 0
    fi
}

# 设置 CUDA 环境
setup_cuda() {
    # 检查 CUDA 是否已安装
    if [ -d "/usr/local/cuda-11.4" ]; then
        echo "CUDA 11.4 已安装在 /usr/local/cuda-11.4"
        # 设置环境变量
        if ! grep -q "export PATH=/usr/local/cuda-11.4/bin" ~/.bashrc; then
            echo 'export PATH=/usr/local/cuda-11.4/bin:$PATH' >> ~/.bashrc
        fi
        if ! grep -q "export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64" ~/.bashrc; then
            echo 'export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
        fi
        source ~/.bashrc
        return 0
    # 如果没有安装且没有 nvcc 命令
    elif ! command -v nvcc &> /dev/null; then
        echo "未检测到 CUDA toolkit,正在安装..."
        # 检查安装文件是否已存在
        CUDA_INSTALLER="cuda_11.4.4_470.82.01_linux.run"
        if [ ! -f "$CUDA_INSTALLER" ]; then
            echo "下载 CUDA 11.4 安装包..."
            wget https://developer.download.nvidia.com/compute/cuda/11.4.4/local_installers/$CUDA_INSTALLER
        else
            echo "CUDA 安装包已存在,跳过下载..."
        fi
        
        echo "安装 CUDA toolkit..."
        sudo sh $CUDA_INSTALLER --toolkit --silent --override
        
        # 设置环境变量
        if ! grep -q "export PATH=/usr/local/cuda-11.4/bin" ~/.bashrc; then
            echo 'export PATH=/usr/local/cuda-11.4/bin:$PATH' >> ~/.bashrc
        fi
        if ! grep -q "export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64" ~/.bashrc; then
            echo 'export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
        fi
        source ~/.bashrc
        return 0
    fi
    return 1
}

# 检查 GPU 和设置 CUDA
if check_cuda; then
    echo "检测到 GPU,设置 CUDA 环境..."
    setup_cuda
    # 设置 GPU 相关环境变量
    export NODE_ONNX_RUNTIME_GPU=1
    export CUDA_VISIBLE_DEVICES=0
    # 显示 CUDA 版本
    echo "CUDA 版本: $(nvidia-smi | grep "CUDA Version" | awk '{print $9}')"
    
    # 下载 GPU 版本的 onnxruntime
    echo "下载 onnxruntime GPU 版本..."
    mkdir -p node_modules/onnxruntime-node/bin/napi-v3/linux/x64
    cd node_modules/onnxruntime-node/bin/napi-v3/linux/x64
    
    # 尝试多个下载源
    download_file() {
        local urls=(
            "https://mirror.ghproxy.com/https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz"
            "https://hub.fastgit.xyz/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz"
            "https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz"
        )
        
        for url in "${urls[@]}"; do
            echo "尝试从 $url 下载..."
            wget --no-check-certificate \
                 --timeout=15 \
                 --tries=3 \
                 --continue \
                 --inet4-only \
                 -q --show-progress \
                 "$url" && return 0
            echo "从 $url 下载失败,尝试下一个源..."
        done
        return 1
    }
    
    if ! download_file; then
        echo "GPU 版本下载失败,切换到 CPU 模式..."
        export NODE_ONNX_RUNTIME_GPU=0
    else
        echo "解压 GPU 版本文件..."
        tar xzf onnxruntime-linux-x64-gpu-1.20.1.tgz
    fi
    cd -
else
    echo "未检测到 GPU,将使用 CPU 模式..."
    export NODE_ONNX_RUNTIME_GPU=0
    
    # 下载 CPU 版本的 onnxruntime
    echo "下载 onnxruntime CPU 版本..."
    mkdir -p node_modules/onnxruntime-node/bin/napi-v3/linux/x64
    cd node_modules/onnxruntime-node/bin/napi-v3/linux/x64
    
    wget --no-check-certificate \
         --timeout=15 \
         --tries=3 \
         --continue \
         --inet4-only \
         -q --show-progress \
         "https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-1.20.1.tgz"
    
    if [ $? -eq 0 ]; then
        echo "解压 CPU 版本文件..."
        tar xzf onnxruntime-linux-x64-1.20.1.tgz
    else
        echo "警告: onnxruntime CPU 版本下载失败"
    fi
    cd -
fi

# 临时设置环境变量
if [ -d "/usr/local/cuda-11.4" ]; then
    export PATH=/usr/local/cuda-11.4/bin:$PATH
    export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH
fi

# 检查是否已经在虚拟环境中
if [ -z "$VIRTUAL_ENV" ]; then
    # 如果不在虚拟环境中,则检查并设置 Conda
    if ! command -v conda &> /dev/null; then
        echo "Conda 未安装或不在 PATH 中,正在设置..."
        setup_conda
    fi

    # 再次检查 conda 是否可用
    if ! command -v conda &> /dev/null; then
        echo "Conda 安装失败,请手动安装 Conda 后重试"
        exit 1
    fi

    # 确保 conda 命令可用
    source "$HOME/.bashrc"
    eval "$(conda shell.bash hook)"

    # 检查并删除已存在的环境
    if conda env list | grep -q "^open-webui "; then
        echo "删除已存在的 open-webui 环境..."
        conda deactivate
        conda env remove -n open-webui -y
    fi

    # 创建并激活 Python 3.11 环境
    echo "创建 Python 3.11 环境..."
    conda create -y -n open-webui python=3.11
    source activate open-webui || conda activate open-webui
else
    echo "检测到已存在的虚拟环境: $VIRTUAL_ENV"
    echo "跳过创建新环境..."
fi

# 验证 Python 环境
echo "验证 Python 环境..."
which python
python --version

# 创建安装目录
echo "设置 Open WebUI 安装目录..."
INSTALL_DIR="/opt/open-webui"
mkdir -p "$INSTALL_DIR"

# 下载或更新 Open WebUI
if [[ "$SKIP_DOWNLOAD" = false ]]; then
    echo "下载 Open WebUI..."
    if [ -d "$INSTALL_DIR/open-webui" ]; then
        echo "更新 Open WebUI..."
        cd "$INSTALL_DIR/open-webui"
        git pull
    else
        echo "克隆 Open WebUI..."
        cd "$INSTALL_DIR"
        git clone https://github.com/open-webui/open-webui.git
    fi
else
    echo "跳过下载 Open WebUI..."
    if [ ! -d "$INSTALL_DIR/open-webui" ]; then
        echo "错误:Open WebUI 目录不存在于 $INSTALL_DIR/open-webui"
        echo "请确保目录存在或移除 --no-download 选项"
        exit 1
    fi
fi

# 设置权限
echo "设置目录权限..."
sudo -n chown -R $USER:$USER "$INSTALL_DIR"

# 进入项目目录
cd "$INSTALL_DIR/open-webui"

# 安装系统依赖
echo "安装系统依赖..."
if command -v apt-get &> /dev/null; then
    sudo -n apt-get update
    sudo -n apt-get install -y ffmpeg
elif command -v yum &> /dev/null; then
    sudo -n yum install -y ffmpeg
elif command -v pacman &> /dev/null; then
    sudo -n pacman -S --noconfirm ffmpeg
elif command -v apk &> /dev/null; then
    sudo -n apk add --no-cache ffmpeg
else
    echo "警告: 无法识别的包管理器,请手动安装 ffmpeg"
fi

# 构建前端
echo "构建前端..."
cd /opt/open-webui/open-webui

echo "清理旧的构建文件..."
rm -rf node_modules package-lock.json

echo "配置 npm..."
npm config set registry https://registry.npmmirror.com
npm config set fetch-retries 5
npm config set fetch-timeout 60000
npm config set progress true
npm config set loglevel info

echo "安装前端依赖..."
# 使用 pnpm 或 npm 安装依赖
if command -v pnpm &> /dev/null; then
    echo "使用 pnpm 安装依赖..."
    # 配置 pnpm 使用淘宝镜像
    pnpm config set registry https://registry.npmmirror.com
    pnpm install --reporter=default
else
    echo "使用 npm 安装依赖..."
    npm install --verbose
fi

# 构建前端
echo "构建前端..."
if command -v pnpm &> /dev/null; then
    pnpm run build --reporter=default
else
    npm run build --verbose
fi

# 检查构建结果
if [ -d "build" ]; then
    echo "前端构建成功!"
else
    echo "前端构建失败,请检查错误信息"
    exit 1
fi

# 初始化数据库
echo "初始化数据库..."
cd backend
export PYTHONPATH=/opt/open-webui/open-webui/backend

# 运行数据库迁移
echo "运行数据库迁移..."
if [ -f "open_webui/alembic.ini" ]; then
    cd open_webui
    echo "当前目录: $(pwd)"
    echo "运行迁移..."
    alembic upgrade head
    cd ..
else
    echo "在以下位置搜索 alembic.ini:"
    find . -name "alembic.ini" -type f
    echo "错误: 找不到 alembic.ini"
    exit 1
fi

# 确保 .webui_secret_key 存在
if [ ! -f ".webui_secret_key" ]; then
    echo "生成 secret key..."
    head -c 12 /dev/random | base64 > .webui_secret_key
fi

# 设置环境变量
export WEBUI_SECRET_KEY=$(cat .webui_secret_key)
export PORT=8111
export HOST=0.0.0.0

# 启动服务
if command -v gunicorn &> /dev/null; then
    echo "使用 gunicorn 启动..."
    gunicorn -w 1 -k uvicorn.workers.UvicornWorker "open_webui.main:app" \
        --bind 0.0.0.0:8111 \
        --timeout 300 \
        --log-level debug \
        --error-logfile - \
        --capture-output &
    
    # 保存进程 ID
    GUNICORN_PID=$!
    echo "Gunicorn PID: $GUNICORN_PID"
else
    echo "使用 uvicorn 启动..."
    python -m uvicorn "open_webui.main:app" \
        --host 0.0.0.0 \
        --port 8111 \
        --log-level debug &
    
    # 保存进程 ID
    UVICORN_PID=$!
    echo "Uvicorn PID: $UVICORN_PID"
fi

# 等待后端启动
echo "等待服务启动..."
for i in {1..30}; do
    if curl -s http://localhost:8111/health > /dev/null; then
        echo "服务已启动成功!"
        echo "请访问 http://localhost:8111"
        break
    fi
    
    # 检查进程是否还在运行
    if [ ! -z "$GUNICORN_PID" ] && ! ps -p $GUNICORN_PID > /dev/null; then
        echo "错误: Gunicorn 进程已退出"
        break
    fi
    if [ ! -z "$UVICORN_PID" ] && ! ps -p $UVICORN_PID > /dev/null; then
        echo "错误: Uvicorn 进程已退出"
        break
    fi
    
    echo "尝试 $i/30..."
    sleep 1
done

# 如果服务没有启动,显示调试信息
if ! curl -s http://localhost:8111/health > /dev/null; then
    echo "服务启动失败,显示调试信息:"
    echo "Python 路径: $PYTHONPATH"
    echo "当前目录: $(pwd)"
    echo "Python 版本: $(python --version)"
    echo "已安装的包:"
    pip list
    echo "目录内容:"
    ls -la
    echo "open_webui 目录内容:"
    ls -la open_webui/
    echo "进程状态:"
    ps aux | grep -E "gunicorn|uvicorn"
    echo "端口状态:"
    netstat -tuln | grep 8111
    echo "日志内容:"
    tail -n 50 /var/log/syslog | grep -E "gunicorn|uvicorn|open_webui"
fi

# 创建系统服务
echo "创建系统服务..."
sudo tee /etc/systemd/system/open-webui-backend.service << EOL
[Unit]
Description=Open WebUI Backend
After=network.target

[Service]
Type=simple
User=$USER
WorkingDirectory=/opt/open-webui/open-webui/backend
ExecStart=/opt/open-webui/open-webui/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8111
Environment="PATH=/opt/open-webui/open-webui/venv/bin"
Restart=on-failure
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=open-webui-backend

[Install]
WantedBy=multi-user.target
EOL

# 启动并启用服务
echo "启动 Open WebUI 服务..."
sudo systemctl daemon-reload
sudo systemctl enable open-webui-backend
sudo systemctl start open-webui-backend

# 配置防火墙
echo "配置防火墙..."
sudo ufw allow 8111/tcp

echo "安装成功完成!"
echo "您现在可以通过 http://localhost:8111 访问 Open WebUI。"
echo "首次访问时,请创建一个管理员账户。"

使用方法:

将脚本保存为文件,例如 install_open_webui.sh。

赋予脚本执行权限:
bash
复制

chmod +x install_open_webui.sh

运行脚本:

    默认安装(包含 Ollama):
    bash
    复制

    ./install_open_webui.sh

    跳过 Ollama 安装:
    bash
    复制

    ./install_open_webui.sh --no-ollama

注意事项:

确保您具有 sudo 权限来运行脚本。

如果安装失败,可以通过以下命令查看服务日志:
bash
复制

sudo journalctl -u open-webui-backend

如果前端构建失败,请确保已正确安装 nodejs 和 npm,然后手动运行以下命令:
bash
复制

npm install
npm run build

如果有其他问题,欢迎随时提问!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2284336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读 AlphaFold 2

用AlphaFold进行非常精确的蛋白质结构的预测(AlphaFold2) 发表于2021年07月15日 NatureDOI: 10.1038/s41586-021-03819-2自然和科学杂志评选为2021年最重要的科学突破之一2021年AI在科学界最大的突破 前言 2020年11月30号, deepmind博客说AlphaFold解决了50年以来生物学的大挑…

计算机网络 (62)移动通信的展望

一、技术发展趋势 6G技术的崛起 内生智能&#xff1a;6G将强调自适应网络架构&#xff0c;通过AI驱动的智能算法提升通信能力。例如&#xff0c;基于生成式AI的6G内生智能架构将成为重要研究方向&#xff0c;实现低延迟、高效率的智能通信。信息编码与调制技术&#xff1a;新型…

探索与创新:DeepSeek R1与Ollama在深度研究中的应用

在当今信息爆炸的时代&#xff0c;获取和处理信息的能力变得至关重要。特别是在学术和研究领域&#xff0c;如何有效地进行深度研究是一个亟待解决的问题。最近&#xff0c;一个名为DeepSeek R1的模型结合Ollama平台提供了一种创新的解决方案。本文将分析并解构这一新兴的研究工…

mantisbt添加修改用户密码

文章目录 问题当前版本安装流程创建用户修改密码老的方式探索阶段 问题 不太好改密码啊。貌似必须要域名要发邮件。公司太穷&#xff0c;看不见的东西不关心&#xff0c;只能改源码了。 当前版本 当前mantisbt版本 2.27 php版本 7.4.3 安装流程 &#xff08;下面流程不是…

记录 | Docker的windows版安装

目录 前言一、1.1 打开“启用或关闭Windows功能”1.2 安装“WSL”方式1&#xff1a;命令行下载方式2&#xff1a;离线包下载 二、Docker Desktop更新时间 前言 参考文章&#xff1a;Windows Subsystem for Linux——解决WSL更新速度慢的方案 参考视频&#xff1a;一个视频解决D…

【Elasticsearch】内置分词器和IK分词器

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

2025美赛数学建模C题:奥运金牌榜,完整论文代码模型目前已经更新

2025美赛数学建模C题&#xff1a;奥运金牌榜&#xff0c;完整论文代码模型目前已经更新&#xff0c;获取见文末名片

HarmonyOS:ForEach:循环渲染

一、前言 ForEach接口基于数组类型数据来进行循环渲染&#xff0c;需要与容器组件配合使用&#xff0c;且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如&#xff0c;ListItem组件要求ForEach的父容器组件必须为List组件。 API参数说明见&#xff1a;ForEa…

C++ STL:深入探索常见容器

你好呀&#xff0c;欢迎来到 Dong雨 的技术小栈 &#x1f331; 在这里&#xff0c;我们一同探索代码的奥秘&#xff0c;感受技术的魅力 ✨。 &#x1f449; 我的小世界&#xff1a;Dong雨 &#x1f4cc; 分享我的学习旅程 &#x1f6e0;️ 提供贴心的实用工具 &#x1f4a1; 记…

Java面试题2025-设计模式

1.说一下开发中需要遵守的设计原则&#xff1f; 设计模式中主要有六大设计原则&#xff0c;简称为SOLID &#xff0c;是由于各个原则的首字母简称合并的来(两个L算一个,solid 稳定的)&#xff0c;六大设计原则分别如下&#xff1a; 1、单一职责原则 单一职责原则的定义描述非…

flink StreamGraph解析

Flink程序有三部分operation组成&#xff0c;分别是源source、转换transformation、目的地sink。这三部分构成DAG。 DAG首先生成的是StreamGraph。 用户代码在添加operation的时候会在env中缓存&#xff08;变量transformations&#xff09;&#xff0c;在env.execute()执行的…

基于SpringBoot的网上摄影工作室开发与实现 | 含论文、任务书、选题表

随着互联网技术的不断发展&#xff0c;摄影爱好者们越来越需要一个在线平台来展示和分享他们的作品。基于SpringBoot的网上摄影工作室应运而生&#xff0c;它不仅为用户提供了一个展示摄影作品的平台&#xff0c;还为管理员提供了便捷的管理工具。本文幽络源将详细介绍该系统的…

数字人+展厅应用方案:开启全新沉浸式游览体验

随着人们生活质量的不断提升&#xff0c;对于美好体验的追求日益增长。在展厅展馆领域&#xff0c;传统的展示方式已难以满足大众日益多样化的需求。而通过将数字人与展厅进行深度结合&#xff0c;可以打造数字化、智能化新型展厅&#xff0c;不仅能提升展示效果&#xff0c;还…

基于单片机的家用无线火灾报警系统的设计

1 总体设计 本设计家用无线火灾报警系统利用单片机控制技术、传感器检测技术、GSM通信技术展开设计&#xff0c;如图2.1所示为本次系统设计的主体框图&#xff0c;系统包括单片机主控模块、温度检测模块、烟雾检测模块、按键模块、GSM通信模块、液晶显示模块、蜂鸣器报警模块。…

多级缓存(亿级并发解决方案)

多级缓存&#xff08;亿级流量&#xff08;并发&#xff09;的缓存方案&#xff09; 传统缓存的问题 传统缓存是请求到达tomcat后&#xff0c;先查询redis&#xff0c;如果未命中则查询数据库&#xff0c;问题如下&#xff1a; &#xff08;1&#xff09;请求要经过tomcat处…

iic、spi以及uart

何为总线&#xff1f; 连接多个部件的信息传输线&#xff0c;是部件共享的传输介质 总线的作用&#xff1f; 实现数据传输&#xff0c;即模块之间的通信 总线如何分类&#xff1f; 根据总线连接的外设属于内部外设还是外部外设将总线可以分为片内总线和片外总线 可分为数…

Shell编程(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)

本篇文章继续给大家介绍Shell编程&#xff0c;包括for循环、并发问题&#xff0c;while循环&#xff0c;流程控制语句&#xff0c;函数传参、函数变量、函数返回值&#xff0c;反向破解MD5等内容。 1.for循环 for 变量 in [取值列表] 取值列表可以是数字 字符串 变量 序列…

深入 Rollup:从入门到精通(三)Rollup CLI命令行实战

准备阶段&#xff1a;初始化项目 初始化项目&#xff0c;这里使用的是pnpm&#xff0c;也可以使用yarn或者npm # npm npm init -y # yarn yarn init -y # pnpm pnpm init安装rollup # npm npm install rollup -D # yarn yarn add rollup -D # pnpm pnpm install rollup -D在…

CycleGAN模型解读(附源码+论文)

CycleGAN 论文链接&#xff1a;Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks 官方链接&#xff1a;pytorch-CycleGAN-and-pix2pix 老规矩&#xff0c;先看看效果 总体流程 先简单过一遍流程&#xff0c;细节在代码里说。CycleGAN有…

线程配置经验

工作时&#xff0c;时常会遇到&#xff0c;线程相关的问题与解法&#xff0c;本人会持续对开发过程中遇到的关于线程相关的问题及解决记录更新记录在此篇博客中。 目录 一、线程基本知识 1. 线程和进程 二、问题与解法 1. 避免乘法级别数量线程并行 1&#xff09;使用线程池…