使用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 "完成数据库修改."; }