求教关于wsl提速问题

AI摘要
【知识分享】用户分享在WSL2环境下提升PhpStorm和Fork客户端文件访问速度的两种技术方案:一是尝试通过WinBtrfs挂载ext4.vhdx文件实现跨系统高速访问(未成功配置),二是详细提供了通过Samba配置SMB共享的完整脚本与优化参数,包括网络设置、权限调整和Windows端自动IP映射脚本,以替代默认的\wsl$路径,实测能显著改善Git操作和IDE索引加载性能。

目前是win10+docker的环境下开发的,因为项目响应很慢的原因,将项目迁移到wsl里面了,响应速度确实提速明显
但出现了另一个问题,phpStorm通过\wsl$ 路径的方式打开项目有时会有点卡没有之前项目放在win下那么丝滑了,另一个问题是我一直用fork客户端提交Git等操作,现在fork也很卡,切分支、推拉代码等操作都很慢
想问问有没有可以有效提高phpStorm和fork的速度的方法

最近两天没事又研究了下,问了问deepseek,他跟我推荐了WinBtrfs的方式,大致意思是可以将wsl的ext4.vhdx文件通过WinBtrfs直接挂到Win磁盘上,这样操作后相当于wsl内部和win上访问时都能体验到本地磁盘的速度,但我搞了半天没配置上,ext4.vhdx挂到磁盘后win一直不识别,如果有其他大佬想体验极致速度的可以研究研究。

另一个方式是可以通过SMB协议的方式提高文件访问速度,具体比9P协议下速度能快多少我没有详细测,不过我自身使用fork客户端时确实明显比默认的\wsl$路径的方式快多了,Phpstorm使用时 第一次加载索引会很慢,加载完后下次再打开速度会快很多。

