【Unity】项目部署Linux服务器
Unity项目部署Linux记录。
1 Unity打包到Linux平台
最近需要将Unity项目放到Linux平台上运行,也是研究了下。目前成功在linux的图形界面上正常运行;在命令行模式下因为虚拟桌面暂时没找到切换为独显渲染的方法,所以还不能运行。下面记录一下部署过程。系统版本:CentOS 7.9。
1.1 平台切换与设置
首先在Build Settings界面中,下左侧平台选择Winsows,Mac,Linux选项,在右侧Target Platform选择Linux。
然后还需要一些设置。
-
在Project Settings-Player-Resolution and Presentation中:
-
设置Fullscreen Mode为Windowed,然后输入我们需要的分辨率,这样做是为了保证分辨率固定。
-
Run In Background勾选。
-
Resizable Window取消勾选。
-
-
在Project Settings-Player-Other Settings中:
-
AutoGraphicsAPIforLinux默认是勾选的,可以取消勾选然后选择需要的API,一般勾选即可。
-
Graphics Jobs取消勾选。
-
Scripting Backend改为IL2CPP。
-
ApiCompatibilityLevel,选Framwork、standard2.1都可。
-
另外第一次打包的话,可能还需要在UnityHub里为编辑器下载相关模块:Linux Build Support(IL2CPP)。
图形API也要选择下,在Project Settings-Player-OtherSettings下的Rendering中,这里勾选Auto Graphics API for Linux就行,若自行想限定OpenGL或Vulkan则取消勾选,然后在新增的列表里增删即可。
1.2 代码冲突
切换平台后,大概率会遇到一些代码报错,这通常是Window平台下的代码在Linux的不兼容导致的。另外,这些错误也可能会在项目打包时才报出来。
报出来后解决就行,我这边是一些插件中的代码不兼容,因为都是没有用到的插件,所以有的是直接卸载了,有的则是直接把相关代码注释了。如果是用到的插件,则需要好好寻找解决方法。
1.3 打包产物
打包所得内容跟在Window上差不多,只不过没有.exe文件了,对应的执行文件是.x86_64文件。
2 部署Linux服务器
直接把部署需求告诉AI,基本上AI都会提供一套部署流程。就我的部署经历来看,最大的问题就Linux服务器的环境配置,Unity本身倒没什么问题。所以先问AI自己操作一遍,若没问题自然很好,若有问题可参考我的配置经历。
接下来我会把我当时如何部署的流程叙述一遍,并说明当时遇到的问题,所给的命令不一定完整,毕竟来回捣鼓了很久,所以还是建议先让问AI要套部署流程,之后有什么问题问什么即可,期间可以参考我的部署经历。
提示:相关问题中的解决方法不会在基础配置小节中说明,会随着问题的列出逐步说明,所以想了解我这边都使用了哪些方法来部署,基本就要从头看到尾。
2.1 基础环境配置
这个就直接问AI,我这里给个基础的参考。
# 步骤 1:系统基础检查与依赖源配置
# 1. 安装EPEL源(必须,否则部分依赖包无法找到)
yum install -y epel-release
# 步骤 2:验证 NVIDIA 驱动与 OpenGL 基础环境
# 1. 检查NVIDIA驱动状态
nvidia-smi
# 正常输出应显示GPU信息、驱动版本,无"Failed to initialize NVML"错误
# 2. 安装OpenGL基础依赖(必须,Unity运行依赖)
yum install -y mesa-libGL mesa-libGL-devel mesa-libGLES mesa-libGLES-devel
yum install -y glx-utils libX11-devel libXcursor-devel libXrandr-devel libXinerama-devel libXi-devel
yum install -y libstdc++ libgomp glibc-devel libuuid-devel
# 3. 临时检查OpenGL版本(无显示器时暂无法直接输出,后续配虚拟显示后验证)
glxinfo | grep "OpenGL version"
#步骤 3:配置无显示器的虚拟显示(Xvfb)
#Unity 依赖图形上下文,无物理显示器时必须通过 Xvfb 创建虚拟帧缓冲区:
# 1. 安装Xvfb(虚拟显示服务)
yum install -y xorg-x11-server-Xvfb xorg-x11-apps
# 虚拟显示器实际我并未用到,因为存在一些问题,但最好还是安装下↑↑↑↑↑↑
然后先给linux服务器先装一个物理显示器,再在系统内装一个图形界面,这里就不展开说明了,确保安装好后能进入图形界面即可。
2.2 图形渲染开关问题
最初我是通过MobaXterm通过SSH会话连接Linux服务器来操作。因为服务器之前有在用在别的地方,所以有一定的环境配置(显卡驱动、图形界面等等),所以我开始并未配置环境。另外,我的项目中使用了UnityRenderStreaming云渲染,渲染画面理论上可以在我Window机器这边看到。直接将打包好的项目拷贝到服务器上,进入对应项目目录下执行:
# 权限设置(若需要)
chmod 755 xxx.x86_64
# 执行
./xxx.x86_64 -nographics -logFile /xxx/xxx.log
运行后发现log可打印输出,输出内容正常,确定在运行,但云渲染画面加载不出来,不过log中说明渲染设备为Null。后来研究半天发现,不能使用“-nographics”参数,这是关闭图形渲染的意思。我向AI表达的是无显示器的渲染方式,但其却理解偏差,给了我错误的参数。
2.3 libstdc++版本低/缺失
再执行:
./xxx.x86_64 -logFile /xxx/xxx.log
直接在中断窗口中报错,最终提示吐核,并终止程序。错误原因是相关libstdc++库版本低或缺失,解决方案:
# 步骤 1:升级 libstdc++ 并配置库路径
# 1. 先备份系统原有libstdc++(防止系统崩溃)
mv /usr/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6.bak
# 2. 从GCC目录复制高版本libstdc++(替换为你的GCC安装路径)
cp /usr/local/gcc-9.3.0/lib64/libstdc++.so.6.0.28 /usr/lib64/
# 3. 创建新的软链接
ln -s /usr/lib64/libstdc++.so.6.0.28 /usr/lib64/libstdc++.so.6
# 4. 验证版本(需显示GLIBCXX_3.4.26及以上)
strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
若没有gcc的话则需要自己安装下,建议根据自己的情况问AI。
具体按自己的来,930也只是我在使用的版本而已,“需显示GLIBCXX_3.4.26及以上”也是我的环境下的要求。
参考:
# 安装编译依赖
yum install -y gcc gcc-c++ make kernel-devel kernel-headers dkms
2.4 OpenGL Version低
之后再次运行程序:
./xxx.x86_64 -logFile /xxx/xxx.log
终端中不再报错,但程序运行后马上就中断。打开输出的log文件可以看到提示:
Display 0 'screen': 1920x1080 (primary device).
Desktop is 1920 x 1080 @ 0 Hz
Unable to find a supported OpenGL core profile
Failed to create valid graphics context: please ensure you meet the minimum requirements
E.g. OpenGL core profile 3.2 or later for OpenGL Core renderer
No supported renderers found, exiting
执行命令查看版本:
glxinfo | grep -E "OpenGL version|OpenGL core profile version"
# 正常输出示例:(只是例子,不用在意版本号不同)
# OpenGL core profile version string: 4.6.0 NVIDIA 545.23.06
# OpenGL version string: 3.3.0 NVIDIA 535.261.03(≥3.2即可)
# 但我这边输出为
OpenGL version string: 2.1 Mesa 18.3.4。
原因是:默认加载了 CentOS 系统自带的 Mesa 软件渲染库(OpenGL 2.1),而非 NVIDIA 显卡驱动提供的硬件加速 OpenGL 库(3.2+)。
另外,在图形界面下,也可以在设置-详情中看到当前是用什么渲染的,在我这边,若是模拟渲染则会显示“llvmpipe相关字样”,若是显卡渲染则会显示对应的显卡信息,如“RTX4080”。
问题解决过程
开始AI让我在“/usr/lib64/nvidia/”去寻找相关lib文件,然后让“/usr/lib64/”下的相关lib文件去关联。但我这边“/usr/lib64/nvidia/”下根本没lib文件。驱动重装、换版本,试了好多次,依旧是没有,到后来才发现,这边的lib文件会直接放到“/usr/lib64/”下,虽然期间也用find命令找到过,但因为一直是模拟渲染,所以被AI认定为不是,后来通过每次安装驱动发现这些lib会更新才确定是我要找的东西。
期间不再使用MobaXterm远程连接,而是直接跑到服务器那操作。
在确定这些都没丢失后就只能从别的角度解决,后来通过
sudo nvidia-xconfig
命令生成了一个配置文件,要确定此配置文件内的Device下添的设备是Nvidia(独显,我用的N卡,所以是这个),之后重启服务器,打开后就使用独显渲染了。
无论用之前的opengl version指令还是在设置详情中看,都会显示为独显的信息。
再去运行Unity程序,正常运行。
2.5 图形界面下的远程访问
这是在图形界面下可以正常运行了。那如果使用远程连接呢,如MobaXterm的SSH会话。答案是依旧没问题。
不过需要注意在远程连接到服务器后,执行Unity程序前,需要输入
DISPLAY=:0
这里好像是物理显示器默认是0,所以需要切到物理显示器上。之后运行Unity,显示器上也会同步打开窗口。
另外,即使把物理显示器拔掉也没影响。
总结一下就是:在图形界面下配置好后就可以直接把显示器拔了,用远程会话访问切换到显示器0下,运行程序即可。
2.6 命令行界面
除了图形界面外还有命令行界面。我这边的相关命令如下,不同的系统命令可能不同。
# 查看当前模式
systemctl get-default
# 切换为多用户模式(命令行)
systemctl isolate multi-user.target
# 切换为图形界面模式
systemctl isolate graphical.target
在命令行模式下,查看opengl版本将会出入null,因为没有桌面来渲染了,需要创建虚拟桌面,可以通过Xvfb来创建。
# 创建虚拟桌面
Xvfb :99 -screen 0 1920x1080x24 -ac +extension GLX +render -noreset &
# 切换到对应虚拟桌面
DISPLAY=:99
但目前在创建的虚拟桌面上只会用模拟渲染(Mesa),还没找到切为独显渲染的方法,所以无法运行Unity项目。
2.7 终端后台执行
目前在终端内执行后,会卡住终端输入,且只能执行一个程序。改为nohup可以不影响终端后续输入且执行多个。
# 执行test.x86_64,在同目录下输入mylog.log、mylog_nohup.log文件,前者存放unitylog,后者存放终端log,终端错误信息也放入log文件内容,不阻塞终端输入
nohup ./test.x86_64 -logFile mylog.log > mylog_nohup.log 2>&1 &
# 另外,也可以加上signalingUrl,来设置UnityRenderStreaming云渲染连接服务器地址
nohup ./test.x86_64 -signalingUrl ws://xxx.xx.x.xxx:xxxx -logFile mylog.log > mylog_nohup.log 2>&1 &
不过这是执行同一个项目文件,若是项目存在项目文件会被修改的情况,这样感觉有风险。考虑复制多个项目文件来执行。
3 Unity需注意问题
3.1 YooAsset资源问题
切换linux平台后,资源需要重新打包,否则会出现贴图丢失问题。
3.2 UnityRenderStreaming云渲染鼠标位置丢失问题
这个不会影响程序,但会在log中一直输出,可以在使用InputSystem的鼠标位置前,判断下位置是否为nan,来决定本次是否使用。
3.3 UnityRenderStreaming画面翻转问题
在Window中,Unity客户端连接上Webserver后,因为使用的时广播模式,在打开多个网页访问时都会访问到客户端的同一界面,最新打开的网页可以交互,其他网页不可交互。这种情况在Linux中发生了变化,在多网页访问的情况下,除了前面说的最新的才可以交互,还出现了若刷新网页,则会画面翻转的情况,不过将多余页面关闭只打开一个,再次刷新,又会恢复正常。
当然最好的解决方法是不要广播,可以从unity这边控制,也可以从webserver上控制。
unity这边可以断开streaming重连,也能恢复正常。
4 部署结果
服务器图形界面下(graphical),配置好独显渲染,本机、远程会话都可以正常运行unity。远程会话需要DISPLAY=:0切换为显示器0。只要在图形界面下,即使拔掉显示器,重启服务器后,依旧可识别并切换到显示器0(DISPLAY0),且为之前配置好的独显渲染。
在命令行界面下(multi-user),无显示器,需要使用模拟显示器,但模拟显示器目前一直是CPU模拟渲染(Mesa),暂未找到切换为独显渲染的方式,故无法运行unity。
5 补充 部署到Rocky Linux 8上
依旧模式为图形界面,即graphical.target,只不过没有硬件显示器。Unity项目的配置如之前一样,不过这里Linux服务器上已经安装好了N卡驱动,下面只展示之后的部署过程。
# 同样,选择0显示器,这是系统默认的图形管理器
export DISPLAY=:0
# 我这边使用的MobaXterm连接的,需要开启相关显示器权限,这里是拿到开启权限的“密码”
export XAUTHORITY=/run/user/42/gdm/Xauthority
# 为本地root用户开启权限
xhost +local:root
# 输出以下内容表示成功
# non-network local connections being added to access control list
# 限定使用N卡渲染、驱动
export __NV_PRIME_RENDER_OFFLOAD=1
export __GLX_VENDOR_LIBRARY_NAME=nvidia
# 查询是否成功
glxinfo | grep -E "OpenGL version|OpenGL core profile version"
# 输出类似如下内容表示成功
# OpenGL core profile version string: 4.6.0 NVIDIA 570.133.07
# OpenGL version string: 4.6.0 NVIDIA 570.133.07
之后即可运行。
不过目前也出现了一些问题,显卡占用率偶尔会99,导致项目卡死几秒,严重时甚至影响模型贴图。出现频率不稳定,有时一直没事,有时偶尔,有时频繁。【暂未解决】
6 补充 GPU占用阶段性为0问题(CentOS 7.9)
最近又在CentOS 7.9服务器上部署,出现了GPU阶段性占用为0,导致云渲染画面偶尔卡住的情况,GPU占用0时,nvidias-smi面板中Disp.A也会由On变为Off,发现是因为锁屏问题。目前有两种解决方案。
第一种:
解决方法是修改/etc/X11/xorg.conf文件,在Device段添加以下内容:
# 强制启用显示控制器
Option "UseDisplayDevice" "none"
# 禁用显示电源管理
Option "DPMS" "false"
# 允许没有显示器时启动X Server
Option "AllowEmptyInitialConfiguration" "true"
之后重启服务器后,Disp.A就固定为Off,云渲染也运行正常。
我的理解:这里三个配置,首先是不绑定任何物理显示接口,即不再在屏幕输送画面(具体没看,说法是这样),然后禁用了显示器电管管理(休眠之类的),最后是让XServer即使在没有显示器是也能正常启动,整体组合下来,相当于能启动Xorg同时排除了显示器对其的影响。最终,Disp.A为Off,云渲染也能稳定运行,不出异常。
第二种:
第一种会导致屏幕不显示,有时并不方便。第二种则没有这种问题。也是在xorg.conf配置文件中进行配置,在上面基础上做如下修改:
# 强制启用显示控制器
# Option "UseDisplayDevice" "none"
# 禁用显示电源管理
Option "DPMS" "false"
# 允许没有显示器时启动X Server
Option "AllowEmptyInitialConfiguration" "true"
# 禁用你的特殊 HardDPMS 实现,回归标准DPMS行为, 标准行为可保证GPU性能不受显示器影响
Option "HardDPMS" "false"
将关闭显示输出的配置注释了,在下面添加了一个配置。标准DPMS的初衷是“仅控制显示器本身的电源消耗,不影响显卡 GPU 的任何功能”,所以这里禁用特殊实现,回归标准就解决了问题。
7 切换显卡运行(Rocky Linux 8)
在多显卡服务器上,选择其中一个显卡运行项目,命令如下:
# 1、显卡信息查询
xrandr --listproviders
# 输出如下(几个显卡输出几个)
# Providers: number : 8
# Provider 0: id: 0x1b8 cap: 0x0 crtcs: 0 outputs: 0 name:NVIDIA-G0
# Provider 1: id: 0x21f cap: 0x0 crtcs: 0 outputs: 0 name:NVIDIA-G1
# ...
# Provider 7: id: 0x489 cap: 0x0 crtcs: 0 outputs: 0 name:NVIDIA-G7
# 2、执行程序
# 这里选择显卡7,第一个选数字编号,最后选显卡name,中间固定
nohup env \
CUDA_VISIBLE_DEVICES=7 \
__NV_PRIME_RENDER_OFFLOAD=1 \
__GLX_VENDOR_LIBRARY_NAME=nvidia \
__NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G7 \
./aiops.x86_64 -signalingUrl ws://XXX.XXX.XXX.XXX:XXXX -logFile mylog.log > mylog_nohup.log 2>&1 &
PS xorg.conf文件内容
这里记录下文件的内容。
# nvidia-xconfig: X configuration file generated by nvidia-xconfig
# nvidia-xconfig: version 545.23.06
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0"
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "Mouse0" "CorePointer"
EndSection
Section "Files"
EndSection
Section "InputDevice"
# generated from default
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "Emulate3Buttons" "no"
Option "ZAxisMapping" "4 5"
EndSection
Section "InputDevice"
# generated from default
Identifier "Keyboard0"
Driver "kbd"
EndSection
Section "Monitor"
Identifier "Monitor0"
VendorName "Unknown"
ModelName "Unknown"
Option "DPMS"
EndSection
Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BusID "PCI:1:0:0"
# 强制启用显示控制器
# Option "UseDisplayDevice" "none"
# 禁用显示电源管理
Option "DPMS" "false"
# 允许没有显示器时启动X Server
Option "AllowEmptyInitialConfiguration" "true"
# 禁用你的特殊 HardDPMS 实现,回归标准DPMS行为, 标准行为可保证GPU性能不受显示器影响
Option "HardDPMS" "false"
EndSection
Section "Screen"
Identifier "Screen0"
Device "Device0"
Monitor "Monitor0"
DefaultDepth 24
SubSection "Display"
Depth 24
EndSubSection
EndSection
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)