如何把 ThinkPHP 5 的项目迁移到阿里云函数计算来应对流量洪峰?

作者:wxf2305

为什么要迁移到阿里云函数计算

我的项目是一个节日礼品领取项目,过节的时候会有短时间的流量洪峰,而平时访问量很低。之前的架构是购买的阿里云 alb + 多台 ecs + 云 msyql + 云 redis。我最大的困扰就是成本问题。平时流量低的时候 ecs 成本也无法缩减。

阿里云函数计算 FC 是 Serverless,即无服务架构,就比如你的业务流量短时间突然很多,函数计算就会毫秒级别启动多个实例(阿里云函数计算 FC 用来运行函数的最小单元),如果没人访问可以没有实例运行,做到 0 费用。但是有人访问的时候第一次冷启动就稍微慢一点,可以根据实际情况设置最少保留一个实例。

部署到阿里云函数计算 FC,还能减少运行环境搭建的成本。之前的模式需要在 ecs 安装 nginx,然后安装 php,以及安装 php 的驱动程序 redis 等。

看了下阿里云函数计算 FC 官方文档,目前 custom runtime Debian 9 内置 php7.4 并且看了下内置的 php 的扩展整好也支持到了我整好需要的 redis。

不仅省下了买服务器钱!而且还不用安装 php 环境了,更惊喜的是,每个月还有免费的算力额度。

迁移原因总结下:

  • 成本降低了很多;
  • 免去了环境部署;
  • 自动扩容,天生应对高并发。

改造旧项目适配函数计算

代码改动:

虽然说免去了环境部署,但是我之前的代码还是有些不适配的地方,比如之前代码的日志都是存放到服务器的某个目录的。如果迁移到函数计算的话,实例会随时销毁重建,导致日志丢失。

解决办法就是把日志写入到阿里云 oss 上面,或者使用阿里云的日志服务写到那个里面去。

这里还有一点要注意,我的项目不是前后端分离的,鉴权还是穿透的 session 和 cookie 模式。如果 session 是保留在服务端的文件的话也会存在上面的问题,建议存储的 redis 里面,我的项目本省就是存到 redis 里面的,所以这块不需要改动,如果你的项目存在这样的问题那就需要改进下了。

阿里云函数计算 FC 和云 msyql 、云 redis 通讯的时候一定要采用 vpc 内网互通的原则,减少链路传输的开销以及链路劫持风险。

增加 s.yml 以及启动 shell 脚本

配置 s.yml 使用 Serverless Devs 客户端工具发布到阿里云函数计算 FC,Serverless Devs 这个工具并非阿里云的客户端工具,而是一个开源开放的 Serverless 开发者平台,致力于为开发者提供强大的工具链体系。

通过该平台,开发者不仅可以一键体验多云 Serverless 产品,极速部署 Serverless 项目,还可以在 Serverless 应用全生命周期进行项目的管理,并且非常简单快速的将 Serverless Devs 与其他工具/平台进行结合,进一步提升研发、运维效能。

官网地址:

https://www.serverless-devs.com/

然后看下我的 s.yml 里面的配置信息,具体的说下重要项是干嘛的。

edition: 1.0.0
name: compoent-test
access: 'default'
services:
  cn-hangzhou-test1002-func-3i3c0f95:
    component: devsapp/fc
    props:
      region: cn-hangzhou
      service:
        logConfig:
          enableRequestMetrics: true
          enableInstanceMetrics: true
          logBeginRule: DefaultRegex
          project: aliyun-fc-cn-hangzhou-ae3ef8b8-db4a-5b7a-a040-7012789ad20f
          logstore: function-log
        role: acs:ram::1621341641365186:role/AliyunFcDefaultRole
        internetAccess: true
        name: test1002
      function:
        customRuntimeConfig:
          command:
            - bash
          args:
            - '-c'
            - 'chmod 777 /code/start.sh && /code/start.sh'
        handler: index.handler
        instanceType: e1
        runtime: custom
        timeout: 5
        instanceConcurrency: 20
        memorySize: 512
        caPort: 9000
        environmentVariables: {}
        internetAccess: true
        name: func-3i3c0f95
        asyncConfiguration: {}
        codeUri: ./test1002/func-3i3c0f95
      triggers:
        - name: defaultTrigger
          description: ''
          type: http
          qualifier: LATEST
          config:
            methods:
              - GET
              - POST
              - PUT
              - DELETE
            authType: anonymous

1.jpeg

codeUri: ./test1002/func-3i3c0f95这个指定的是我的项目代码的位置,会把这个目录下面的代码拷贝到 debain系统的 /code目录下面。
        customRuntimeConfig:
          command:
            - bash
          args:
            - '-c'
            - 'chmod 777 /code/start.sh && /code/start.sh'

这句话的是项目启动脚本,其实就是执行这个 start.sh 的 shell 脚本,先给予一个 777 的权限,然后在执行。

翻译成 shell 脚本其实就是 bash -c 'chmod 777 /code/start.sh && /code/start.sh'

2.jpeg

caPort: 9000

监听端口 9000 一定要和启动脚本 start.sh 里面的一样。

#!/usr/bin/env bash
cd /code/tp5/public
php -S 0.0.0.0:9000 router.php

这里我觉得我还是要说下这个启动脚本,先 cd 到 public 目录,ThinkPHP 5 的入口在 public下面这个和项目框架有关系。然后就是这个启动脚本,上面这是ThinkPHP 5 特有的写法。

其他项就不详细说了,大概看看应该能看懂。

使用客户端工具发布

工具的安装就忽略了不说了,看下官方文档说的很详细:

https://docs.serverless-devs.com/serverless-devs/quick_start

Serverless Devs 这个工具安装好后,配置配置上阿里云的 AccessKey ID 和 AccessKey Secret,在项目根目录建立 s.yml,以及在代码目录建立上面的启动脚本 start.sh 然后就可以使用客户端工具的 s deploy 部署到阿里云函数计算了。

3.jpeg

发布成功了。

绑定自己的域名

4.jpeg

把自己的域名 cname 到上图的 “公网 cname”

https://fcnext.console.aliyun.com/cn-hangzhou/domains/create

然后 “服务名称” “测试函数”  版本都对应选择正确,创建即可。

5.jpeg

部署成功了,哈哈。

谈下自己的感受

Serverless 是以后的趋势,开发者能够有更多的精力去关注业务层。从开始预计迁移到代码的修改以及阿里云函数计算 FC 文档查阅,到迁移成功,花费了大概 3 天的时间,对阿里云函数计算 FC 有了更深层次的认知。

同时也期待迁移过来的项目在下次使用高峰的时候能够稳定运行。我后面也会随时关注阿里云函数计算 FC 的动态,同时感谢阿里云函数计算 FC 团队能做出来这么优秀的产品。

点击此处,查看更多产品内容~

posted @ 2022-11-14 16:12  阿里云云原生  阅读(58)  评论(0编辑  收藏  举报