下面是配置SMB的方式,有兴趣的话可以体验下看看

  • 复制下面的脚本代码保存到wsl内然后运行,脚本会自动安装Samba并设置目录和用户权限,因为我用的是laradock集成的docker容器,所以里面会有涉及到laradock用户和组的操作,可以根据自己需要修改脚本内涉及到权限、用户、项目目录等。

    #!/bin/bash
    # wsl_samba_fixed_install.sh
    # 在WSL终端中运行
    echo "=========================================="
    echo "    WSL2 Samba 极致性能安装"
    echo "=========================================="
    echo
    # 检查是否以root运行
    if [ "$EUID" -ne 0 ]; then 
      echo "请使用 sudo 运行此脚本"
      echo "示例: sudo bash wsl_samba_fixed_install.sh"
      exit 1
    fi
    echo "laradock用户信息:"
    id laradock
    echo
    USERNAME=$(whoami)
    DockerUSERNAME=laradock
    # 确保目录结构存在
    echo "创建目录结构..."
    sudo mkdir -p /home/projects
    sudo mkdir -p /home/projects/PhpProjects
    # 设置 /home/projects 为当前用户(保持灵活)
    sudo chown $USERNAME:$USERNAME /home/projects
    sudo chmod 755 /home/projects
    # 设置 /home/projects/PhpProjects 为 laradock
    sudo chown -R $DockerUSERNAME:$DockerUSERNAME /home/projects/PhpProject
    sudo chmod -R 775 /home/projects/PhpProject
    # 记录开始时间
    START_TIME=$(date +%s)
    echo "[1/8] 更新系统并安装Samba..."
    apt update && apt upgrade -y
    apt install -y samba samba-common cifs-utils smbclient
    echo "[2/8] 备份原配置文件..."
    cp /etc/samba/smb.conf /etc/samba/smb.conf.backup.$(date +%Y%m%d)
    echo "[3/8] 创建极致性能配置..."
    cat > /etc/samba/smb.conf << EOF
    # ==========================================
    # WSL2 Samba 极致性能配置
    # 生成时间: $(date)
    # ==========================================
    [global]
     # 基础设置
     workgroup = WORKGROUP
     netbios name = WSL2
     server string = WSL2 Development Server
     server role = standalone server
     interfaces = lo lo eth0 0.0.0.0
     bind interfaces only = yes
    
     # 日志设置
     log level = 1
     log file = /var/log/samba/log.%m
     max log size = 50
     debug timestamp = yes
    
     # 性能优化 - 网络层
     socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=8388608 SO_SNDBUF=8388608
     max xmit = 65536
     dead time = 15
     getwd cache = yes
     large readwrite = yes
    
     # 性能优化 - 文件操作
     use sendfile = yes
     min receivefile size = 16384
     aio read size = 16384
     aio write size = 16384
     read raw = yes
     write raw = yes
     strict sync = no
     sync always = no
     use mmap = yes
     fake directory create times = yes
    
     # SMB3优化
     server multi channel support = yes
     smb2 max read = 16777216
     smb2 max write = 16777216
     smb2 max trans = 16777216
     smb2 max credits = 8192
     max protocol = SMB3_11
    
     # 内存和缓存
     cache directory = /var/cache/samba
     case sensitive = yes
     default case = lower
     preserve case = yes
     short preserve case = yes
    
     # 安全设置(开发环境简化)
     map to guest = Bad User
     guest account = nobody
     security = user
     encrypt passwords = yes
     unix extensions = no
     restrict anonymous = 0
    
     # 禁用不需要的功能
     printing = bsd
     printcap name = /dev/null
     disable spoolss = yes
     show add printer wizard = no
     dns proxy = no
     wins support = no
    # ========== 主共享:Home目录 ==========
    [home]
     comment = WSL Home Directory
     path = /home
     browseable = yes
     writable = yes
     guest ok = yes
     read only = no
     create mask = 0775
     directory mask = 0775
     force create mode = 0775
     force directory mode = 0775
     hide dot files = no
     hide special files = no
     veto files = /.git/
     delete veto files = yes
     follow symlinks = yes
     wide links = yes
    
     # 共享级性能优化
     strict locking = no
     kernel oplocks = yes
     level2 oplocks = yes
     oplocks = yes
     locking = no
     blocking locks = yes
     posix locking = no
     fake oplocks = yes
     smb2 lease = yes
    # ========== 项目共享专用 ==========
    [projects]
     comment = Development Projects
     path = /home/projects
     browseable = yes
     writable = yes
     guest ok = yes
     #valid users = ${USERNAME}
     read only = no
     create mask = 0775
     directory mask = 0775
     force user = ${USERNAME}
     force group = ${USERNAME}
     follow symlinks = yes
     wide links = yes
    # ========== PHP项目共享专用 ==========   
    [php-projects]
     path = /home/projects/PhpProject
     comment = PHP Projects (laradock权限)
     browseable = yes
     writable = yes
     guest ok = yes
     read only = no
    
     # 强制所有文件为laradock
     force user = $DockerUSERNAME
     force group = $DockerUSERNAME
    
     # 适合PHP开发
     create mask = 0775
     directory mask = 0775
     force create mode = 0775
     force directory mode = 0775   
    # ========== 临时共享 ==========
    [temp]
     comment = Temporary Files
     path = /tmp
     browseable = yes
     writable = yes
     guest ok = yes
     read only = no
    EOF
    echo "[4/8] 创建必要的目录和权限..."
    mkdir -p /var/cache/samba
    #mkdir -p /home/${USERNAME}/projects
    chmod 1777 /tmp
    echo "[5/8] 设置Samba用户(可选)..."
    (echo "123456"; echo "123456") | smbpasswd -a -s ${USERNAME} 2>/dev/null || true
    echo "[6/8] 测试配置文件..."
    testparm -s > /dev/null 2>&1 && echo "配置文件测试通过" || echo "配置文件有警告"
    echo "[7/8] 重启Samba服务..."
    if systemctl list-unit-files | grep -q smbd; then
      systemctl restart smbd nmbd 2>/dev/null
    else
      service smbd restart 2>/dev/null
    fi
    echo "[8/8] 设置开机自启..."
    if systemctl list-unit-files | grep -q smbd; then
      systemctl enable smbd 2>/dev/null
    else
      update-rc.d smbd defaults 2>/dev/null
    fi
    # 计算安装时间
    END_TIME=$(date +%s)
    DURATION=$((END_TIME - START_TIME))
    echo
    echo "=========================================="
    echo "    安装完成!耗时: ${DURATION}秒"
    echo "=========================================="
    echo
    echo "重要信息:"
    echo "1. Samba服务已启动"
    echo "2. 共享路径:"
    echo "   - Home目录: //localhost/home"
    echo "   - 项目目录: //localhost/projects"
    echo "   - PHP项目目录: //localhost/projects/PhpProject"
    echo "3. 在Windows中访问:"
    echo "   - 文件资源管理器: \\\\localhost\\home"
    echo "   - 或: \\\\wsl.localhost\\$(hostname)\\home"
    echo
  • 测试SMB

    #脚本运行完后可以运行下命令,看下SMB网络监听是不是正常的
    sudo netstat -tlnp | grep smbd
    #如果提示没有就安装下
    sudo apt update
    sudo apt install -y net-tools
    #如果提示类似的监听 应该就可以正常使用了
    tcp        0      0 172.17.250.158:445      0.0.0.0:*               LISTEN      525/smbd
    tcp        0      0 127.0.0.1:139           0.0.0.0:*               LISTEN      525/smbd
    tcp        0      0 172.17.250.158:139      0.0.0.0:*               LISTEN      525/smbd
    tcp        0      0 127.0.0.1:445           0.0.0.0:*               LISTEN      525/smbd
    tcp6       0      0 :139                 :::*                    LISTEN      525/smbd
    tcp6       0      0 :445                 :::*                    LISTEN      525/smbd
  • win上测试

    #在win PowerShell上运行下面俩语句,查看wsl的IP
    $wslIp = wsl -- hostname -I | ForEach-Object { $_.Trim().Split()[0] }
    echo $wslIp
    #例如:172.17.250.158,然后后运行下面语句测试是否能正常连通
    Test-NetConnection -ComputerName 172.17.250.158 -Port 445
  • 上面如果能连通了,那基本上就可以使用了,直接在 此电脑->右键->添加网络位置,下一步下一步然后输入\172.17.250.158\projects,或根据自身脚本配置的目录替换projects,能正常添加基本上就成功了。

  • 配置通过Wsl主机名连接

    #wsl内 通过命令打开wsl.conf配置文件,如果没有的话可以新建一个
    #追加如下内容
    [network]
    hostname=ubuntu22.04
    generateHosts=false
    #hostname 可以根据自己随意写

    然后在host内用wsl的ip和刚刚设置的hostname添加下映射 例如:172.17.250.158 ubuntu22.04,这样设置后就可以在添加网络位置时直接用 \ubuntu22.04+目录的形式访问了。
    因为我用的是win10 22H2 只能支持wsl的Nat网络模式,win11可以支持Mirrored,而据说Nat网络模式每次启动ip可能会变,所以 可以写一个开机脚本cmd文件,保存到C:\Users\AMA\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup,开机后获取wsl的IP,然后替换掉host内的 172.17.250.158,这样即使wsl的IP变了的话,我们设置的网络位置也可以不需要修改就能正常访问了
    我这边试了几次,每次重启电脑或wsl IP都没变,所以没具体测试,可以试试下面的win脚本

    # 需要管理员运行
    if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
      Start-Process powershell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
      exit
    }
    Write-Host "=== 设置WSL网络访问 ===" -ForegroundColor Cyan
    # 设置WSL主机名
    Write-Host "[1] 设置WSL主机名..." -ForegroundColor Yellow
    wsl -- sudo hostnamectl set-hostname ubuntu22.04 2>$null
    # 获取当前IP并更新hosts
    Write-Host "[2] 更新hosts文件..." -ForegroundColor Yellow
    $wslIp = wsl -- hostname -I | ForEach-Object { $_.Trim().Split()[0] }
    $hostsPath = "$env:windir\System32\drivers\etc\hosts"
    # 备份原始hosts文件
    Copy-Item $hostsPath "$hostsPath.backup" -Force -ErrorAction SilentlyContinue
    # 清除旧条目,添加新条目
    $tempFile = "$env:TEMP\hosts.tmp"
    (Get-Content $hostsPath) -notmatch "ubuntu22.04" | Out-File $tempFile -Encoding ASCII
    "$wslIp ubuntu22.04" | Out-File $tempFile -Append -Encoding ASCII
    Move-Item $tempFile $hostsPath -Force
    Write-Host "  hosts已更新: $wslIp ubuntu22.04" -ForegroundColor Green
    # 创建开机启动脚本(只更新IP,不创建驱动器)
    Write-Host "[3] 创建开机启动脚本..." -ForegroundColor Yellow
    $startupScript = @'
    @echo off
    chcp 65001 >nul
    echo 正在更新WSL网络配置...
    REM 等待网络服务启动
    timeout /t 15 /nobreak >nul
    REM 获取WSL当前IP
    for /f "tokens=1" %%i in ('wsl hostname -I') do set WSL_IP=%%i
    REM 检查IP是否有效
    if "%WSL_IP%"=="" (
      echo 无法获取WSL IP地址
      goto :end
    )
    echo WSL当前IP: %WSL_IP%
    REM 检查是否已添加该IP到hosts
    findstr /c:"ubuntu22.04" C:\Windows\System32\drivers\etc\hosts >nul 2>nul
    if errorlevel 1 (
      echo 在hosts中添加条目...
      echo %WSL_IP% ubuntu22.04 >> C:\Windows\System32\drivers\etc\hosts
    ) else (
      REM 更新现有条目
      echo 更新hosts中的IP...
      powershell -Command "$hosts = Get-Content 'C:\Windows\System32\drivers\etc\hosts'; $newHosts = @(); foreach($line in $hosts) { if($line -match 'ubuntu22\.04') { $newHosts += '%WSL_IP% ubuntu22.04' } else { $newHosts += $line } }; $newHosts | Out-File 'C:\Windows\System32\drivers\etc\hosts' -Encoding ASCII"
    )
    echo.
    echo === WSL网络配置完成 ===
    echo 您可以通过以下方式访问WSL:
    echo 1. 文件资源管理器地址栏输入: \\ubuntu22.04
    echo 2. 或使用IP地址: \\%WSL_IP%
    echo 3. 或使用WSL默认路径: \\wsl$\Ubuntu
    echo.
    echo 提示: 如果无法访问,请确保WSL已启动
    pause
    :end
    '@
    $startupScript | Out-File "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\Connect_WSL.cmd" -Encoding ASCII
    # 创建测试脚本
    Write-Host "[6] 创建测试脚本..." -ForegroundColor Yellow
    $testScript = @'
    @echo off
    chcp 65001 >nul
    echo === WSL网络连接测试 ===
    echo.
    REM 测试方法1: 通过主机名
    echo 测试方法1: 通过主机名 ubuntu22.04
    ping -n 2 ubuntu22.04 >nul 2>nul
    if errorlevel 1 (
      echo ✗ 无法通过主机名访问
    ) else (
      echo ✓ 可以通过主机名访问
      echo 打开文件资源管理器查看: \\ubuntu22.04
      explorer "\\ubuntu22.04"
    )
    echo.
    REM 测试方法2: 通过IP
    echo 测试方法2: 通过IP地址
    for /f "tokens=1" %%i in ('wsl hostname -I') do set WSL_IP=%%i
    echo WSL IP地址: %WSL_IP%
    ping -n 2 %WSL_IP% >nul 2>nul
    if errorlevel 1 (
      echo ✗ 无法通过IP访问
    ) else (
      echo ✓ 可以通过IP访问
      explorer "\\%WSL_IP%"
    )
    echo.
    REM 测试方法3: 通过WSL默认路径
    echo 测试方法3: WSL默认路径
    if exist "\\wsl$\Ubuntu\" (
      echo ✓ 可以使用WSL默认路径
      explorer "\\wsl$\Ubuntu"
    ) else (
      echo ✗ WSL默认路径不可用
      echo 请检查WSL是否运行
      echo 运行命令: wsl --list --verbose
    )
    echo.
    echo 测试完成!
    pause
    '@
    $testScript | Out-File "$desktop\测试WSL连接.cmd" -Encoding ASCII

    这个脚本 替换了host内容后可能会导致 整个host文件内配置的域名都失效,如果失效的话可以把host文件内容复制,然后清空内容保存,再把原内容粘贴回去就行了。

