使用阿里云函数计算将 WordPress 变成按量的 ServerLess 服务
本文最后更新于 1831 天前,其中的信息可能已经有所发展或是发生改变。

前面有大段函数计算的概念介绍,如果大家觉得没有意义的可以直接跳到教程那一块进行操作。

前言

如果玩云计算比较早的其实都会知道在公有云大火之前,有一种 PaaS 模式是非常火的,也就是各种 APP Engine,比如说最早做的谷歌GAE、新浪SAE,后期的阿里云ACE和百度云BAE,但是现在来看我们都知道其结果,他们都不行了,尽管在当时看来 App Engine 是对虚拟主机和物理服务器的一场革新,但是体验不好就是不行。

ServerLess (无服务器化)是最近很火的一个概念,让我想起了曾经的 APP Engine,但是随着 ServerLess 的不断发展其实我们可以发现,ServerLess 已经变得和传统服务器一样好用了,受到的限制也随着版本的迭代服务的升级变得越来越少。

无服务器发展简史

上图是 ServerLess 发展的小简史,网站背后的运行技术服务的发展其实就像是我们对物质从分子到原子到电子、夸克的理解:

  1. 物理服务器时代,从大型机、小型机中脱离开来,1U、2U的服务器就可以支撑我们的服务,同时将服务器托管给IDC机构,不再考虑机房的建设维护问题,典型应用是 服务器租赁托管和虚拟主机。

  2. 虚拟化时代,我们使用 XEN、KVM等虚拟化技术,隔离了硬件以实现操作系统级别的隔离,让服务器的购买更加优惠同时粒度更细,我们以 CPU、内存计费并以月计费,不再考虑物理服务器采购和维护的问题,典型应用是 VPS。

  3. 云计算时代,我们使用云计算进一步地自动管理这些虚拟化的资源,更安全更便捷同时也更便宜,不仅仅可以将服务器拆的更细,也能将多台服务器整合成一台超性能服务器,同时计费粒度到了小时级别。 不仅仅是服务器,数据库、存储等等我们都不再考虑实施部署的问题,典型应用是各类云计算产品,特别是云数据库、云存储等。

  4. 容器化时代,我们使用 Docker、k8s 等容器技术,通过微服务的拆解将应用粒度变得更细腻,维护和实施变得更加方便。典型应用是各大企业开发能力、效率提升。

现在,我们有了 Serverless,一种粒度更细的形式出现了,我们以 计算 * 时间 的方式计费,同时又获得了将应用拆解的更加细腻的方式,让我们无需考虑任何后端的问题,随着请求的增长,ServerLess 会自动进行伸缩,而不像传统云服务一样要自行搭建负载均衡和配置可扩展的无状态环境,开发人员不用考虑服务器的安全问题,不用考虑Docker的部署问题,不用考虑 Runtime 调优、升级、安全等问题等等。

当然了,ServerLess 远不是那么简单的产品,我也只是浅浅的了解了一层。

介绍

ServerLess 在阿里云上是 函数计算(Function Compute)是一个事件驱动的全托管计算服务。这里是介绍:

通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码。更棒的是,您只需要为代码实际运行消耗的资源付费 – 代码未运行则不产生费用。

如果要搜索一些 ServerLess 的中文教程,或者阿里云函数计算的相关教程,个人建议就用 函数计算 代替 ServerLess 来避免大量搜到其他比不要的 ServerLess 教程的噪音。

下面是传统方式搭建服务和 ServerLess 的对比:

项目开发效率传统方式搭建服务函数计算方式
采购服务器等基础设施需要不需要
管理服务器等基础设施需要不需要
开发业务服务模块需要需要
部署业务服务模块需要需要,但是很简单,提供了很多工具
通过 nginx 搭建反向代理、https 和负载均衡需要不需要,通过阿里云 API 网关或函数 HTTP 触发器可以实现
搭建相关日志服务需要不需要,通过日志开关开启日志服务
配置安全访问规则需要不需要,自带基础安全访问配置,API 网关提供更多的配置
运维负担
开发效率高,通常几天就能完成
Serverless传统方式搭建服务
维护成本维护成本低,无需管理服务器等基础设施,只需编写代码并上传,程序员从底层设备维护中解放出来,只考虑实际业务逻辑即可。维护成本高,自行维护服务器,需要处理服务器宕机、服务器扩容等一系列底层琐碎的事情
可用性可用性高,函数计算为用户准备弹性、可靠的计算资源,具有根据流量自动scale特性,对有明显波峰波谷的运用效果奇佳服务器故障会对应用服务产生严重影响
费用按需付费,只为实际使用的计算资源付费,代码未运行则不产生费用需要支付服务器的费用,代码运行与否都要收费

