{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-03-09-community-chenyuan","result":{"data":{"currentBlog":{"id":"eb3e239f-0ac6-5381-8a51-26142f95edfc","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020318/1584510373593-lab.jpg","authors":["高晨远"],"categories":["user-stories"],"date":"2020-03-09T00:00:00.000Z","title":"实验室站迁移 Serverless 之路（上）","description":"本文为 Serverless 社区成员撰稿。作者高晨远，研发工程师，熟悉 Python 开发，常写 Web 和爬虫","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","Python"],"keywords":"Serverless Flask 框架,Serverless 框架,Serverless 迁移方案","outdated":true},"wordCount":{"words":305,"sentences":63,"paragraphs":62},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-09-community-chenyuan.md","fields":{"slug":"/blog/2020-03-09-community-chenyuan/","keywords":["go","nodejs","python","serverless","无服务器","无服务器架构","云函数","Serverless","serverless","template","components","requirements"]},"html":"<h2 id=\"前言\"><a href=\"#%E5%89%8D%E8%A8%80\" 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>2 月份，TencentServerless 举办了系列在线课堂分享，讲解了 Serverless 概念、架构、最佳实践以及如何开发一个 component 等技术知识。</p>\n<p>因为对 Serverless 非常感兴趣，每次都参加了直播学习并提交了课堂作业，一路下来感觉还不错，因此决定把自己的<a href=\"https://lab.yuangezhizao.cn/\">实验室站</a>迁移到 Serverless 试试看。</p>\n<h2 id=\"1-tencentserverless-介绍\"><a href=\"#1-tencentserverless-%E4%BB%8B%E7%BB%8D\" aria-label=\"1 tencentserverless 介绍 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. TencentServerless 介绍</h2>\n<p>不得不感叹互联网时代科技的进步，之前我的实验室站采用的是传统方法发布网站的环境部署，虽然现在熟悉了操作并不觉得很麻烦，但是对于从来没接触过这块的人来说就比较难懂了。</p>\n<p>而现在有了 Serverless，就可以完全无视上面的操作步骤了，这里引用官网的两段话：</p>\n<blockquote>\n<p>Serverless Framework 可以帮您以更少的成本和开销, 快速构建 Serverless 应用。它能够完美支持无服务器应用的开发，部署，测试，监控等环节。Serverless 是面向未来的运维方式。</p>\n<p>Serverless 建立在下一代公共云服务之上，该服务仅在使用时自动扩容和收费。当规模，所用容量和成本管理实现自动化时，可节省 99% 的成本管理。</p>\n<p>无服务器架构是全新的，因此我们需要改变先前对老架构和工作流的看法。Serverless Framework 的目标是以一种简单，强大而优雅的使用体验为开发者、团队提供开发和运行 serverless 应用程序所需的所有工具。</p>\n</blockquote>\n<p>这种方式非常方便，本人现在倒是觉得对于个人开发者来说，如果想构建轻量应用的话，用 Serverless 应该会节省非常多的时间。当然 Serverless 对比传统型应用还是有区别的，目前它并不能完美支持，举一个例子：Flask CLI 就不支持，不过相信随着 Serverless 技术的发展，Serverless 的支持将更加全面。</p>\n<p>对于企业开发者来说也是同理的，想快速上线一套网站的话，部署在一个服务器上倒是好说，可是当访问量上升之后，需要扩容的时候就比较麻烦了，这时候你得在多个服务器上部署并且配置负载均衡等等。</p>\n<p>对我个人来说，我觉得 Serverless 最大的优点在于运维部署方面，通过 Serverless 部署，还是非常方便的。</p>\n<h2 id=\"2-安装-serverless-framework\"><a href=\"#2-%E5%AE%89%E8%A3%85-serverless-framework\" aria-label=\"2 安装 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>2. 安装 Serverless Framework</h2>\n<p>Serverless Framework 是基于 Node.js 的开源 CLI，注：需 Node 8+ 全局安装：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install serverless -g</code></pre></div>\n<p>这里没有使用 cnpm 的原因是因为网络还算 ok 没有特别耗时，另外忘记了之前在哪里看到过 cnpm 不会更新 package-lock.json，因此也就没有再去用第三方源。之后更新的话就</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install serverless -g</code></pre></div>\n<p>官网的快速开始教程之后快速部署了个 demo，即：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">serverless create -t tencent-nodejs</code></pre></div>\n<p>命令里的 tencent-nodejs 是众多组件中的一个，组件列表：<a href=\"https://github.com/serverless/components\">https://github.com/serverless/components</a></p>\n<h2 id=\"3-部署-python-flask-框架\"><a href=\"#3-%E9%83%A8%E7%BD%B2-python-flask-%E6%A1%86%E6%9E%B6\" aria-label=\"3 部署 python flask 框架 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. 部署 Python Flask 框架</h2>\n<p>因为本人对 Flask 还算熟悉，所以干脆把部署这个 Component 当成 Hello World 好了。其中官网简介里写道：任何支持 WSGI（Web Server Gateway Interface）的 Python 服务端框架都可以通过该组件进行部署，例如 Falcon 框架等。</p>\n<p><strong>1) 创建新项目</strong></p>\n<ul>\n<li>\n<h4 id=\"基于模板\"><a href=\"#%E5%9F%BA%E4%BA%8E%E6%A8%A1%E6%9D%BF\" 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>基于模板</h4>\n</li>\n</ul>\n<p>通过 sls 直接根据模板创建服务，Serverless github 上有很多模板 比如：<a href=\"https://github.com/serverless/components/tree/master/templates/tencent-flask\">https://github.com/serverless/components/tree/master/templates/tencent-flask</a></p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">serverless create --template-url https://github.com/serverless/components/tree/master/templates/tencent-flask</code></pre></div>\n<p>源码如下：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\"># -*- coding: utf8 -*-\n\nimport json\nfrom flask import Flask, jsonify, request\napp = Flask(__name__)\n\n\n@app.route(&quot;/&quot;)\ndef index():\n    return &quot;Hello Flash&quot;\n\n@app.route(&#39;/user&#39;, methods = [&#39;POST&#39;])\ndef addUser():\n    # we must get request body from clound function event;\n    event = request.environ[&#39;event&#39;]\n    user = json.loads(event[&#39;body&#39;])\n    return jsonify(data=user)\n\n\n@app.route(&quot;/user&quot;, methods = [&#39;GET&#39;])\ndef listUser():\n    users = [{&#39;name&#39;: &#39;test1&#39;}, {&#39;name&#39;: &#39;test2&#39;}]\n    return jsonify(data=users)\n\n\n@app.route(&quot;/user/&lt;id&gt;&quot;, methods = [&#39;GET&#39;])\ndef getUser(id):\n    return jsonify(data={&#39;name&#39;: &#39;test1&#39;})</code></pre></div>\n<ul>\n<li>不基于模板</li>\n</ul>\n<p>在 Pycharm 创建一个新的 Flask 项目：LAB_Serverless 以区别之前的 LAB</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939427919-IMG_0276.JPG\" alt=\"img\"></p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939428092-IMG_0276.JPG\" alt=\"img\"></p>\n<p>源码如下：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">from flask import Flask\n\napp = Flask(__name__)\n\n@app.route(&#39;/&#39;)\ndef hello_world():\n    return &#39;Hello World!&#39;\n\nif __name__ == &#39;__main__&#39;:\n    app.run()</code></pre></div>\n<p><strong>2) 配置Serverless</strong></p>\n<ul>\n<li>创建serverless.yml，这里更改了几处配置</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">MyComponent:\n  component: &#39;@serverless/tencent-flask&#39;\n  inputs:\n    region: ap-beijing\n    functionName: LAB_Serverless\n    code: ./\n    functionConf:\n      timeout: 10\n      memorySize: 128\n      environment:\n        variables:\n          TEST: value\n          Version: 2020-2-23_21:01:44\n      vpcConfig:\n        subnetId: &#39;&#39;\n        vpcId: &#39;&#39;\n    apigatewayConf:\n      protocol: https\n      environment: test</code></pre></div>\n<ul>\n<li>创建.env，写入密匙（因为懒得每次部署都得拿起手机扫一扫授权(^_−)☆</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">TENCENT_SECRET_ID=&lt;rm&gt;\nTENCENT_SECRET_KEY=&lt;rm&gt;</code></pre></div>\n<p><strong>3) 部署</strong></p>\n<p>serverless 的缩写是 sls，因此也可以用 sls 简化命令。但是这里报错了……报错的原因是requirements文件夹不存在。</p>\n<p>查看终端</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Microsoft Windows [版本10.0.17763.1039]\n(c) 2018 Microsoft Corporation。保留所有权利。\n\nD:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless&gt;sls --debug\n\n  DEBUG─Resolving the template&#39;s static variables.\n  DEBUG─Collecting components from the template.\n  DEBUG─Downloading any NPM components found in the template.\n  DEBUG─Analyzing the template&#39;s components dependencies.\n  DEBUG─Creating the template&#39;s components graph.\n  DEBUG─Syncing template state.\n  DEBUG─Executing the template&#39;s components graph.\n  DEBUG─Compressing function LAB_Serverless file to D:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless\\.serverless/LAB_Serverless.zip.\n(node:22500) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, stat &#39;D:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless\\.\nserverless\\requirements&#39;eploying\n    at Object.statSync (fs.js:946:3)\n    at Object.statSync (C:\\Users\\yuangezhizao\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\_graceful-fs@4.2.3@graceful-fs\\polyfills.js:308:16\n)\n    at WriteStream.&lt;anonymous&gt; (C:\\Users\\yuangezhizao\\.serverless\\components\\registry\\npm\\@serverless\\tencent-flask@0.2.0\\node_modules\\@serverless\\tencen\nt-flask\\node_modules\\@serverless\\tencent-scf\\library\\utils.js:124:20)\n    at WriteStream.emit (events.js:304:20)\n    at C:\\Users\\yuangezhizao\\.serverless\\components\\registry\\npm\\@serverless\\tencent-flask@0.2.0\\node_modules\\@serverless\\tencent-flask\\node_modules\\grac\neful-fs\\graceful-fs.js:298:14\n    at C:\\Users\\yuangezhizao\\.serverless\\components\\registry\\npm\\@serverless\\tencent-flask@0.2.0\\node_modules\\@serverless\\tencent-flask\\node_modules\\grac\neful-fs\\graceful-fs.js:325:16\n    at C:\\Users\\yuangezhizao\\AppData\\Roaming\\npm\\node_modules\\serverless\\node_modules\\_graceful-fs@4.2.3@graceful-fs\\graceful-fs.js:325:16\n    at FSReqCallback.oncomplete (fs.js:152:23)\n(node:22500) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without\na catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)\n(node:22500) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will termi\nnate the Node.js process with a non-zero exit code.\n\n  194s»MyComponent»canceled\n\n终止批处理操作吗(Y/N)? Y\n\nD:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless&gt;</code></pre></div>\n<p>然后去 .serverless 文件下的 Template.MyComponent.pyRequirements.json 文件中看到了requirements.txt。这里其实是故意操作的（特意没添加requirements.txt），说明 requirements.txt 必须存在！</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939428805-IMG_0276.JPG\" alt=\"img\"></p>\n<p>因此，去创建文件内容为 Flask 的 requirements.txt</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">D:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless&gt;sls --debug\n\n  DEBUG─Resolving the template&#39;s static variables.\n  DEBUG─Collecting components from the template.\n  DEBUG─Downloading any NPM components found in the template.\n  DEBUG─Analyzing the template&#39;s components dependencies.\n  DEBUG─Creating the template&#39;s components graph.\n  DEBUG─Syncing template state.\n  DEBUG─Executing the template&#39;s components graph.\n  DEBUG─Generated requirements from D:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless\\requirements.txt in D:\\yuangezhizao\\Documents\\PycharmProje\ncts\\LAB_Serverless\\.serverless\\requirements.txt...\n  DEBUG─Installing requirements from C:\\Users\\yuangezhizao\\AppData\\Local\\Yugasun\\serverless-python-requirements\\Cache\\2a1a661c4e3e6faadab5d001bc10cc3ac\nccf648921aad7c279d94f138eaaf833_slspyc\\requirements.txt ...\n  DEBUG─Using download cache directory C:\\Users\\yuangezhizao\\AppData\\Local\\Yugasun\\serverless-python-requirements\\Cache\\downloadCacheslspyc\n  DEBUG─Running ...\n  DEBUG─Compressing function LAB_Serverless file to D:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless\\.serverless/LAB_Serverless.zip.\n  DEBUG─Compressed function LAB_Serverless file successful\n  DEBUG─Uploading service package to cos[sls-cloudfunction-ap-beijing-code]. sls-cloudfunction-default-LAB_Serverless-1582464464.zip\n  DEBUG─Uploaded package successful D:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless\\.serverless/LAB_Serverless.zip\n  DEBUG─Creating function LAB_Serverless\n  DEBUG─Created function LAB_Serverless successful\n  DEBUG─Setting tags for function LAB_Serverless\n  DEBUG─Creating trigger for function LAB_Serverless\n  DEBUG─Deployed function LAB_Serverless successful\n  DEBUG─Starting API-Gateway deployment with name MyComponent.TencentApiGateway in the ap-beijing region\n  DEBUG─Service with ID service-0ok85tqh created.\n  DEBUG─API with id api-ivk6tk0y created.\n  DEBUG─Deploying service with id service-0ok85tqh.\n  DEBUG─Deployment successful for the api named MyComponent.TencentApiGateway in the ap-beijing region.\n\n  MyComponent:\n    region:              ap-beijing\n    functionName:        LAB_Serverless\n    apiGatewayServiceId: service-0ok85tqh\n    url:                 http://service-0ok85tqh-1251901037.bj.apigw.tencentcs.com/test/\n\n  44s»MyComponent»done\n\n\nD:\\yuangezhizao\\Documents\\PycharmProjects\\LAB_Serverless&gt;</code></pre></div>\n<p>趁机看下部署成功之后的 .serverless 文件夹：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939428147-IMG_0276.JPG\" alt=\"img\"></p>\n<p>这里 Template.MyComponent.TencentCloudFunction.json 即云函数</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{\n  &quot;deployed&quot;: {\n    &quot;Name&quot;: &quot;LAB_Serverless&quot;,\n    &quot;Runtime&quot;: &quot;Python3.6&quot;,\n    &quot;Handler&quot;: &quot;api_service.handler&quot;,\n    &quot;MemorySize&quot;: 128,\n    &quot;Timeout&quot;: 10,\n    &quot;Region&quot;: &quot;ap-beijing&quot;,\n    &quot;Description&quot;: &quot;This is a template function&quot;\n  }\n}</code></pre></div>\n<p>第三方包全在这里：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939428188-IMG_0276.JPG\" alt=\"img\"></p>\n<p>Template.MyComponent.TencentApiGateway.json 即 API 网关</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{\n  &quot;protocols&quot;: [\n    &quot;http&quot;\n  ],\n  &quot;subDomain&quot;: &quot;service-0ok85tqh-1251901037.bj.apigw.tencentcs.com&quot;,\n  &quot;environment&quot;: &quot;test&quot;,\n  &quot;region&quot;: &quot;ap-beijing&quot;,\n  &quot;service&quot;: {\n    &quot;value&quot;: &quot;service-0ok85tqh&quot;,\n    &quot;created&quot;: true\n  },\n  &quot;apis&quot;: [\n    {\n      &quot;path&quot;: &quot;/&quot;,\n      &quot;method&quot;: &quot;ANY&quot;,\n      &quot;apiId&quot;: {\n        &quot;value&quot;: &quot;api-ivk6tk0y&quot;,\n        &quot;created&quot;: true\n      }\n    }\n  ]\n}</code></pre></div>\n<p>也就是说CLI自动帮我们创建SCF并将运行环境一并上传，再创建API 网关配置到SCF的触发器上。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">apigatewayConf:\n    protocol: https\n    environment: test</code></pre></div>\n<p>到这里demo就搞定了，已经可以正常访问了 。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939427902-IMG_0276.JPG\" alt=\"img\"></p>\n<h2 id=\"4-原理深入\"><a href=\"#4-%E5%8E%9F%E7%90%86%E6%B7%B1%E5%85%A5\" aria-label=\"4 原理深入 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. 原理深入</h2>\n<p>去云函数看实际运行环境，发现把.idea文件夹也给上传了 另外，多了如下俩本地没有的文件：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939428669-IMG_0276.JPG\" alt=\"img\"></p>\n<p><img src=\"https://img.serverlesscloud.cn/2020323/1584939427932-IMG_0276.JPG\" alt=\"img\"></p>\n<p>其实这就是Serverless的核心了，Serverless配置静态页面的原理自己是清楚的。比如Hexo就是生成页面之后上传到COS上就能访问了。</p>\n<p>但是，对于动态页面就比较好奇了，这是怎么实现的呢？其实就是靠着serverless.wsgi 这个文件等等。能看到这个模块描述：此模块将 AWS APIGateway 代理请求转换为 WSGI 请求。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&quot;&quot;&quot;\nThis module converts an AWS API Gateway proxied request to a WSGI request.\n\nInspired by: https://github.com/miserlou/zappa\n\nAuthor: Logan Raarup &lt;logan@logan.dk&gt;\n&quot;&quot;&quot;</code></pre></div>\n<p>还是相当有意思的。</p>\n<h2 id=\"5-迁移-lab\"><a href=\"#5-%E8%BF%81%E7%A7%BB-lab\" aria-label=\"5 迁移 lab 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. 迁移 LAB</h2>\n<p>接下来就得一点儿一点儿进行迁移了，不难想到应该有非常多的坑的，比如如何访问自己的 MySQL、Redis、 MongoDB，再比如Celery计划任务，自己是用RabbitMQ 的消息队列，这东西要怎么上云？这些问题都是自己需要后期去解决的。毕竟上大学就开始写的网站，有非常非常多的依赖……</p>\n<p>更新日志：当前 git 版本：7a65018，总提交 824 次</p>\n<p>迁移注定是一个大工程，下一篇将详细介绍迁移遇到的各种坑和填坑操作。</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-03-09-community-chenyuan/#%E5%89%8D%E8%A8%80\">前言</a></li>\n<li><a href=\"/blog/2020-03-09-community-chenyuan/#1-tencentserverless-%E4%BB%8B%E7%BB%8D\">1. TencentServerless 介绍</a></li>\n<li><a href=\"/blog/2020-03-09-community-chenyuan/#2-%E5%AE%89%E8%A3%85-serverless-framework\">2. 安装 Serverless Framework</a></li>\n<li><a href=\"/blog/2020-03-09-community-chenyuan/#3-%E9%83%A8%E7%BD%B2-python-flask-%E6%A1%86%E6%9E%B6\">3. 部署 Python Flask 框架</a></li>\n<li><a href=\"/blog/2020-03-09-community-chenyuan/#4-%E5%8E%9F%E7%90%86%E6%B7%B1%E5%85%A5\">4. 原理深入</a></li>\n<li><a href=\"/blog/2020-03-09-community-chenyuan/#5-%E8%BF%81%E7%A7%BB-lab\">5. 迁移 LAB</a></li>\n</ul>"},"previousBlog":{"id":"a6f28826-bc2f-552b-80ef-d961efacd2b0","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020318/1584508672111-Blazor.jpg","authors":["Elder James"],"categories":["user-stories"],"date":"2020-03-11T00:00:00.000Z","title":"通过 Serverless 加速 Blazor WebAssembly","description":"本文为 Serverless 社区成员撰稿。作者杨舜杰，系统架构研发工程师，开源爱好者，.NET开源项目 shriek-fx 作者","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","Blazor"],"keywords":"Serverless Blazor,Blazor WebAssembly,Serverless加速","outdated":true},"wordCount":{"words":215,"sentences":50,"paragraphs":49},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-11-blazor-webAssembly.md","fields":{"slug":"/blog/2020-03-11-blazor-webAssembly/","keywords":["nodejs","serverless","website","blazor","bucket","serverless","BlazorServerless","Serverless","Blazor"]}},"nextBlog":{"id":"f7418940-bfb5-5b3c-b3fa-0d5a80695033","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020318/1584509669262-qian.jpg","authors":["谢扬"],"categories":["user-stories"],"date":"2020-03-08T00:00:00.000Z","title":"Serverless 的前景和机会","description":"本文为 Serverless 社区成员撰稿。作者谢扬，蒸汽记忆创始人，SoLiD 中文社区（learnsolid.cn）发起人。目前聚焦研发一款 IDaaS 身份即服务产品 Authing","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","Authing"],"keywords":"Serverless前景,Serverless机会,Serverless使用场景","outdated":null},"wordCount":{"words":1284,"sentences":145,"paragraphs":145},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-08-community-xieyang.md","fields":{"slug":"/blog/2020-03-08-community-xieyang/","keywords":["serverless","无服务器","云函数","云原生","Serverless","FaaS","serverlesscloud","需要","服务"]}},"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":"eb3e239f-0ac6-5381-8a51-26142f95edfc","previousBlogId":"a6f28826-bc2f-552b-80ef-d961efacd2b0","nextBlogId":"f7418940-bfb5-5b3c-b3fa-0d5a80695033","categories":["user-stories"]}}}