使用Serverless的原因之一,就是轻量任务响应,不需要一个长期运行的服务器,如果说还要买RDS,就违背我原来想省钱的初衷了,所以我想起了COS+SQLite方式.
优点:
- 节约成本,近似免费,SQLite数据库文件极小,通常少量到连COS储存费用都是免得,9.9分钱1GB,可能数据库不到128M,完全免费,就算付费也就几分钱一个月,比RDS等节约大量成本.
- 无服务器,不需要自己准备服务器,跟Serverless一样,无需服务器支持,而且随时可以提供网关访问,还不用考虑带宽不够问题.
- 内网互访,不需要支付公网费用.
- 节约内存,基本可以忽略的内存开销.
缺点:
- COS获取,取得带宽是个问题,内网取回大概需要20毫秒,上报大概需要30毫秒.
- 加锁机制不太完美,总有概率发生互相抢的问题.
- 受限于SCF的临时目录影响,数据库不能大于512M,不过这个还是比较难遇到的.
<?php
require 'cos-php-sdk-v5/vendor/autoload.php';
$appid = 1253440000;//这里填写APPID
$secret_id = ''; //不用解释
$secret_key = ''; //不用解释
$region = 'ap-guangzhou';
$bucket = "db" . '-' . $appid;
$db_location = '/tmp/sqlite.db';
$db_key = "ExampleObject";
$cosClient = new QcloudCosClient(array(
'region' => $region,
'credentials' => array(
'secretId' => $secret_id,
'secretKey' => $secret_key
)
));
class MyDB extends SQLite3
{
function __construct()
{
global $cosClient;
global $bucket;
global $db_location;
global $db_key;
try {
$result = $cosClient->getObject(array(
'Bucket' => $bucket,
'Key' => $db_key,
'SaveAs' => $db_location
));
} catch (Exception $e) {
return "数据库已锁,暂时无法操作."; //找不到数据库文件可能是其他文件正在访问数据,只读的话,可以访问只读副本.
}
//删除数据库文件,这样别人就拉取不了,相当于上锁.
$cosClient->deleteObject(array(
'Bucket' => $bucket,
'Key' => $db_key,
));
$this->open($db_location);
}
}
function main_handler($event, $context)
{
global $cosClient;
global $bucket;
global $db_location;
global $db_key;
$db = new MyDB();
$sql =<<<EOF
SELECT * from COMPANY;
EOF;
$ret = $db->query($sql);
while($row = $ret->fetchArray(SQLITE3_ASSOC)){
print_r($row);
}
$db->close(); //执行查询后关闭数据库.
try {
$cosClient->putObject(array(
'Bucket' => $bucket,
'Key' => $db_key,
'Body' => fopen($db_location, 'rb')
));
//操作完成就上传数据库,如果数据很要紧,可以上传一个备份,用于只读.
} catch (Exception $e) {
return "无法完成数据库上传.";
}
return "完成数据库修改.";
}