如果不怕麻烦的话可以试试这种方式,对我来说 因为习惯了使用fork客户端,使用smb的方式确实提速明显,最起码git的各种操作不用等半天相应了。
或者也可以使用评论区内各位大佬的方式,如果没有在win上操作git的需求,使用 @yyy123456
大佬的方式也挺好的

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 7

你在Windows系统中访问 \wsl$ 中的文件就是很慢,文件数越多越慢,其原因是因为 \wsl$ 是通过网络协议挂载到Windows系统中的。 要解决慢这个问题,只能把软件安装到WSL中,比如直接连接到wsl系统中去安装操作git,把你的 phpstorm 安装到WSL中(这个得WSL的GUI支持,似乎现在可以实现,你可以研究下)。

3周前 评论

你这是跨 os 访问文件慢的问题,我目前是这样处理的:弄两套代码,win 一套给 PhpStorm 用,wsl 一套给运行环境用,两套代码之间的文件同步,用 PhpStorm 自带的 Deployment ,并且勾上自动同步代码。这样也会有麻烦事,一个是 win 系统下 composer 调整过依赖后,需要手动同步变更过的 vendor 到 wsl 里,而且同步的速度很慢,因为需要同步的文件比较多;另一个是 win 下看不到项目日志,需要切到 wsl 环境里看项目日志

file

3周前 评论

我目前的开发方案是 win10+wsl,但是几乎所有的开发工具都是在wsl里。phpstorm使用其远程模式。就是在wsl里开phpstorm服务器,windows里是phpstrom客户端这样。安装是在windows里安装的。

3周前 评论
后后 3周前
yangweijie 3周前

一个办法就是宿主机的配置要高,同样的32G内存,台式机和笔记本差别就很大,还有硬盘类型(固态和机械)也是会影响

3周前 评论

除非微软优化,不然现有的方法或多或少都有缺点。 我之前用的方法和@浮心 一样,只不过是自己写了个python脚本同步代码到wsl。 缺点就是偶尔会同步失败,看日志需要打开wsl的文件才能看。phpstorm的远程模式以前试过,重启wsl后,phpstorm远程模式就断开了需要重启phpstorm才能重新连上,不知道现在怎么样了。

3周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!