2020年7月

‎aria2 是用于下载文件的实用程序。它支持 HTTP(S)/FTP/SFTP/BitTorrent 和 Metalink 协议。aria2可以从多个来源/协议下载文件,并尝试利用您的最大下载带宽。它支持同时从HTTP(S)/FTP/SFTP和BitTorrent下载文件,而从HTTP(S)/FTP/SFTP下载的数据上传到BitTorrent群。使用 Metalink 块校验和,aria2 在下载文件时自动验证数据块。‎

安装Aria2

sudo apt install aria2

image.png

配置Aria2配置文件

Arai2默认会从$HOME/.aria2/aria2.conf$XDG_CONFIG_HOME/aria2/aria2.conf这两个位置读取配置,为了方便管理,我们可以将配置文件放到/etc/aria2/aria2.conf,以方便管理。

创建/etc/aria2目录,新建并编辑/etc/aria2/aria2.conf配置文件

sudo mkdir /etc/aria2/
sudo vim /etc/aria2/aria2.conf

创建下载文件保存目录

mkdir /home/ubuntu/downloads

把以下配置内容写入到/etc/aria2/aria2.conf

# 设置加密的密钥
rpc-secret=12580
# RPC 开关
enable-rpc=true
# RPC 跨域(WEB 界面需要跨域)
rpc-allow-origin-all=true
# RPC 外部访问(false 的话只监听本地端口)
rpc-listen-all=true
# RPC 端口, 仅当默认端口被占用时修改
rpc-listen-port=6800
# 最大并行下载数(默认值:5)
#max-concurrent-downloads=5
# 单文件并行下载数
split=5
# 断点续传
continue=true
# 同服务器最大连接数
max-connection-per-server=5
# 最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要
min-split-size=10M
# 下载速度限制(0代表不限制)(示例值:500K、10M)
max-overall-download-limit=0
# 单文件速度限制
max-download-limit=0
# 上传速度限制
max-overall-upload-limit=0
# 单文件速度限制
max-upload-limit=0
# 断开速度过慢的连接
#lowest-speed-limit=0
# 设置请求头 referer
#referer=*
# 文件保存路径, 默认为当前启动位置
dir=/home/ubuntu/downloads
# 启用磁盘缓存
#disk-cache=0
# 文件分配方法
#file-allocation=prealloc

配置开机启动

sudo nano /etc/systemd/system/aria2.service
[Unit]
Description=aria2 Service
After=network.target

[Service]
Type=simple
User=www
Group=www
Restart=on-failure
RestartSec=5s
ExecStart=aria2c --conf-path=/etc/aria2/aria2.conf

[Install]
WantedBy=multi-user.target

此时,我们尝试下启动服务

sudo systemctl start aria2

然后查看服务状态

sudo systemctl status aria2

如果Active的状态是 active (running) ,则代表服务运行正常。

那我们就可以直接启用服务了,那么服务就会开机时自动启动。

sudo systemctl enable aria2

开放端口

防火墙放通 6800 端口

sudo ufw allow 6800
sudo ufw enable

imageb714790991761b6e.png

参考资料

从ThinkPHP6.0.2升级到ThinkPHP6.0.3后,测试整体网站,发现用了多对多关联关联统计的地方均报错SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'pivot'。经过排查,系think-orm扩展最近一次的升级,调整了多对多关联导致的错误。

应用代码

下面是关键代码部分

控制器

\app\model\TaskLabel::withCount(['task'])->select()

TaskLabel模型

<?php
namespace app\model;

use think\Model;

/**
 * 任务标签模型
 * @package app\model
 */
class TaskLabel extends Model
{
    // 自动写入时间
    protected $autoWriteTimestamp = 'timestamp';

    // 关闭更新时间
    protected $updateTime = false;

    /**
     * 任务关联
     * @return \think\model\relation\BelongsToMany
     */
    public function task()
    {
        return $this->belongsToMany(Task::class, TaskLabelPivot::class, 'task_id', 'label_id')
            ->where('status', '>', 0);
    }
}

中间表模型

<?php
namespace app\model;

use think\model\Pivot;

/**
 * 任务标签中间表模型
 * @package app\model
 */
class TaskLabelPivot extends Pivot
{
    // 自动写入时间
    protected $autoWriteTimestamp = 'timestamp';

    // 关闭更新时间
    protected $updateTime = false;
}

任务模型

<?php
namespace app\model;

use think\Model;

/**
 * 任务
 * @package app\model
 */
class Task extends Model
{
    // 自动写入时间
    protected $autoWriteTimestamp = 'timestamp';
}

流程解刨

1.执行withCount方法

\think\db\BaseQuery::withCount()

2.执行withAggregate方法

\think\db\BaseQuery::withAggregate()

3.执行relationCount方法

\think\Model::relationCount()

4.执行task方法

\app\model\TaskLabel::task()

5.触发__call方法

因为where是Query里面的方法,在关联类里面不存在,所以会触发魔术方法

\think\model\Relation::__call()

6.执行baseQuery方法

\think\model\relation\BelongsToMany::baseQuery()

7.执行belongsToManyQuery方法

这方法里面会调用Query类的fieldjoinwhere等方法

\think\model\relation\BelongsToMany::belongsToManyQuery()

8.执行getRelationCountQuery方法

\think\model\relation\BelongsToMany::getRelationCountQuery()

9.执行belongsToManyQuery方法

这方法里面会调用Query类的fieldjoinwhere等方法

\think\model\relation\BelongsToMany::belongsToManyQuery()

问题总结

从执行流程可以看出,\think\model\relation\BelongsToMany::belongsToManyQuery()执行了两次,导致的结果就是join也执行了两次,出现了开头的报错SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'pivot'

