开发函数计算的正确姿势 —— 开发 WordPress 应用

  1. 云栖社区>
  2. 博客>
  3. 正文

开发函数计算的正确姿势 —— 开发 WordPress 应用

倚贤 2019-01-01 22:12:34 浏览1233 评论1

摘要: 前言 首先介绍下在本文出现的几个比较重要的概念: __函数计算(Function Compute)__: 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。

前言

首先介绍下在本文出现的几个比较重要的概念:

__函数计算(Function Compute)__: 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息 参考

__Fun__: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。Fun 的更多文档 参考

__Fun Local__: Fun Local 作为 Fun 的一个子命令存在,可以直接通过 fun local 命令使用。Fun Local 工具可以将函数计算中的函数在本地完全模拟运行,并提供单步调试的功能,旨在弥补函数计算相对于传统应用开发体验上的短板,并为用户提供一种解决函数计算问题排查的新途径。

备注: 本文介绍的技巧需要 Fun 版本大于等于 2.8.0。

声明:本文基于 十分钟上线-函数计算玩转 WordPress 提供的思路开发 wordpress 应用。

创建 fun 项目

创建一个目录作为 fun 项目的根目录,然后创建一个 index.php 编写函数代码:

<?php
use RingCentral\Psr7\Response;

function startsWith($haystack, $needle) {
    $length = strlen($needle);
    return (substr($haystack, 0, $length) === $needle);
}

function handler($request, $context): Response{
    $uri    = $request->getAttribute("requestURI");
    $uriArr = explode("?", $uri);

    // default php / or /wp-admin/
    if (preg_match('#/$#', $uriArr[0]) && !(strpos($uri, '.php'))) {
        $uriArr[0] .= "index.php";
        $uri = implode($uriArr);
        if (startsWith($uri, "/2016-08-15/proxy/share/wp-func/wp-admin/")) {
            // wordpress admin entrypoint
            $request = $request->withAttribute("requestURI", $uri);
        }
    }

    $proxy    = $GLOBALS['fcPhpCgiProxy'];
    $root_dir = '/mnt/www';
    
    //php script
    if (preg_match('#\.php.*#', $uri)) {
        $format = '%s.%s.fc.aliyuncs.com';
        $host   = sprintf($format, $context['accountId'], $context['region']); // maybe user define domain
        $resp   = $proxy->requestPhpCgi($request, $root_dir, "index.php",
            ['SERVER_NAME' => $host, 'SERVER_PORT' => '80', 'HTTP_HOST' => $host],
            ['debug_show_cgi_params' => false, 'readWriteTimeout' => 15000]
        );
        return $resp;
    } else {
        // static files, js, css, jpg ...
        $filename = $root_dir . explode("?", $uri)[0];
        $filename = rawurldecode($filename);
        $handle   = fopen($filename, "r");
        $contents = fread($handle, filesize($filename));
        fclose($handle);
        $headers = [
            'Content-Type'  => $proxy->getMimeType($filename),
            'Cache-Control' => "max-age=8640000",
            'Accept-Ranges' => 'bytes',
        ];
        return new Response(200, $headers, $contents);
    }
}

然后创建 template.yml:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  share:
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'fc wordpress test'
      Policies: 
        - AliyunECSNetworkInterfaceManagementAccess
      VpcConfig:
        VpcId: 'vpc-bp12hm92gdpcjtai7ua82'
        VSwitchIds: [ 'vsw-bp1gitru7oicyyb4uiylj' ]
        SecurityGroupId: 'sg-bp1243pi65bw4cjj4bks'
      NasConfig: 
        UserId: -1
        GroupId: -1
        MountPoints: 
          - ServerAddr: '012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com:/'
            MountDir: '/mnt/www'

    wp-func:
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        Runtime: php7.2
        CodeUri: './index.php'
        Timeout: 100
      Events:
        http-test: # trigger name
          Type: HTTP # http trigger
          Properties:
              AuthType: ANONYMOUS
              Methods: ['GET', 'POST', 'PUT']

我们在 template.yml 中描述了 VPC、NAS 服务,以及 HTTP Trigger。至此,我们的函数就开发完了,在发布到线上前,我们需要先在本地调通。

通过执行 fun local start 可以将函数计算在本地模拟启动:

打开提示的 url,会得到错误提示:

这是因为我们没有安装 wordpress 的缘故。我们需要将 wordpress 安装到 NAS 挂载的目录上。fun local 对 NAS 的支持可以 参考。我们需要通过以下几步来让函数能够访问到 wordpress 应用:

  1. 下载 wordpress
  2. 解压下载的 wordpress。
  3. 将解压后的 wordpress 内容复制到本地模拟的 NAS 目录。

对于我们的项目,本地模拟的 NAS 目录为:.fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/。这个目录在函数运行时,会被挂载到容器的 /mnt/www 下。函数可以直接访问该目录。

对于 wordprss 应用,我们需要在 .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/ 下依次创建子目录:2016-08-15/proxy/share/wp-func

可以直接通过命令完成:

mkdir -p .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/2016-08-15/proxy/share/wp-func

然后将解压后的 wordpress 的内容复制进来,也可以通过类似的命令完成:

cp -r wordpress/ .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/2016-08-15/proxy/share/wp-func/

操作完成后,不需要重启服务,直接刷新页面即可。

打开页面会显示配置向导,按照向导提示配置数据库、用户信息即可。

注意: 本地开发时,如果使用的 RDS,需要申请外网地址,并设置 IP 白名单为:0.0.0.0/0。但由于 0.0.0.0/0 表示允许任何设备访问 RDS 实例,除非是测试,否则不太推荐这么做。更好的做法是在本地使用 mysql 进行开发。由于函数是运行在 docker container 中的,网络环境与宿主机是隔离的,因此需要将本地 mysql 配置为允许任何 ip 访问。可以 参考

以下是一个 wordpress 本地启动后的效果演示:

本文作者:小默

【云栖快讯】阿里巴巴小程序繁星计划,20亿补贴第一弹云应用免费申请,限量从速!  详情请点击

网友评论