网站的域名和ip地址如何重新解析,工业品牌设计公司,天津响应式网站,wordpress怎么修改数据库配置文件简介#xff1a; 当下#xff0c;Serverless 概念很火#xff0c;很多同学被 Serverless 的优势吸引过来#xff0c;比如它的弹性伸缩#xff0c;免运维#xff0c;高可用#xff0c;资费少。但真正使用起来去落地的时候发现问题很多#xff0c;大型项目如何组织函数 当下Serverless 概念很火很多同学被 Serverless 的优势吸引过来比如它的弹性伸缩免运维高可用资费少。但真正使用起来去落地的时候发现问题很多大型项目如何组织函数性能优化怎么做怎么做Serverless调试数据库共享会话怎么加等等。上周Serverless Devs 2.0 正式版全新发布。Serverless Devs 2.0 在平台能力、应用模板以及开发者套件方面能力提升。本文以 Serverless Devs 的应用中心web 版)为案例来看开箱实践方案。
当下Serverless 概念很火很多同学被 Serverless 的优势吸引过来比如它的弹性伸缩免运维高可用资费少。但真正使用起来去落地的时候发现问题很多大型项目如何组织函数性能优化怎么做怎么做Serverless调试数据库共享会话怎么加等等。上周Serverless Devs 2.0 正式版全新发布。Serverless Devs 2.0 在平台能力、应用模板以及开发者套件方面能力提升。接下来以 Serverless Devs 的应用中心web 版)为案例来看开箱实践方案。
Serverless 函数代码组织
如果想充分利用 Serverless 的能力函数是最佳方案可以最大程度减少冷启动时间践行用完即走的理念保障用户体验的同时最大程度减少成本不过对于中大型项目而言以单函数的方式组织代码在维护上无疑是一个巨大挑战可能一个应用会有数百个函数维护成本极高也极易出错。
最好的方式是用框架的方式组织代码以函数的方式部署执行。框架组织代码需要做业务的划分比如电商包含商品订单用户等服务都放到一个框架里面并通过函数去部署执行的话明显太大了。最好就是像微服务一样独立业务的接口可以在同一个函数中每一个业务有自己的独立域名再通过内部路由访问具体的业务服务。 这样做可以最大限度的利用函数能力并且维护得来相对容易一些。
我们把 Serverless Hub 的应用市场作为一类场景进行了统一划分具体的函数调用如下实现(完整的代码目录 git)
const { http } require(serverless-devs/dk);const { searchApp, getAppDetail, getSpecialDetail, getSpecialApp, getCategorys, getTags } require(./services);http.get(/appCenter/getSpecial, async (ctx) {const data await getSpecialApp(ctx);ctx.body data;}).post(/appCenter/getSpecialDetail, async (ctx, next) {const data await getSpecialDetail(ctx);ctx.body data;}) .post(/appCenter/getAppDetail, async (ctx) {const data await getAppDetail(ctx);ctx.body data;}) .get(/appCenter/getCategory, async (ctx) {const data await getCategorys();ctx.body data; }) .get(/appCenter/getTags, async (ctx) {const data await getTags();ctx.body data; }) .post(/appCenter/getApps, async (ctx) {const data await searchApp(ctx);ctx.body data;}) .get(/, async (ctx, next) {let result Hello ServerlessDevs;ctx.body result;})http.app.use(http.routes());exports.handler http();代码使用了 Serverless Devs 提供的 serverless-devs/dk 我们对标准的前端框架进行了核心封装比如 express,koa 等你可以继续使用习惯的 web 框架进行开发工作最后通过 s 工具进行函数部署。s.yaml 的配置如下
edition: 1.0.0 # 命令行YAML规范版本遵循语义化版本Semantic Versioning规范
name: fc-http-demo # 项目名称
access: default # 秘钥别名
vars:
services:serverlesshub:component: devsapp/fc # 组件名称props:region: cn-hangzhouservice:name: myserverlesstestdescription: demo for fc-http componentinternetAccess: truefunction:name: myhubdescription: this is a testruntime: nodejs12codeUri: ./codehandler: index.handlermemorySize: 128timeout: 10triggers:- name: httpTriggertype: httpconfig: authType: anonymous methods: - GET - POST customDomains:- domainName: autoprotocol: HTTP routeConfigs: - path: /*
# 函数计算FC组件文档参考地址https://github.com/devsapp/fc如果你想再增加一个服务业务可以水平扩展一个新的服务配置并且可以用同样的代码包去实现。
性能优化
通常 Serverless 应用的最大耗时都在 冷启动时间上就以阿里云 FC 为例如果我们的应用以容器的方式进行部署冷启动时间会比较长可能是 1 分钟或者更多即使采用镜像加速也仅能缩短到几十秒以内所以如果项目不是特别大AI 类应用的包大小可能会达到 G 级别都建议以 原生runtime 的方式去做。拿我们上面的 serverless hub 为例就是最终运行到 nodejs12 runtime,冷启动时间 1~2s 热启动则缩短到150ms 对于这类非高频访问的站点而言还是比较适合的另外你可以根据需要在具体的某个时间点通过添加预留的方式保持高性能的访问效果。
当然冷启动这块需要云厂商的进一步优化把他做到极致最终才能真正让 Serverless 完美。
端云调试
调试始终是 Serverless 应用的最棘手的部分我们开发的应用是在本地部署的应用是在线上。并且线上的环境跟本地开发环境有着巨大的差异通常我们只能通过在线打印输出然后还得通过日志平台查看日志判断问题再回来本地修改代码一来一回耗时非常巨大而且效果也不好。Serverless Devs 提供了自己的解决方案我们巧妙的设计了一个在线的辅助函数辅助函数完整复刻线上代码然后通过本地跟辅助函数建设通道实现本地的代码调试效果 基于这样的能力我们再来看看具体怎么在 Serverless Hub 实施的, 本次演示使用的是Serverless Desktop, 大家可以尝试跟着我的操作步骤进行使用
1、新建一个Serverless 应用并把它部署到线上
我们可以通过 Serverless Desktop 的应用市场搜索 xxx 应用模板然后加载到本地然后通过可视化配置部分修改相应的服务和函数内容进行部署。
2、进入工作空间-应用管理-应用详情-端云调试 按照提示准备好前置条件比如安装docker demon 指定调试端口启动资源准备这个时候会创建辅助函数同时构建 vscode 的 debug 文件。 启动好之后使用 vscode 打开工程目录查看debug配置文件.vscode/launch.json 以这个启动 debug 模式 3、发起调用
切换到本地调试配置面板点击发起调用 可以发现 vscode 触发调试 调试结束回到 Serverless Desktop 页面我们可以看到输出效果 这里我们发起调用是向这个服务的根目录发起如果我们想向其他的路由地址发起调用该怎么操作呢我们可以复制发起调用后输出的基础地址。 然后贴到 postman, 再往后拼接上我们的测试路由地址比如想访问/appCenter/getSpecial,可以拼接成基础地址/appCenter/getSpecial然后Send这个请求。 通过这样的方式我们可以深入细节知道每一行代码的调用问题到底出在哪里极大的提高了我们的开发效率。
4、清空环境
调试结束后不要忘了清楚调试环境包括关闭本地的容器地址以及清理线上的函数。 综上我们完成了一次完整的调试过程。
数据库使用
Serverless 一大特色就是他的计费模式:按需按量计费。在数据库存储层面阿里云推出 Serverless 分布式数据库 Tablestore和函数计算 FC 是最佳拍档。
1、前提
请先到 tablestore 控制台开通服务使用主账号创建按量付费的实例在实例管理页面获取访问地址以及实例名2、Initializer 函数
首先让我们先认识下 initializer 函数initializer 函数能够保证统一实例成功并且仅成功执行一次。这个特性非常适合我们的数据库初始化连接。
const TableStore require(tablestore);let internal; // 先定义一个全局变量
exports.initializer (context, callback) {try { const endpoint process.env.tablestore_endpoint; // tablestore的连接地址 const instanceName process.env.tablestore_instanceName;// tablestore实例名 const tableClient new TableStore.Client({accessKeyId: context.credentials.accessKeyId,accessKeySecret: context.credentials.accessKeySecret,stsToken: context.credentials.securityToken,endpoint,instancename: instanceName,});internal { tableClient, TableStore };callback();} catch (err) {callback(err.message);}
}3、handler函数
数据库建立连接后我们就可以在 handler 函数中处理业务逻辑。
const { http } require(serverless-devs/dk);
http// 创建表.post(/table, async (ctx, next) {const { tableName } ctx.request.body;const { tableClient } ctx.req.requestContext.internal;const params {tableMeta: {tableName,primaryKey: [{ name: id,type: INTEGER,},],},reservedThroughput: {capacityUnit: {read: 0, write: 0,},},tableOptions: {timeToLive: -1, // 数据的过期时间, 单位秒, -1代表永不过期. 假如设置过期时间为一年, 即为 365 * 24 * 3600.maxVersions: 1, // 保存的最大版本数, 设置为1即代表每列上最多保存一个版本(保存最新的版本).},streamSpecification: {enableStream: true, //开启StreamexpirationTime: 24, //Stream的过期时间单位是小时最长为168设置完以后不能修改},};await tableClient.createTable(params);ctx.body {success: true,message: ${tableName}表已创建成功,}})exports.handler (req, res, context) {context.internal internal;http()(req, res, context);
};3、快速体验
1. Serverless Devs 提供 tablestore 组件, 通过一行命令快速体验
$ s init dk-tablestore2. 本地调试
$ cd code
$ npm install
$ npm run serve3. 一键部署到函数计算 FC
回到项目根目录(s.yaml平级)执行命令
$ s deploy
原文链接 本文为阿里云原创内容未经允许不得转载。