不足

当然了 ServerLess 是很诱人,但却不是万能的,有些场景还是不适合的。

  1. ServerLess 不仅仅是一门技术也是一种理念和微服务一样,很多老系统不能直接上 ServerLess,得相应的进行升级和拆解才能更好的适应 ServerLess,这是一个门槛。
  2. 同时 ServerLess 针对开发语言的可定制性和可开放性,ServerLess 会选择处于稳定版的语言且更新具有一定的滞后性,特别是 Node.JS 这样的版本更新帝,最新稳定版是10,但是提供的却是8。同时如果对语言有底层的修改而无法通过 Plugin 实现同样也无法适应相关场景。
  3. 不适合长时间的进行计算处理的场景,ServerLess 是产生计算后按时间计费的,适合那些触发类短时间计算的,如果有长时间进行计算的场景就不适合。

教程

本次教程,我们将介绍如何在阿里云的 ServerLess 产品中部署 WordPress。 因为在博客这种计算量小的场景也是比较适合放在 ServerLess 中的,不过因为 WordPress 的插件库又很丰富用了不同的插件完全可以实现不同的场景功能,所以到底适不适合放还得评估一下。

enter description here

如上图所示,函数计算代替了像 Apache Httpd、Nginx 之类的传统 Web 服务软件本身,用户函数代替了Web 服务软件的 .conf 配置文件。 PHP Runtime 代替 PHP 这个就很好理解了。然后 NAS 则作为存储文件并提供写入的地方,不然像 APP Engine 一样无法进行写入操作就很难操作了。

准备

一、 函数计算FaaS,可按量付费,有免费额度

二、 文件存储NAS,可按量付费

三、 云数据库RDS

四、 日志服务LOG(可选),可按量付费,有免费额度

每个产品都开设在同一个地域同一个 VPC 下。

动手吧

NAS

因为文件托管需要依赖 NAS,所以得开通 NAS。

一、进入 NAS 控制台 https://nas.console.aliyun.com/

二、 选择好地域后,创建文件系统

enter description here

三、存储类型建议还是用 SSD性能型,因为 NAS 的读写性能相比云盘还是有些低的,NAS 只要地域对任何可用区都可以挂载使用。

enter description here

四、创建完之后 添加挂载点

enter description here

五、选择专有网络,选择好对应的VPC网络和交换机,权限组选择 全部允许

enter description here

函数计算

一、进入函数计算控制台 https://fc.console.aliyun.com

二、选择地域后创建新的函数服务

enter description here

三、开启高级配置,开通公网访问,不然网站都打不开:

enter description here

四、需要配置专有网络,在专有网络下才能更安全的使用函数计算并整合其他云产品。

enter description here

五、配置NAS的用户(uid)和用户组(gid),例如我填的是 10005,这个用在到时候 chown 给予权限上,然后选择之前创建过的 NAS挂载点,本地目录选择挂载在 /mnt/www

enter description here

六、日志配置建议就只是选择空白项目和空白仓库好了,日志服务是有一定免费的额度的。 当然不开也不影响服务运行。

enter description here

七、相关服务间的调用需要进行授权,所以我们可以选择 新建角色 ,在系统模板授权中勾选服务所需要的系统授权,然后如图中搜索 AliyunECSNetworkInterfaceManagementAccess 权限,并选择。

enter description here

八、然后会跳转到 角色快捷创建 的页面,也不用管太多,直接 同意授权 即可。

enter description here

九、返回后就是授权成功了。

enter description here

十、点击创建即可,成功了就直接成功了,如果返回说:

VSwitch 'vsw-2zenbov6s8r8kwad6c0bd' is in unsupported zone 'cn-beijing-e' (allowed zones: cn-beijing-c)

意思就是说目前函数计算只支持创建在 cn-beijing-c 的专有网络·虚拟交换机。 不同的地域具体支持的可用区可能不同。 在专有网络哪里创建一个 allowed zones: xxxxx 可用区的虚拟交换器然后重新创建函数计算即可。

十一、然后新建函数

enter description here

十二、选择创建一个空白函数

enter description here

十三、选择创建 HTTP 触发器,认证方式选择 anoymous,请求方式全部勾选

enter description here

十四、运行环境选择 PHP 7.2,不然怎么跑 WordPress

enter description here

十五、代码配置这块,选择 在线编辑,贴入下面我提供的代码即可。

