zoukankan      html  css  js  c++  java
  • 旧手机小用途:在Android手机上建网站,较完全指南

    做个人服务器就是一个不错的用途:功耗低,还自带UPS。做个个人网站,个人云或下载机,7x24小时开机,不担心费电,也不担心停电。

    最近在Android手机上利用Linux Deploy搭建了一个LEMP/LNMP网站,本文讲述其中的主要流程和注意事项。有一些坑,也有点小窍门,还有一些测试数据,拿手机做其它框架的网站或其它用途的服务器也可参考。

    可行性及方案

    先评估下性能。在手机上装了个Linux,用sysbench测试下CPU,以PC和树莓派作为对比。

    命令:

    sysbench --test=cpu --cpu-max-prime=20000 run
    

    结果是耗时,越短越好。

    • PC: i7 4770K: 21.2s
    • 华为荣耀6 plus: 247s
    • 树莓派3代: 535s
    • 树莓派2代: 1150s

    虽然比PC差远了,但比树莓派快不少(多核应该更强)。其实我的网站以前是跑在树莓派2代上的。树莓派的I/O(SD卡)也是很慢的。

    至于方案,理论上来说有这么几类:

    1. APK提供http服务器、MySQL服务器、PHP的支持。——功能受限于APK,不能使用标准的工具集。
    2. 用类似于busybox的方式,把Linux下的命令集和需要的服务器都编译到Android上。——累。
    3. 双系统,既可以引导Linux,也可以引导Android。——树莓派可以,以前用过RK3188的Android电视盒也可以,理论上手机也可以做到,就看有哪几个手机厂商愿意提供这种支持了。所以,可遇不可求。
    4. 模拟器:APK是Linux的模拟器。——慢。
    5. Linux和Android共用内核,使用chroot容器的方式。——这几乎是最完美的方案了,既不破坏Android,又有一个几乎完整的Linux。Linux Deploy就是这方面的杰出代表。

    手机root及清理

    不root会有很多限制,比如不能使用1024以下的端口。而且root也是Linux Deploy要求的。不同的手机型号,请各显神通寻找root攻略。

    对于荣耀6和6 plus,大致流程是(国内的各种一键root工具都不行):

    1. 先升级到5.1(可能要申请);
    2. 再升级到6.0(可能要申请);
    3. 申请解锁码;
    4. fastboot下unlock, 刷TRWP recovery;
    5. TRWP recovery下刷root用的zip文件。

    root后,SuperSU是必装的(通常会自带),busybox也建议安装。

    既然是专用作服务器,其它不用的程序都卸载掉,包括一些系统程序及服务,以减少对系统资源的占用。方法是列出所有进程,在网上搜索其用途,根据自己的需要进行删除。网上一些文章也会说明是否可删除,建议删除还是保留。不能删除的可以尝试禁止启动。

    我的荣耀6 plus最后保留了不到一屏的App。不过,系统内的进程数还是很多,但都处于不活动状态。最后,手机设置为飞行模式;休眠状态始终保持WiFi连接。

     
    image.png

    SD卡分区

    Linux Deploy可以将系统完全安装在内置Flash,或SD卡的image上,也可以装到某个目录或分区。
    为了比较,我装了多个系统,并共用home分区。最后的SD卡分区方案是这样的:

    1. 2G, FAT,给android系统使用
    2. 8G, ext2, 安装第二个Debian Linux用(第一个装在内置Flash的/data/local目录里)
    3. 8G, ext2, 玩玩Kali Linux
    4. 16G, ext4, 共用的 /home 分区

    这里的小经验是:保留一个小的FAT分区!这是为了让Android系统看上去还是有一个可用的SD卡。否则,系统会提示SD卡不认识,是否要格式化。万一哪天自己忘了SD卡里藏了好几个Linux的系统和数据,或者手快点了一下“是”,就杯具了。

     
    image.png

    Linux Deploy的关键设置

    建立多个Profile,对应于多个系统。

     
    image.png

    然后依次对每个Profile进行配置。

     
    image.png

    上图的安装位置设在内部Flash的/data/local目录下。如果想安装在SD卡分区上,则类似于下图。

     
    image.png

    ssh服务是必须开启的。挂载点的语法要注意:一行一个条目;用冒号分隔源路径和挂载点。

     
    image.png

    然后开始安装(装Debian8时安装忘了截屏,下图用Debian9作为示意)。

     
    image.png

    权限问题

    这里的坑是在Android手机上安装LAMP/LEMP系统特有的。想不到可能半天也搞不定,想到了只是一行命令。

    MySQL启动失败

    MySQL在安装的时候报告启动失败,日志上也没有更多信息。

    好吧,既然MySQL 5.5失败,那我装MariaDB 10.0吧?——结果还是失败。

    会不会是文件系统权限问题?把数据目录从Flash的/var/lib/mysql换到SD卡的/home/mysql吧?——一样失败。

    ...

    其实原因是mysql用户的权限问题。解决办法是把mysql这个用户加到aid_net_raw组。

    sudo usermod -a -G aid_net_raw mysql
    

    aid_xxx 这些组其实是Android的用户组(这些组的映射/创建,应该是Linux Deploy做的),容器内的Linux用户要具有Android的相应权限才能做相应的事。而MySQL创建/监听socket,要有aid_net_raw对应的权限。

    网上有人把aid_inet也给予mysql用户,其实这个Internet访问权限对于MySQL不是必须的。

    PHP下载及发邮件

    我安装的这个Web系统(Drupal)有网页上安装/升级模块(插件)的功能。但这个功能用不了:

    GuzzleHttpExceptionConnectException: cURL error 6: Could not resolve host: updates.drupal.org (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in GuzzleHttpHandlerCurlFactory::createRejection() (line 186 of /home/www/drupal-8.3.2/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php).

    从字面看,像是DNS或是网络连接的问题。最后的答案和前面MySQL启动不了是类似的:Web server进程需要有Internet访问的权限。

    sudo usermod -a -G aid_inet www-data
    

    发邮件也是网站必备的功能。通过PHP发邮件,Web server同样需要Internet的访问权限(比如连接smtp.gmail.com的587端口)。

    性能测试及调优

    WiFi及网络速度

    做服务器肯定是用有线网络好。但无线网络是否堪用呢?下面的测试都是在5G的WiFi下,靠近路由器,小米mini一代。

    用 ping 测试有线连接的树莓派和无线连接的手机。

     
    image.png

    可以看到,往返时间差了两个数量级。前者平均是0.72ms;后者差不多70ms。

    下图是用 iperf 测试网络速度。大约是67Mbps.

     
    image.png

    速度属于正常水平,对于自娱自乐的个人站点,也可接受吧。

    数据库放在Flash还是SD卡上?

    先对文件系统做一简单的测试。用dd读写总共4GB(大于手机内存)的文件,每次读写不同大小的块。

    #$count = $totalsize / $blksize
    dd if=/dev/zero of=$tmpfile bs=$blksize count=$count && sync
    of=/dev/zero if=$tmpfile bs=$blksize count=$count && sync
    

    最后的结果如下图所示。

     
    image.png

    可以看到,写的速度差不多,读的速度Flash还是比SD卡快不少。

    还可以用sysbench测试MySQL性能,或者用wget/curl直接测试网站的速度。总体上,对于这个手机(荣耀6 plus),后面这两项测试的结果差别不大。最后,我还是把数据库放在了内部Flash上。

    屏幕开还是关?

    对于做服务器用途,想当然地会认为要把屏幕关掉。控制开关屏幕的有好几个地方:

    • “显示”里面的延时熄屏;
    • “开发者选项”里的插电时保持屏幕活动;
    • Linux Deploy界面里的保持屏幕活动。
     
    image.png

    在性能测试中发现,屏幕开着和关着的差别很大。

    sysbench --test=cpu --cpu-max-prime=20000 run
    
     
    image.png
    • 屏幕开:247.5s
    • 屏幕关:441.0s

    sysbench进行CPU测试的结果还是很稳定的,包括以前用Linux Deploy 2.0.0-215,现在用的2.0.2-220;开启mysql/nginx等服务或者不开启,分数波动在1%以内。可见,屏幕开和关的差距是非常显著的。

    在Android/Linux系统里,还有一个CPU Governor的策略会影响CPU的性能。

    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

    interactive

    可以看到,默认的策略是"interactive". 尝试把它改到性能最高的 "performance",

    echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

    测试结果也并没有差别。

    也许是屏幕关着的时候,CPU被降频使用了?

    最后,不得不选择让屏幕常开(当然,亮度调至最低)。

    /proc/loadavg的问题

    我们通常会用/proc/loadavg查看系统的load

    cat /proc/loadavg 
    
    • 空闲时:5.16 5.14 5.17 1/1290 8877
    • 运行sysbench时:6.02 5.74 5.48 4/1295 9353

    作为对比,树莓派的loadavg:

    • 空闲时:0.03 0.07 0.02 2/159 28307
    • 运行sysbench时:1.03 0.72 0.33 3/158 28903

    Android系统的loadavg空闲时普遍都很高;而用top命令查看各进程的CPU占用率时,并没有多高。

    关于这个问题,网上有一些讨论,但我还没找到权威的说法。总之,并不能用loadavg作为系统load的参考。

    自动启动

    在启动Android系统时,自动启动容器内的Linux,似乎并不起作用。

     
    image.png

    另一个层面的自动启动是自动启动Linux系统内的服务。这需要在Linux Deploy里启用 Init 系统,并选用类型 SysV.

     
    image.png

    这样,在Linux系统启动时,runlevel(默认为3)中设置为自动启动的服务就会自动启动,像普通的Linux那样。否则,连cron服务都要手动启动。

     
    image.png

    不过在我的手机上有个小问题:在启用了Init后,Stop Linux时会导致Android重启,然后root丢失。但再重启一次会恢复root。

    备份

    数据库本来是安装在Flash上,可以将其备份到SD卡,这样起到了“两个篮子”的作用。

    考虑到Flash和SD卡都有可能突然失效(都曾经碰到过),远程备份也是必须的。

    本想用NFS挂载NAS上的目录的,但NFS client的安装有点问题。没有去深究,直接用了ssh密钥登录加rsync。命令示意:

    rsync -auvAX --delete $srcdir nas:/$dstdir
    

    升级

    升级包括3个层面:

    1. Android系统本身:取决于厂家是否还提供升级支持,升级后可能要重新root。总之是比较麻烦的。由于Linux和Android共用内核,除非出现内核级别的安全漏洞,否则没必要升级。
    2. Linux系统:可以安装unattended-upgrades之类的包来自动更新。
    3. Linux Deploy:根据需要升级。升级前最好保存配置。直接缷载/安装会把原配置数据全部清除;不过只要把Profile重新配置一下,就可以启动原系统 。所以也不是大问题。

    功耗

    用记录型万用表UT181A对电流进行24小时监测(手机电池始终是满电)。

     
    image.png

    每小时的平均电流在140~150mA之间,功耗相当于0.75W。

     
    image.png

    小米路由器的USB口实测电流可以超过200mA,所以可以直接用这个路由器的USB口给手机长期供电。

     
    image.png

    电源/电池状态

    还可以通过读取目录 /sys/class/power_supply/Battery 的文件来监控电源和电池的状态:

    • status:充放电状态;
    • capacity: 电池容量百分比;
    • charge_now:当前充电的容量(mAh);
    • charge_full:电池的总容量(mAh);
    • voltage_now:当前电池电压(V);
    • voltage_max:电池充满电的电压(V);
    • current_now:当前充电电流(mA),充电为正,放电为负;如果系统负载高,电流会是负值;
    • temp:电池温度(有无爆炸隐患早知道)。

    可以写几行脚本,直接在网站上显示这些状态。

     
    image.png

    结语

    在root过的Android手机上通过Linux Deploy安装Linux,可以达到和普通Linux一样的完整度和自由度。能灵活地在上面部署各种LAMP, LEMP/LNMP站点。而且,这样的“服务器”功耗低(小于1W),带“UPS”(电池)。

    主要的要注意的方面有:和Android相关的权限问题,如何自动启动服务,熄屏对性能有无影响,等等。手机虽小,但跨越Android, Linux及容器,涉及系统的多方面,对技术爱好者也是一个很好的练习。

    本文主要是从平台的角度来谈论“手机服务器”的,并不涉及平台上的应用(即具体如何建一个网站)。至于建网站的其它方面,后续会有文章。敬请关注。

    参考

    1. Convert an Android Device to Linux
    2. Linux Deploy官方下载地址


    作者:萝卜头实验室
    链接:https://www.jianshu.com/p/f5e107180b45
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    杭电 Problem
    杭电Problem 5053 the sum of cube 【数学公式】
    杭电 Problem 2089 不要62 【打表】
    杭电 Problem 4548 美素数【打表】
    杭电 Problem 2008 分拆素数和 【打表】
    杭电 Problem 1722 Cake 【gcd】
    杭电 Problem 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心】
    杭电Problem 1872 稳定排序
    杭电 Problem 1753 大明A+B
    东北林业大 564 汉诺塔
  • 原文地址:https://www.cnblogs.com/ricksteves/p/12166722.html
Copyright © 2011-2022 走看看