基于 Serverless Framework 的人工智能小程序开发( 二 )


  • Plugin 部署到线上的函数会自动变更名字,例如函数是 myFunction,服务和阶段是 myService-Dev,那么函数部署到线上就是 myService-Dev-myFunction,这样的函数名,很可能会让函数间调用等部分产生很多不可控因素 。例如现在的环境是 Dev,函数间调用就要写函数名是 myService-Dev-myFunction,如果环境是 Test,此时就要写 myService-Test-myFunction,我始终觉得,更改环境应该只需要更改配置,而不是更深入的代码逻辑 。
  • Plugin 也是有优势的,例如 Invoke、Remove 以及部署单个函数的功能,同时 Plugin 也有全局变量,这更像是一个开发者工具,可以开发、部署、调用、查看一些信息、指标,删除回滚等操作也可以通过 Plugin 完成;
  • Components 可以看作是一个组件集,这里面包括了很多的 Components,既有基础的 Components,例如 cos、scf、apigateway 等,也有一些拓展的 Components,例如在 cos 上拓展出来的 website,可以直接部署静态网站等,还有一些框架级的,例如 Koa、Express 等;
  • Components 除了支持的产品多,可以部署框架之外,更有吸引力的是其部署到线上的函数名字就是我指定的名字,不会出现额外的东西;
  • 相比 Plugin,Components 在功能上略显单薄,除了部署和删除,再没有其他功能了 。如果有多个功能要部署,并写在了一个 Components 的 yaml 上,那么每次部署都要部署所有的功能 。换句话说,如果你只修改了一个函数,并且因为不想重新部署函数,而希望注释掉其它函数,这个是无法实现的,在 Components 看来就只有一个函数,并且它还会帮你把注释掉的函数在线上删除;
  • Components 更多的定义是组件,所以每个组件就是一个东西,在 Components 上是没有全局变量的 。
综上所述,对比 Plugin 和 Components 各有优劣,我很期待产品策略能够将二者合并或者功能对齐 。在本文,我选择了 Components 来做这个项目 。
造轮子:全局变量组件使用 Components 做项目,我遇到的第一个难题是配置文件怎么办?我有很多的配置,我难道要在每个函数中写一遍?
于是,我做了一个新的: serverless-global。这是一个 Components 功能,用来满足全局变量的需求 。
?复制代码
Conf:component: "serverless-global"inputs:MySQL_host: gz-cdb-mytest.sql.tencentcdb.commysql_user: mytestmysql_password: mytestmysql_port: 62580mysql_db: mytestmini_program_App_id: mytestmini_program_app_secret: mytest在使用的时候,只需要使用${}就可以引用,例如:
?复制代码
Album_Login:component: "@serverless/tencent-scf"inputs:name: Album_LogincodeUri: ./album/loginhandler: index.main_handlerruntime: Python3.6region: ap-shanghaienvironment:variables:mysql_host: ${Conf.mysql_host}mysql_port: ${Conf.mysql_port}mysql_user: ${Conf.mysql_user}mysql_password: ${Conf.mysql_password}mysql_db: ${Conf.mysql_db}利用这个功能就可以很轻松将配置信息统一提取到了一个地方 。需要说明的是,为什么我要把一些配置信息放在环境变量,而不是统一放在一个配置文件中,因为环境变量在 SCF 中会真的打到环境中,也就是说,你可以直接取到,我个人觉得比每次创建实例读取一次配置文件性能要好一些,虽然性能优势有限,但是,我还是觉得这样做是比较优雅的 。最主要的是,相比写到代码中和配置到单独的配置文件中,这样做可以将代码分享给别人,并更好的保护敏感信息 。
数据库设计
基于 Serverless Framework 的人工智能小程序开发

文章插图
 
数据库部分主要对相关的表和表之间的关系进行建立 。首先需要创建项目所必须的表:
?复制代码
CREATE DATABASE `album`;CREATE TABLE `album`.`tags` ( `tid` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `remark` TEXT NULL , PRIMARY KEY (`tid`)) ENGINE = InnoDB;CREATE TABLE `album`.`category` ( `cid` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `sorted` INT NOT NULL DEFAULT '1' , `user` INT NOT NULL , `remark` TEXT NULL , `publish` DATE NOT NULL , `area` VARCHAR(255) NULL , PRIMARY KEY (`cid`)) ENGINE = InnoDB;CREATE TABLE `album`.`users` ( `uid` INT NOT NULL AUTO_INCREMENT , `nickname` TEXT NOT NULL , `wechat` VARCHAR(255) NOT NULL , `remark` TEXT NULL , PRIMARY KEY (`uid`)) ENGINE = InnoDB;CREATE TABLE `album`.`photo` ( `pid` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `small` VARCHAR(255) NOT NULL , `large` VARCHAR(255) NOT NULL , `category` INT NOT NULL , `tags` VARCHAR(255) NULL , `remark` TEXT NULL , `creattime` DATE NOT NULL , `creatarea` VARCHAR(255) NOT NULL , `user` INT NOT NULL ,PRIMARY KEY (`pid`)) ENGINE = InnoDB;CREATE TABLE `album`.`photo_tags` ( `ptid` INT NOT NULL AUTO_INCREMENT , `tag` INT NOT NULL , `photo` INT NOT NULL , `remark` INT NULL , PRIMARY KEY (`ptid`)) ENGINE = InnoDB;


推荐阅读