甲骨文 ARM 机原生运行 Android 云手机实践
事情是这样的。
拿广发 Lucky 卡开了两台甲骨文机器,都是 2c12g ,开完后由于屑网络线路,一直处于开机闲置的状态。 与此同时,隔壁基友家 12700 的 ESXi 一直担任着软解显卡挂方舟的重任,铁铁电老虎,一天下来能跑走两度,暑假一到,有点空闲时间,一日忽见 redroid 提供了 arm 版的 docker 镜像,心想不过转译岂不爽飞,遂查资料开搞。
先说结论: 虽然 CPU 一直占满,但是脚本已经稳跑,方舟大关竟不掉帧,猜测瓶颈主要在网络。 一小段测试视频: https://www.bilibili.com/video/BV1na41157fD/
技术栈
本次采用了甲骨文日本东京的 ARM 服务器,主体为双核 Ampere A1
,配置了 12GB 内存(实测发现 4GB 就足够)。具体可以查看甲骨文自己的介绍,也可以瞅一瞅如有乐享的跑分。ARM 服务器比较抢手,可能得用脚本来刷,在此不作推荐。 Android 容器方面,采用 redroid 的 Android 8.1 arm64 镜像,这是经过实测的最佳版本。
流程
基础环境配置
首先参照 Docker 的官方教程进行安装: https://docs.docker.com/engine/install/#server
海外机无需考虑镜像问题,所以可以直接安装,详细步骤亦可百度,在此不表。 另外,请运行系统更新指令,并且尝试将系统更新至最新内核。
更新完毕后请使用 uname -r
命令检查内核版本,对于我而言,版本是 5.13.0-1036-oracle
。
根据官方文档,5.0
版本以上的内核才能保证正常运行,5.0
一下的版本虽然也能通过自己装模块解决,但那可能会有更多奇奇怪怪的问题。
确认完内核版本之后,我们需要补齐内核模块,然后确保相应的内核特性已被开启:
1 | apt install linux-modules-extra-`uname -r` |
据愚人的了解,binder
用于进程间通信,ashmem
用于内存共享,都是 Android
运行强依赖的机制,因此如果您在这一步产生了报错信息,请立即去搜索引擎进行解决,否则将影响下一步的结果。
Protip:这种 Android 的运行方式和 anbox
如出一辙,所以出现问题时可以考虑看看 anbox
相关的解决方案。 对于一些集群机器来说,可能会出现 pid_max
超大导致无法正常运行,请使用 sysctl kernel.pid_max
检查数值是否低于 65536 (一般不会出现问题),如果发现数值不对,请参考华为云的教程来解决。
启动参数
基础条件具备以后,便可配置 Docker 的启动参数,在此为懒人党先贴出全部参数,后逐一详解。
1 | docker run -itd --rm --memory-swappiness=0 \ |
- 前几行(L1-L5)都是较为基础的 Docker 启动参数。
-itd
为后台运行,--rm
用于退出容器后自动删除,防止占用空间(考虑到/data
文件夹已经持久化,此举不会丢失容器数据)。--privileged
设为特权用户规避各种问题,memory-swappiness
设为 0 可停用 swap 分区提升性能。- 在该组指令中,我们用宿主机的
/data
文件夹来映射容器内的/data
分区,考虑到 Android 特性,此举即可使用户数据持久化,无惧容器丢失重启,且易于备份。 - 用宿主机的
5556
端口映射容器内的 ADB 端口。
- 本实践中,我采用了
redroid/redroid:8.1.0-arm64
镜像,这是实践中最稳定的镜像,其他的容易在adb connect
之后出现device offline
错误。如果您测试到了其他版本,欢迎在评论区分享您的经验。- 另据群内老哥分享,
8.1.0
的amd64
镜像在运行明日方舟时会出现闪退问题,需要定时重启,在这里顺道提一下。
- 另据群内老哥分享,
- L6 的参数用于给容器传入一些较为真实的数据,用于应对一些游戏较为简单的风控。这些数据从我的手机(
Redmi Note 10 Pro
)上修改而来,当然您也可以从任意一个能够读取build.prop
文件的系统工具箱上自取。androidboot.hardware
对应着容器内的ro.boot.hardware
变量,默认是redroid
,推荐修改。ro.secure=0
用于为 adb shell 提供 root 权限。- 其余的
ro.xxx
对应着容器内的ro.xxx
变量,您可适当进行添加。
- L7 用于配置容器屏幕的长宽,对于大多数脚本而言,720P 已经足够。
- L8 中
redroid.gpu.mode=guest
用于强制软件解码,否则将会出现奇奇怪怪的问题。
观测
正常情况下,容器应当已经启动,系统是纯净的 AOSP 8.1
。 经过一段时间后,我们可以用 docker exec -it <容器ID> sh
进入容器的终端,之后便可以执行 logcat
这样的调试操作。(容器ID在启动容器时便已给出,也可以使用 docker ps
查看,通常情况下只需复制前八位即可)
这时我们便可以从家机或是另一台服务器,通过 adb connect 服务器IP:5556
连入容器,之后便是常见的刷机操作了。使用 adb install
可以进行远程安装,也可以用秋之盒这类第三方软件进行管理。
在远程控制方面,我们可以使用scrcpy。直奔 Releases 页面下载 zip 格式的文件,直接解压后连接上容器,然后直接双击 scrcpy
即可。
最后,便是文中开头演示的效果。
一点小补充
在方舟脚本方面,我推荐使用 ArknightsAutoHelper ,arknights-mower
更新较为迟缓,MaaAssistantArknights
的截图实现在网络不良时有点问题,唯有这个脚本控制较为简便省心,直接在甲骨文那台正常 x86 机子上跑就行。 在使用 scrcpy 连入系统桌面后,htop
返回的资源占用如图。
而在打开明日方舟之后:
这些启动参数至今未出现更多问题,但如果读者抄作业抄出了问题,可以在评论区进行分享补充,且介于我并非安卓从业人士,有任何问题还请及时拍砖。