本文介绍了如何将传统的php nginx的laravel框架搭建的web项目如何迁移部署到云函数的过程,对于原理如果清楚了的话,同样可以应用到其他的框架上。对比于传统方式,Serverless有以下的一些优点:
知识点
- 如何将laravel框架改造部署到云函数
- 如何实践crm系统部署云函数的整个流程
步骤一:准备工作(环境搭建)
- IDE:phpstorm,sublime,zend studio等。链接(https://www.jetbrains.com/phpstorm/)
- laravel框架的crm系统代码包
步骤二:laravel框架代码改造和入口函数实现
1 在代码根目录下新建一个index.php作为函数的入口文件,入口函数为标准的$event, $content入参格式,代码如下:
<?php
function main_handler($event, $context) {
print "start main handlern";
}
?>
2 入口函数index.php文件增加静态文件路由请求处理,静态文件通过api网关请求的path路径路由到不同的文件,读取本地内容返回给api网关。
if (preg_match('#.html.*|.js.*|.css.*|.html.*#', $event->path) || preg_match('#.gif.*|.jpg.*|.png.*|.jepg.*|.swf.*|.bmp.*|.ico.*#', $event->path)) {
$filename = "/var/user/public" . $event->path;
echo $filename;
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
echo $contents;
fclose($handle);
if (preg_match('#.gif.*|.jpg.*|.png.*|.jepg.*|.swf.*|.bmp.*|.ico.*#', $event->path)) {
return array(
"isBase64Encoded" => true,
"statusCode"=> 200,
"headers"=> [
'Content-Type' => '',
'Cache-Control' => "max-age=86400",
],
"body"=> base64_encode($contents),
);
} else {
return array(
'isBase64Encoded' => false,
'statusCode' => 200,
'headers' => [
'Content-Type' => '',
'Cache-Control' => "max-age=8640000",
'Accept-Ranges' => 'bytes',
],
'body' => $contents
);
}
}
3 laravel框架改造,由于laravel写缓存和日志是分别写在storage/framework和storage/logs目录下面,而对于云函数为了保证代码包一致性,对于代码包目录是不可写的,我们需要将日志和缓存写到/tmp临时目录下面,同时为了将日志能够输出到控制台,需要将框架修改如下:
3.1 缓存目录重写定义目录,修改bootstrap/app.php文件,增加如下代码,将缓存目录写到/tmp目录下:
$path_storage = "/tmp";
$app->useStoragePath($path_storage);
并在vendorlaravelframeworksrcIlluminateFoundationApplication.php文件修改bootstrap缓存文件目录:
return '/tmp'.($path ? DIRECTORY_SEPARATOR.$path : $path);
同时在入口函数index.php文件,新建这些目录
system("mkdir -p /tmp/cache");
system("mkdir -p /tmp/logs");
system("mkdir -p /tmp/framework/sessions");
system("mkdir -p /tmp/framework/cache");
system("mkdir -p /tmp/framework/views");
system("chmod -R 755 /tmp");
3.2 日志打印到控制台便于调试,在/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php增加一条echo将日志打印到云函数控制台
echo (string) $record['formatted'];
4 php文件路由,走本来配置好的路由。在入口函数index.php文件最后增加如下函数即可。
require __DIR__.'/bootstrap/autoload.php';
$app = require __DIR__.'/bootstrap/app.php';
$req = $event->body;
$data = !empty($req) ? json_decode($req, true) : [];
$event->path = str_replace("//", "/", $event->path);
$kernel = $app->make(IlluminateContractsHttpKernel::class);
$request = IlluminateHttpRequest::create($event->path,$event->httpMethod,$data, [], [], []);
$response = $kernel->handle(
$request
);
$content = $response->getContent();
$headers = [
'Content-Type' => '',
];
return array(
'isBase64Encoded' => false,
'statusCode' => 200,
'headers' => $headers,
'body' => $content
);
步骤三:部署代码到云端,在线调试
- 打包整个项目代码包,在控制台上传代码,指定入口函数
- 创建和修改api网关触发器(步骤详细)
1 创建一个api网关触发器,选择集成响应,保存:
2 编辑api网关触发器,修改目录到根目录:
3 修改后需要发布一下
- 在线调试,访问 https://service-ivupdw2r-1253970226.ap-shanghai.apigateway.myzijiebao.com/test/index.html(注意域名替换为自己的) 查看系统跑在云函数上的实际效果,如果有错误可在控制台查看错误日志找出错误原因