belongsToManyQuery为什么会执行两次呢?
主要原因就是我在关联方法里面使用了where方法,这个方法是Query类的,在关联类里面不存在,所以会触发魔术方法。
而魔术方法里会执行baseQuerybaseQuery又会执行belongsToManyQuerygetRelationCountQuery也会执行belongsToManyQuery。就这样,join重复了。

问题已找到,关联方法后面不能跟着Query类的方法,否则就会出错。目前尚不清楚是框架的问题还是自己的用法问题,但框架问题的可能性大些,毕竟用法按照手册也报错。

解决办法

虽然找问题的时间很长,但最终的解决办法也很简单,只需要将think-orm扩展降级即可。

composer require topthink/think-orm:v2.0.32

好了,散了散了,该干嘛干嘛去。等官方出结果

2020-07-15:目前最新开发版已修复该问题,除了降级,我们还可以使用下列命令升级到最新开发版。

composer require topthink/think-orm:2.0.x-dev

其它

下面是完整的执行流程记录,备份记录下吧

array(9) {
  [0]=>
  array(5) {
    ["file"]=>
    string(63) "/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php"
    ["line"]=>
    int(687)
    ["function"]=>
    string(18) "belongsToManyQuery"
    ["class"]=>
    string(34) "think\model\relation\BelongsToMany"
    ["type"]=>
    string(2) "->"
  }
  [1]=>
  array(5) {
    ["file"]=>
    string(49) "/vendor/topthink/think-orm/src/model/Relation.php"
    ["line"]=>
    int(249)
    ["function"]=>
    string(9) "baseQuery"
    ["class"]=>
    string(34) "think\model\relation\BelongsToMany"
    ["type"]=>
    string(2) "->"
  }
  [2]=>
  array(5) {
    ["file"]=>
    string(24) "/app/model/TaskLabel.php"
    ["line"]=>
    int(25)
    ["function"]=>
    string(6) "__call"
    ["class"]=>
    string(20) "think\model\Relation"
    ["type"]=>
    string(2) "->"
  }
  [3]=>
  array(5) {
    ["file"]=>
    string(61) "/vendor/topthink/think-orm/src/model/concern/RelationShip.php"
    ["line"]=>
    int(392)
    ["function"]=>
    string(4) "task"
    ["class"]=>
    string(19) "app\model\TaskLabel"
    ["type"]=>
    string(2) "->"
  }
  [4]=>
  array(5) {
    ["file"]=>
    string(64) "/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php"
    ["line"]=>
    int(273)
    ["function"]=>
    string(13) "relationCount"
    ["class"]=>
    string(11) "think\Model"
    ["type"]=>
    string(2) "->"
  }
  [5]=>
  array(5) {
    ["file"]=>
    string(64) "/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php"
    ["line"]=>
    int(325)
    ["function"]=>
    string(13) "withAggregate"
    ["class"]=>
    string(18) "think\db\BaseQuery"
    ["type"]=>
    string(2) "->"
  }
  [6]=>
  array(3) {
    ["function"]=>
    string(9) "withCount"
    ["class"]=>
    string(18) "think\db\BaseQuery"
    ["type"]=>
    string(2) "->"
  }
  [7]=>
  array(3) {
    ["file"]=>
    string(40) "/vendor/topthink/think-orm/src/Model.php"
    ["line"]=>
    int(1047)
    ["function"]=>
    string(20) "call_user_func_array"
  }
  [8]=>
  array(5) {
    ["file"]=>
    string(24) "/app/controller/Task.php"
    ["line"]=>
    int(573)
    ["function"]=>
    string(12) "__callStatic"
    ["class"]=>
    string(11) "think\Model"
    ["type"]=>
    string(2) "::"
  }
}
array(7) {
  [0]=>
  array(5) {
    ["file"]=>
    string(63) "/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php"
    ["line"]=>
    int(379)
    ["function"]=>
    string(18) "belongsToManyQuery"
    ["class"]=>
    string(34) "think\model\relation\BelongsToMany"
    ["type"]=>
    string(2) "->"
  }
  [1]=>
  array(5) {
    ["file"]=>
    string(61) "/vendor/topthink/think-orm/src/model/concern/RelationShip.php"
    ["line"]=>
    int(392)
    ["function"]=>
    string(21) "getRelationCountQuery"
    ["class"]=>
    string(34) "think\model\relation\BelongsToMany"
    ["type"]=>
    string(2) "->"
  }
  [2]=>
  array(5) {
    ["file"]=>
    string(64) "/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php"
    ["line"]=>
    int(273)
    ["function"]=>
    string(13) "relationCount"
    ["class"]=>
    string(11) "think\Model"
    ["type"]=>
    string(2) "->"
  }
  [3]=>
  array(5) {
    ["file"]=>
    string(64) "/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php"
    ["line"]=>
    int(325)
    ["function"]=>
    string(13) "withAggregate"
    ["class"]=>
    string(18) "think\db\BaseQuery"
    ["type"]=>
    string(2) "->"
  }
  [4]=>
  array(3) {
    ["function"]=>
    string(9) "withCount"
    ["class"]=>
    string(18) "think\db\BaseQuery"
    ["type"]=>
    string(2) "->"
  }
  [5]=>
  array(3) {
    ["file"]=>
    string(40) "/vendor/topthink/think-orm/src/Model.php"
    ["line"]=>
    int(1047)
    ["function"]=>
    string(20) "call_user_func_array"
  }
  [6]=>
  array(5) {
    ["file"]=>
    string(24) "/app/controller/Task.php"
    ["line"]=>
    int(573)
    ["function"]=>
    string(12) "__callStatic"
    ["class"]=>
    string(11) "think\Model"
    ["type"]=>
    string(2) "::"
  }
}