一、项目需求
近期因为项目有自动执行函数的需求。一开始采用的是阿里云函数计算的“处理HTTP请求”方式部署,在这种方式下面,函数只能创建一个 HTTP 类型的触发器,且 HTTP 函数只能添加 HTTP 触发器,不支持创建其他类型的触发器,要触发函数,需要另外进行调用,适合做http服务的功能,比如WEB\APP\小程序等的API服务。所以需要自动执行的话,就采用了另外购买一个ECS,使用crond定时使用crul访问函数的方式,这样就增加了另外的ECS成本。后来发现阿里云函数计算“处理事件请求”的模式下,可以建立定时自动触发器,在函数计算里面就可以根据需要自动进行触发调用,无需其它功能配合,并且不建立对外调用HTTP连接接口,安全性上也更有保障,于是着手把之前的HTTP函数转换成事件请求函数。
* HTTP请求函数与事件请求函数的简单功能对比
| 功能 | HTTP函数 | 事件请求函数 |
| 触发器 | 一个HTTP 触发器 | 多个不同类型的触发器(定时、与阿里云其它产品事件联动) |
| 访问 | 绑定域名访问url | 函数触发器调用,无需域名等 |
| 自动执行 | 其它CURL、API调用程序 | 函数计算自带定时触发器自动执行 |
二、部署步骤(在阿里云PC控制台页面内直接部署)
1、创建函数
(1)、在阿里云函数计算控制台页面内,创建好服务之后,进入服务的“函数管理”功能页面。在这里“创建函数”。

(2)、函数创建的参数,见下图


2、设置请求路由
(1)、函数创建完成之后,即会进入到函数详情页面。基本的ThinkPHP代码已经部署好了。下图为基本的目录文件结构

(2)、创建请求路由映射
创建函数时有提示:当函数是事件请求处理程序时,Http Server 仅需实现 Path 为 /invoke 和 Method 为 POST 的对应逻辑即可。
这句话的意思就是,执行函数时,只有一个唯一的请求入口路径: /invoke 携带POST请求参数过来,我们需要在函数里面实现这个接收方法。但是此时thinkphp的应用(app目录)里面并没有这个方法,且请求路径还没有控制器。此时测试函数,是会报错的。
接下来就需要通过thinkphp的自定义路由,将此路径映射到app的默认首页入口。首先在webide里面打开左侧文件列表“route/app.php”,注释掉原来的路由规则,添加一个路由规则,将invoke请求转到 Index/index去处理。
路由规则:Route::rule('Invoke', 'Index/index', 'POST'); 修改后截图如下:

3、接收处理请求
将函数的请求转发到“Index/index”方法后,需要在方法里面去接收函数计算POST过来的数据。此数据的格式为一个json数据,数据示例如下:
{
"triggerTime": "2024-11-27T11:46:14Z",
"triggerName": "test",
"payload": "自定义参数"
}
此数据,前两个参数为定时触发器的执行时间和定时任务名称。第三个“payload”,是重点需要解析的数据,是调用函数时,自己需要传入的参数。我这里为了在index方法里面,自动根据参数名称调用对应的函数,就定义了一个自己的参数格式,同样是json格式:
{
"triggerTime": "2024-11-27T11:46:14Z",
"triggerName": "test",
"payload": "{\"functionName\": \"test\",\"params\": \"Hello world!\"}"
}
在WEBIDE里面打开app\controller\Index.php,将里面原来的代码删除,替换为以下代码:
<?php
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
public function index()
{
//获取定时事件请求参数
$data = file_get_contents('php://input');
$data = json_decode($data,true);
/******打印请求参数*******/
echo "Request data is: ".PHP_EOL;
print_r($data);
echo PHP_EOL.PHP_EOL;
/******判断请求参数是否为空*******/
if(!$data || !isset($data['payload'])){
return 'No data post'.PHP_EOL;
}
//解析自定义传入的参数,格式为JSON:'{"functionName":"test","params":"123456"}'
$payload = json_decode($data['payload'],true);
//print_r($payload);
if(!isset($payload['functionName'])){
return 'No functionName'.PHP_EOL;
}
//获取要调用的函数名称
$methodName = $payload['functionName'];
if (method_exists($this, $methodName)) {
//判断是否传入了参数
if($payload['params']){
$this->$methodName($payload['params']);
}else{
$this->$methodName();
}
} else {
echo "Function [".$methodName."] does not exist.";
}
}
private function test($params){
echo "You called the test function.".PHP_EOL;
echo "Input params is: ".$params;
return "success";
}
}
此代码将通过入口Index/index方法,根据传入的参数functionName,自动调用与参数值相同名称的函数,已达到执行不同的功能的目的。例如,要调用test2方法,那么,在Index类里面,创建一个test2方法,调用参数改为:
"payload": "{\"functionName\": \"test2\",\"params\": \"你的参数。也可以为空\"}"
保存,部署代码。
4、运行测试
配置测试参数:点击编辑器上部左侧,“测试函数”的下拉箭头,选择“配置测试参数”,输入上方的测试参数,如图所示

保存之后,点击“测试函数”按钮,即会在上方显示测试运行结果。如下图:

5、建立定时任务
测试完成之后,即可根据需要建立定时任务,自动执行函数,愉快滴完成需要的功能了。
找到上方的“触发器管理”选项卡,点击进入触发器功能界面。
创建触发器。这里我们要创建一个自动执行的定时触发器,参数设置如下图(为了测试自动执行,设置了时间间隔2分钟,根据自己需求进行设置,可设置间隔、日期、星期、自定义等):

确定参数之后,保存即可。 在下面即会出现建立的触发器。
6、打开任务模式
要自动执行定时触发器任务,需要打开函数计算的任务模式。

7、查看定时任务执行结果
等待几分钟后,即可去“异步任务列表”查看定时任务自动调用执行结果。列表里面列出了自动执行调用记录,点击右侧“查看详细”可以看到执行结果及参数等内容。

至此,整个部署及定时任务执行流程就完成了。基础调用入口也建立好了,可以在Index类里面建立不同功能的方法函数,在触发器里面建立不同需求的定时触发器进行触发,实现不同的功能。
阿里云为首次登录函数计算控制台的用户,提供一定额度的免费试用包,请愉快滴玩耍!
677





