{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-04-09-serverless-combo-handler","result":{"data":{"currentBlog":{"id":"66fbf753-e21e-50af-9fb0-8d6ff3611176","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020522/1590170625843-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901706165494.png","authors":["galenye"],"categories":["user-stories"],"date":"2020-04-09T00:00:00.000Z","title":"利用 Serverless，实现 COS & CDN Combo Handler","description":"小 S 维护的一个前端系统，单个页面中有数个没有依赖关系的 js, css 需要加载，此时浏览器会分别去请求对应的文件。此时小 S 收到 Leader 给的一个任务：优化前端的静态资源请求，尽量做合并。","authorslink":["https://cloud.tencent.com/developer/article/1610316"],"translators":null,"translatorslink":null,"tags":["Serverless","对象存储"],"keywords":"Serverless,COS,CDN","outdated":true},"wordCount":{"words":367,"sentences":52,"paragraphs":49},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-09-serverless-combo-handler.md","fields":{"slug":"/blog/2020-04-09-serverless-combo-handler/","keywords":["java","serverless","combo","cdn","Serverless"]},"html":"<h2 id=\"背景\"><a href=\"#%E8%83%8C%E6%99%AF\" aria-label=\"背景 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>背景</h2>\n<p>小 S 维护的一个前端系统，单个页面中有数个没有依赖关系的 js, css 需要加载，此时浏览器会分别去请求对应的文件。此时小 S 收到 Leader 给的一个任务：优化前端的静态资源请求，尽量做合并。</p>\n<blockquote>\n<p>什么是 Combo Handler？相信很多前端同学并不陌生。<a href=\"https://yuiblog.com/blog/2008/07/16/combohandler/\">2008 年 7 月 YUI Team 宣布在 YAHOO! CDN 上对 YUI JavaScript 组件提供 Combo Handler 服务</a>。简单讲，当前端有 n 个 js 需要分别去拉取时，通过 cdn combo 技术能用一个请求把 js 在服务端合并后拉回，同理可用于 css 文件。</p>\n</blockquote>\n<h2 id=\"现状\"><a href=\"#%E7%8E%B0%E7%8A%B6\" aria-label=\"现状 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>现状</h2>\n<p>小 S 马上开始着手，看了下手头的项目，目前静态资源是经过 <a href=\"https://cloud.tencent.com/document/product/228?from=10680\">腾讯云 CDN </a>的，静态资源放在了 <a href=\"https://cloud.tencent.com/document/product/436?from=10680\">腾讯云对象存储 COS</a>，js、css 文件因为模块的不同，被打包成了多个。而腾讯云 CDN 目前不支持 Combo 的方式。</p>\n<h2 id=\"分析\"><a href=\"#%E5%88%86%E6%9E%90\" aria-label=\"分析 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>分析</h2>\n<p>小 S 开始想到了 HTTP2.0，但看了 CDN 的请求配置已开启 HTTP2.0，这一块能提升的空间已不大。那是否能做静态的离线合并处理，看似可行的一条路，但改动量不小，且确实涉及到一些历史原因，这块不好动。小 S 突然想起以前了解过的 CDN Combo，那从请求实时合并入手，也是可行的。但可惜，目前接入的 CDN 没能支持。</p>\n<p>此时天空飘来一句秦牛·道格拉斯·正威的话打在了小 S 身上</p>\n<blockquote>\n<p>淡黄的长...不是，计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决</p>\n</blockquote>\n<p>目前静态资源的请求链路是 前端 → CDN → COS，想做实时合并的话，那可以在 CDN 和 COS 之间加入一个中间层来实现，这个中间层根据过来的请求，分别去 COS 上拉取文件做合并后返回给 CDN，CDN 则可以根据请求的路径做缓存。而适合做这个中间层的，小 S 首先想到了最近火的不行的 <a href=\"https://cloud.tencent.com/document/product/1154/38787?from=10680\">Serverless</a>。</p>\n<p>小 S 如梦初醒，甚是感动，简单手动几下便完成了。下面来把实现过程中的关键步骤分享出来。</p>\n<h2 id=\"实现\"><a href=\"#%E5%AE%9E%E7%8E%B0\" aria-label=\"实现 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>实现</h2>\n<h3 id=\"原理\"><a href=\"#%E5%8E%9F%E7%90%86\" aria-label=\"原理 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>原理</h3>\n<p>使用 Serverless framework 实现一个 server，用来给 CDN 作为源站，server 中根据 CDN 过来的判断是否开启 combo 特性，这里使用 url 中的 <code class=\"language-text\">??</code> 双问号开启 combo 特性，使用 <code class=\"language-text\">&amp;</code> 连接多个文件路径，如 xxx.com??<pathA>&#x26;<pathB>。如果启用，则去 COS 上拉取对应的文件合并后返回。如果不启用，则跟原始请求单个文件一样，如 xxx.com/<pathA> ，则 server 返回 302 cos 链接到 CDN，让 CDN 去 follow 302，与原始使用没有差别。</p>\n<p>相关产品：</p>\n<ul>\n<li><a href=\"https://cloud.tencent.com/document/product/1154/38787?from=10680\">Serverless framework （通过云 API 网关开启外网访问）</a></li>\n<li><a href=\"https://cloud.tencent.com/document/product/228?from=10680\">CDN</a></li>\n<li><a href=\"https://cloud.tencent.com/document/product/436?from=10680\">COS</a></li>\n</ul>\n<h3 id=\"1-安装serverless-framework-命令行工具\"><a href=\"#1-%E5%AE%89%E8%A3%85serverless-framework-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7\" aria-label=\"1 安装serverless framework 命令行工具 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 安装Serverless framework 命令行工具</h3>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"17297457370072777000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`// 非npm安装可查看 https://cloud.tencent.com/document/product/1154/42990\nnpm install -g serverless\nserverless -v`, `17297457370072777000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">// 非npm安装可查看 https://cloud.tencent.com/document/product/1154/42990</span>\nnpm install <span class=\"token operator\">-</span>g serverless\nserverless <span class=\"token operator\">-</span>v</code></pre></div>\n<h3 id=\"2-修改-demo-配置\"><a href=\"#2-%E4%BF%AE%E6%94%B9-demo-%E9%85%8D%E7%BD%AE\" aria-label=\"2 修改 demo 配置 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 修改 demo 配置</h3>\n<p>下载 <a href=\"https://galenye-1251496585.cos.ap-guangzhou.myqcloud.com/cdn-combo.zip\">cdn-combo demo 的代码</a>，解压后得到 cdn-combo 文件夹，修改里面的几个配置信息，包括 SecretId、SecretKey、Bucket 以及 Region。</p>\n<p>其中，Bucket、Region 即原本 CDN 回源的 COS 源站的桶信息，如果修改了 app.js 中的 Region，也要同时修改 serverless.yml 中的 region 的值，这样保证了 Serverless 服务请求 COS 时走的是腾讯内网。</p>\n<p>SecretId、SecretKey 即账号的密钥信息。</p>\n<p>（该例子是从一个存储桶中拿不同文件进行合并，如何希望从不同存储桶，乃至从非 COS 的源站中拿文件进行合并，均可自行参考实现）</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020522/1590170199841-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901701049856.png\" alt=\"serverless\"></p>\n<h3 id=\"3-serverless-部署\"><a href=\"#3-serverless-%E9%83%A8%E7%BD%B2\" aria-label=\"3 serverless 部署 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Serverless 部署</h3>\n<p>在 cdn-combo 文件夹下执行进行 serverless 的部署</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"55471508407053574000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`sls --debug`, `55471508407053574000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">sls <span class=\"token operator\">--</span>debug</code></pre></div>\n<p>部署过程中需要扫描二维码进行登录，如果希望持久化登录状态，可参考 <a href=\"https://cloud.tencent.com/document/product/1154/40493?from=10680#.E8.B4.A6.E5.8F.B7.E9.85.8D.E7.BD.AE.EF.BC.88.E5.8F.AF.E9.80.89.EF.BC.89\">文档</a></p>\n<p>部署完成，在命令行我们会得到如下信息，此时证明中间服务已部署起来，拿到 url 的 host 部分 <strong><a href=\"https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com\">https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com</a></strong> 这我们需要的内容，记住它。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020522/1590170199844-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901701049856.png\" alt=\"部署 Serverless framework\"></p>\n<h3 id=\"4-设置-cdn-回源-serverless-server-url\"><a href=\"#4-%E8%AE%BE%E7%BD%AE-cdn-%E5%9B%9E%E6%BA%90-serverless-server-url\" aria-label=\"4 设置 cdn 回源 serverless server url permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. 设置 CDN 回源 Serverless Server Url</h3>\n<p>登录 CDN 控制台，找到之前接入的域名，或者接入个新的域名。</p>\n<p>以下面作为例子，CDN 域名为 cdn-combo.galen-yip.com，修改源站，源站选择自有源，<strong><code class=\"language-text\">回源协议务必选择 HTTP</code></strong>，源站地址以及回源 host 填写 Serverless server url，待设置成功，至此我们变完成了所有的变更工作。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020522/1590170199819-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901701049856.png\" alt=\"修改 CDN 源站配置\"></p>\n<p>同时注意，这两个配置务必如下，过略参数配置需关闭，跟随回源 301/302 配置打开</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020522/1590170199805-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901701049856.png\" alt=\"过略参数配置关闭\"></p>\n<p><img src=\"https://img.serverlesscloud.cn/2020522/1590170199782-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901701049856.png\" alt=\"回源跟随打开\"></p>\n<h3 id=\"5-验收成果\"><a href=\"#5-%E9%AA%8C%E6%94%B6%E6%88%90%E6%9E%9C\" aria-label=\"5 验收成果 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. 验收成果</h3>\n<p>访问 <a href=\"http://cdn-combo.galen-yip.com/js-combo/foo.js\">http://cdn-combo.galen-yip.com/js-combo/foo.js </a>返回 200 以及单文件内容</p>\n<p>访问 <a href=\"http://cdn-combo.galen-yip.com/??js-combo/foo.js&#x26;js-combo/bin.js\">http://cdn-combo.galen-yip.com/??js-combo/foo.js&#x26;js-combo/bin.js</a> 返回 200 以及文件合并后的内容</p>\n<p>最后把页面 <a href=\"http://cdn-combo-demo-1251496585.cos.ap-guangzhou.myqcloud.com/index.html\">http://cdn-combo-demo-1251496585.cos.ap-guangzhou.myqcloud.com/index.html</a>中的静态资源引用，改变成以上 cdn combo 的引用方式</p>\n<h2 id=\"小结\"><a href=\"#%E5%B0%8F%E7%BB%93\" aria-label=\"小结 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>小结</h2>\n<p>以上便完成了 CDN Combo Handler 能力。特别注意，CDN 源站从 COS 改为 Serverless server，计费这边是有变更的，具体可以查询对应产品的流量计费情况。</p>\n<p>Serverless 能发挥的作用远不止此，最后附上 demo <a href=\"https://galenye-1251496585.cos.ap-guangzhou.myqcloud.com/cdn-combo.zip\">下载地址</a>。</p>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a></li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#%E8%83%8C%E6%99%AF\">背景</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#%E7%8E%B0%E7%8A%B6\">现状</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#%E5%88%86%E6%9E%90\">分析</a></li>\n<li>\n<p><a href=\"/blog/2020-04-09-serverless-combo-handler/#%E5%AE%9E%E7%8E%B0\">实现</a></p>\n<ul>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#%E5%8E%9F%E7%90%86\">原理</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#1-%E5%AE%89%E8%A3%85serverless-framework-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7\">1. 安装Serverless framework 命令行工具</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#2-%E4%BF%AE%E6%94%B9-demo-%E9%85%8D%E7%BD%AE\">2. 修改 demo 配置</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#3-serverless-%E9%83%A8%E7%BD%B2\">3. Serverless 部署</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#4-%E8%AE%BE%E7%BD%AE-cdn-%E5%9B%9E%E6%BA%90-serverless-server-url\">4. 设置 CDN 回源 Serverless Server Url</a></li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#5-%E9%AA%8C%E6%94%B6%E6%88%90%E6%9E%9C\">5. 验收成果</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-04-09-serverless-combo-handler/#%E5%B0%8F%E7%BB%93\">小结</a></li>\n</ul>"},"previousBlog":{"id":"44ad21a9-00a3-592c-83c1-696af478c55f","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586850670017-%E5%B0%81%E9%9D%A2%E5%9B%BE%20%283%29.png","authors":["Anycodes"],"categories":["guides-and-tutorials","operations-and-observability"],"date":"2020-04-10T00:00:00.000Z","title":"Serverless 实战：通过 Serverless 架构实现监控告警","description":"Serverless 的一个重要应用场景就是运维、监控与告警，本文将会通过现有的 Serverless 平台，部署一个网站状态监控脚本，对网站的可用性进行监控告警","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["Serverless","监控告警"],"keywords":"Serverless 全局变量组件,Serverless 单独部署组件,Serverless Component","outdated":true},"wordCount":{"words":368,"sentences":65,"paragraphs":65},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-10-website-alarm.md","fields":{"slug":"/blog/2020-04-10-website-alarm/","keywords":["php","python","serverless","监控","告警","Serverless","耗时","网站"]}},"nextBlog":{"id":"1deff4fb-c4ce-52d7-9a92-a6e33ab35714","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020522/1590168389721-%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_15901683546214.png","authors":["brzhang"],"categories":["user-stories"],"date":"2020-04-09T00:00:00.000Z","title":"手把手带你利用云函数 SCF 轻松实现一个热点资讯小程序","description":"新技能，手把手带你利用云函数轻松实现一个热点资讯小程序","authorslink":["https://cloud.tencent.com/developer/article/1609581"],"translators":null,"translatorslink":null,"tags":["云函数","小程序"],"keywords":"Serverless","outdated":null},"wordCount":{"words":208,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-09-serverless-scf.md","fields":{"slug":"/blog/2020-04-09-serverless-scf/","keywords":["go","java","serverless","云函数","函数","serverless","程序","event"]}},"recommendBlogs":{"edges":[{"node":{"id":"4300b21c-7209-5256-86ff-0d38e3daec9b","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/14f1c8eed372e76c1b139703b2f6d0fa.jpg","authors":["KieranMcCarthy"],"categories":["user-stories","engineering-culture"],"date":"2018-01-09T00:00:00.000Z","title":"我是如何在四年时间里，从厨师转行为 Serverless 应用开发者","description":"我是厨师出身，现在成为了一名 Serverless 应用开发者。","authorslink":["https://serverless.com/author/kieranmccarthy/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["应用开发","Serverless"],"keywords":"Serverless 应用开发,Serverless 管理,厨师转行为 Serverless 应用开发者","outdated":null},"wordCount":{"words":285,"sentences":38,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years.md","fields":{"slug":"/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years/","keywords":["无服务器","无服务器开发","云函数","学习","Serverless","构建","Framework","开发者","服务器","应用","学位","简历"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"98602143-b837-5f50-a24f-3b1ec76044d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/sqquid/sqquid-serverless-thumb.jpg","authors":["RonPeled"],"categories":["user-stories"],"date":"2018-12-17T00:00:00.000Z","title":"SQQUID：100% 无服务器初创公司","description":"SQQUID 将 AWS Lambda 和无服务器框架用于其核心产品和营销网站。我们来看看一个完全无服务器的初创公司是怎样的。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":266,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-17-sqquid-one-hundred-percent-serverless.md","fields":{"slug":"/blog/2018-12-17-sqquid-one-hundred-percent-serverless/","keywords":["go","serverless","无服务器","无服务器架构","服务器","架构","Lambda","集成","FaaS","串行","系统"]}}},{"node":{"id":"29dc2e58-d2ba-56f9-aee1-d21b0bc62e0e","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/ao-com-story/ao-serverless-thumbnail.png","authors":["NickGottlieb"],"categories":["user-stories"],"date":"2019-04-24T00:00:00.000Z","title":"AO.com：逐渐转向无服务器优先","description":"AO.com 的 SCV 团队率先尝试无服务器服务。折服于无服务器框架的快速周转时间和低维护成本，整个团队逐渐转向无服务器优先。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":236,"sentences":42,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-04-24-ao-serverless-first.md","fields":{"slug":"/blog/2019-04-24-ao-serverless-first/","keywords":["serverless","无服务器","服务器","团队","Lambda","功能","构建"]}}},{"node":{"id":"752d08d1-387a-5bde-acf3-98141baab294","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586871710979-%E5%85%AC%E5%85%B1%E7%94%A8.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-06-20T00:00:00.000Z","title":"如何用 Serverless 为 Python 云函数打包依赖","description":"在使用无服务器云函数SCF时通常会遇到导入第三方库的问题，很多小伙伴比较头疼是：应该如何打包进去？这里，推荐几个不错的方法。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["云函数","Serverless"],"keywords":"Serverless,Serverless应用,无服务器云函数","outdated":null},"wordCount":{"words":81,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-06-20-for-python-cloud-functions.md","fields":{"slug":"/blog/2019-06-20-for-python-cloud-functions/","keywords":["java","serverless","无服务器","无服务器云函数","云函数","serverlesscloud","安装","serverless","pillowtest"]}}},{"node":{"id":"2dc78814-9d77-555b-a1bb-ad202c8ec2d1","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/cloudforecast/thumbnail.png","authors":["FrancoisLagier"],"categories":["user-stories"],"date":"2019-08-07T00:00:00.000Z","title":"Serverless：初创企业的理想选择？（CloudForecast 案例分析）","description":"CloudForecast 是 2018 年成立的一家独立初创企业，本文将介绍他们决定选择 Serverless 的原因。","authorslink":["https://serverless.com/author/francoislagier/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":211,"sentences":29,"paragraphs":29},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-07-serverless-for-startups.md","fields":{"slug":"/blog/2019-08-07-serverless-for-startups/","keywords":["serverless","云函数","serverless","函数","Serverless","utm","Framework","blog","CloudForecast","cloudforecast"]}}},{"node":{"id":"97450b07-658b-5207-8216-1c7b9b51b115","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578988490344-v2-8b2cd2c5275aa2c5a3c5083a148a7a9f_1200x500.jpg","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-09-01T00:00:00.000Z","title":"如何通过 Serverless 与自然语言处理，让搜索引擎「看」到你的博客","description":"Serverless 与自然语言处理结合的一个小应用","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["个人博客","serverless"],"keywords":"Serverless 自然语言处理","outdated":null},"wordCount":{"words":106,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-01-search-engine-blog.md","fields":{"slug":"/blog/2019-09-01-search-engine-blog/","keywords":["serverless","云函数","keywords","serverlesscloud","summary"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}}],"totalCount":64}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"66fbf753-e21e-50af-9fb0-8d6ff3611176","previousBlogId":"44ad21a9-00a3-592c-83c1-696af478c55f","nextBlogId":"1deff4fb-c4ce-52d7-9a92-a6e33ab35714","categories":["user-stories"]}}}