enter description here

<?php
use RingCentral\Psr7\Response;

function endsWith($haystack, $needle) {
    $length = strlen($needle);

    return $length === 0 ||
        (substr($haystack, -$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);
    }

    $proxy    = $GLOBALS['fcPhpCgiProxy'];
    $root_dir = '/mnt/www';

    //php script
    if (preg_match('#\.php.*#', $uri)) {
        $host   = "pressless.mf8.biz"; // 此处填写你的域名
        $resp   = $proxy->requestPhpCgi($request, $root_dir, "index.php",
            ['HTTP_HOST' => $host, 'SERVER_NAME' => $host, 'SERVER_PORT' => '80'],
            ['debug_show_cgi_params' => false, 'readWriteTimeout' => 60000]
        );
        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);
    }
}

注意:

第25行需要修改为你自己的域名

$host   = "pressless.mf8.biz"; // 此处填写你的域名

其他的环境配置,比如说内存大小、超时秒数都可以自行设置。

十六、授权这块因为一开始我们就创建过,所以可以直接下一步,如果应用比较复杂那么就再修改一下。

enter description here

十七、在触发器中点击之前创建好的 wp-func 触发器

enter description here

十八、可以看到这边又配置自定义域名的位置

enter description here

十九、然后点击创建域名

enter description here

二十、填写域名名称就是域名这个没毛病。 然后路由设置中,路径填写:/*,然后函数就选择之前创建的触发器的函数。

enter description here

二十一、然后会提示你下面的:

domain name 'pressless.mf8.biz' has not been resolved to your FC endpoint, the expected endpoint is '1572623648803837.cn-beijing.fc.aliyuncs.com.'

意思就是咱们得先把域名解析到提示的:1572623648803837.cn-beijing.fc.aliyuncs.com 上才行。

那我就把我要绑定的 pressless.mf8.biz域名CNAME解析到 1572623648803837.cn-beijing.fc.aliyuncs.com上就行。

二十二、接下来就是上传WordPress程序了,这时候需要就需要继续用到 NAS 了。鉴于新建一个转移函数迁移压缩包内容到NAS很多人不太会,所以我更建议开一台按量的 ECS 挂载NAS然后通过SFTP进行可视化操作。 当然还可以拿这台 ECS 来做数据库服务器在前期可以降低购买云数据库的成本。

例如我通过下面的命令将 NAS 通过 NFS 的方式挂载至 /mnt 目录下:

mount -t nfs -o vers=4.0 16d3e4b609-cub21.cn-beijing.nas.aliyuncs.com:/ /mnt

enter description here

二十三、访问我们绑定的域名,例如我是:http://pressless.mf8.biz

enter description here

二十四、那我这里就通过 ECS 自建的 MySQL 数据库,然后内网地址连接是可以进行正常连接和安装的。 如果是通过云数据库的话,那么需要在白名单哪里添加 0.0.0.0/0,同样的ECS自建也要保证专有网络内网内可以被访问。

enter description here

二十五、如果我们安装WP插件和升级WP遇到了需要填写FTP的要求的话,我们别忘了之前我们创建函数服务的时候有填写过 uid 和 gid。

enter description here

那我们还得在 ECS 中进行操作。

chown -R 10005:10005 /mnt/*

因为我之前设置过的 uid 和 gid 是 10005,所以这里写的是 10005,大家可以自己顶一,然后NAS挂载在 /mnt 目录下,所以是 /mnt/*

总结

就这样我们完成了一个 WordPress 的 ServerLess 化,因为大家都是第一次接触所以教程写的很细步骤很多,自己踩的坑都写了一遍。

WordPress 的 ServerLess 化下一步应该是进行前后端分离通过 API 通信来减少动态请求减少函数的计算。

然后现在函数计算还不支持 Rewrite(伪静态),不过相关技术应该是可行的,大家可以给我的这条聆听点个赞:【功能建议】函数计算ServerLess添加对Rewrite(伪静态)的支持

再然后其实函数计算还需要一款按量计费的ServerLess化的关系型数据库,因为 TableStore 是支持按量的 NoSQL,同样这是聆听建议的链接:【功能建议】数据库体系中还需要一款能按量使用的关系型数据库,可以是 POLARDB ServerLess

评论

  1. 5年前
    2018-12-07 14:07:36

    点赞!这操作有点骚,想法很奇特!

    • 妙正灰
      博主
      Quanyin
      5年前
      2018-12-07 16:23:24

      就是骚 就是干

本文评论已关闭
上一篇
下一篇