前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实验室站迁移 Serverless 之路(上)|社区精选文章

实验室站迁移 Serverless 之路(上)|社区精选文章

作者头像
腾讯云serverless团队
发布2020-03-18 12:40:28
9720
发布2020-03-18 12:40:28
举报

本文为 Serverless 社区成员撰稿。作者高晨远,研发工程师,熟悉 Python 开发,常写 Web 和爬虫,日常维护有个人博客和实验室两个站点。供稿请戳~

0.前言

2月份,TencentServerless 举办了系列在线课堂分享,讲解了 Serverless 概念、架构、最佳实践以及如何开发一个 component 等技术知识。

因为对Serverless非常感兴趣,每次都参加了直播学习并提交了课堂作业,一路下来感觉还不错,因此决定把自己的实验室站(https://lab.yuangezhizao.cn/)迁移到 Serverless 试试看。

1.TencentCloudServerless 介绍

不得不感叹互联网时代科技的进步,之前我的实验室站采用的是传统方法发布网站的环境部署,虽然现在熟悉了操作并不觉得很麻烦,但是对于从来没接触过这块的人来说就比较难懂了。

而现在有了Serverless,就可以完全无视上面的操作步骤了,这里引用官网的两段话:

Serverless Framework 可以帮您以更少的成本和开销, 快速构建Serverless应用。它能够完美支持无服务器应用的开发,部署,测试,监控等环节。Serverless 是面向未来的运维方式。 Serverless 建立在下一代公共云服务之上,该服务仅在使用时自动扩容和收费。当规模,所用容量和成本管理实现自动化时,可节省99%的成本管理。 无服务器架构是全新的,因此我们需要改变先前对老架构和工作流的看法。serverless Framework 的目标是以一种简单,强大而优雅的使用体验为开发者、团队提供开发和运行serverless应用程序所需的所有工具。

这种方式非常方便,本人现在倒是觉得对于个人开发者来说,如果想构建轻量应用的话,用 Serverless 应该会节省非常多的时间。当然 Serverless 对比传统型应用还是有区别的,目前它并不能完美支持,举一个例子:Flask CLI就不支持,不过相信随着 Serverless 技术的发展,Serverless 的支持将更加全面。

对于企业开发者来说也是同理的,想快速上线一套网站的话,部署在一个服务器上倒是好说,可是当访问量上升之后,需要扩容的时候就比较麻烦了,这时候你得在多个服务器上部署并且配置负载均衡等等。

对我个人来说,我觉得 Serverless 最大的优点在于运维部署方面,通过 Serverless 部署,还是非常方便的。

2.安装 Serverless Framework

Serverless Framework 是基于 Node.js 的开源 CLI,注:需 Node 8+ 全局安装:

代码语言:javascript
复制
npm install serverless -g

这里没有使用cnpm的原因是因为网络还算ok没有特别耗时,另外忘记了之前在哪里看到过 cnpm 不会更新 package-lock.json,因此也就没有再去用第三方源。之后更新的话就

代码语言:javascript
复制
npm install serverless -g

官网的快速开始教程之后快速部署了个demo,即:

代码语言:javascript
复制
serverless create -t tencent-nodejs

命令里的tencent-nodejs是众多组件中的一个,组件列表:https://github.com/serverless/components

3.部署 Python Flask 框架

因为本人对Flask还算熟悉,所以干脆把部署这个Component当成Hello World好了。其中官网简介里写道:任何支持WSGI(Web Server Gateway Interface)的Python服务端框架都可以通过该组件进行部署,例如 Falcon框架等。

1. 创建新项目

  • 基于模板

通过sls直接根据模板创建服务,Serverless github 上有很多模板 比如https://github.com/serverless/components/tree/master/templates/tencent-flask

代码语言:javascript
复制
代码语言:javascript
复制
serverless create --template-url https://github.com/serverless/components/tree/master/templates/tencent-flask
代码语言:javascript
复制
源码如下:
代码语言:javascript
复制
代码语言:javascript
复制
# -*- coding: utf8 -*- import jsonfrom flask import Flask, jsonify, requestapp = Flask(__name__)  @app.route("/")def index():    return "Hello Flash" @app.route('/user', methods = ['POST'])def addUser():    # we must get request body from clound function event;    event = request.environ['event']    user = json.loads(event['body'])    return jsonify(data=user)  @app.route("/user", methods = ['GET'])def listUser():    users = [{'name': 'test1'}, {'name': 'test2'}]    return jsonify(data=users)  @app.route("/user/<id>", methods = ['GET'])def getUser(id):    return jsonify(data={'name': 'test1'})
  • 不基于模板

在Pycharm创建一个新的Flask项目:LAB_Serverless 以区别之前的 LAB

源码如下:

代码语言:javascript
复制
代码语言:javascript
复制
from flask import Flask app = Flask(__name__) @app.route('/')def hello_world():    return 'Hello World!' if __name__ == '__main__':    app.run()
代码语言:javascript
复制

2. 配置Serverless

  • 创建serverless.yml,这里更改了几处配置
代码语言:javascript
复制
代码语言:javascript
复制
MyComponent:  component: '@serverless/tencent-flask'  inputs:    region: ap-beijing    functionName: LAB_Serverless    code: ./    functionConf:      timeout: 10      memorySize: 128      environment:        variables:          TEST: value          Version: 2020-2-23_21:01:44      vpcConfig:        subnetId: ''        vpcId: ''    apigatewayConf:      protocol: https      environment: test
代码语言:javascript
复制
  • 创建.env,写入密匙(因为懒得每次部署都得拿起手机扫一扫授权(^_−)☆
代码语言:javascript
复制
代码语言:javascript
复制
TENCENT_SECRET_ID=<rm>TENCENT_SECRET_KEY=<rm>
代码语言:javascript
复制

3. 部署

serverless 的缩写是 sls,因此也可以用 sls 简化命令。但是这里报错了……报错的原因是requirements文件夹不存在。

查看终端

代码语言:javascript
复制
代码语言:javascript
复制
Microsoft Windows [版本10.0.17763.1039](c) 2018 Microsoft Corporation。保留所有权利。 D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless>sls --debug   DEBUG─Resolving the template's static variables.  DEBUG─Collecting components from the template.  DEBUG─Downloading any NPM components found in the template.  DEBUG─Analyzing the template's components dependencies.  DEBUG─Creating the template's components graph.  DEBUG─Syncing template state.  DEBUG─Executing the template's components graph.  DEBUG─Compressing function LAB_Serverless file to D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless\.serverless/LAB_Serverless.zip.(node:22500) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, stat 'D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless\.serverless\requirements'eploying    at Object.statSync (fs.js:946:3)    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)    at WriteStream.<anonymous> (C:\Users\yuangezhizao\.serverless\components\registry\npm\@serverless\tencent-flask@0.2.0\node_modules\@serverless\tencent-flask\node_modules\@serverless\tencent-scf\library\utils.js:124:20)    at WriteStream.emit (events.js:304:20)    at C:\Users\yuangezhizao\.serverless\components\registry\npm\@serverless\tencent-flask@0.2.0\node_modules\@serverless\tencent-flask\node_modules\graceful-fs\graceful-fs.js:298:14    at C:\Users\yuangezhizao\.serverless\components\registry\npm\@serverless\tencent-flask@0.2.0\node_modules\@serverless\tencent-flask\node_modules\graceful-fs\graceful-fs.js:325:16    at C:\Users\yuangezhizao\AppData\Roaming\npm\node_modules\serverless\node_modules\_graceful-fs@4.2.3@graceful-fs\graceful-fs.js:325:16    at FSReqCallback.oncomplete (fs.js:152:23)(node:22500) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function withouta catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)(node:22500) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.   194s»MyComponent»canceled 终止批处理操作吗(Y/N)? Y D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless>
代码语言:javascript
复制

然后去 .serverless 文件下的 Template.MyComponent.pyRequirements.json 文件中看到了requirements.txt。这里其实是故意操作的(特意没添加requirements.txt),说明 requirements.txt 必须存在!

因此,去创建文件内容为 Flask 的 requirements.txt

代码语言:javascript
复制
代码语言:javascript
复制
D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless>sls --debug   DEBUG─Resolving the template's static variables.  DEBUG─Collecting components from the template.  DEBUG─Downloading any NPM components found in the template.  DEBUG─Analyzing the template's components dependencies.  DEBUG─Creating the template's components graph.  DEBUG─Syncing template state.  DEBUG─Executing the template's components graph.  DEBUG─Generated requirements from D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless\requirements.txt in D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless\.serverless\requirements.txt...  DEBUG─Installing requirements from C:\Users\yuangezhizao\AppData\Local\Yugasun\serverless-python-requirements\Cache\2a1a661c4e3e6faadab5d001bc10cc3acccf648921aad7c279d94f138eaaf833_slspyc\requirements.txt ...  DEBUG─Using download cache directory C:\Users\yuangezhizao\AppData\Local\Yugasun\serverless-python-requirements\Cache\downloadCacheslspyc  DEBUG─Running ...  DEBUG─Compressing function LAB_Serverless file to D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless\.serverless/LAB_Serverless.zip.  DEBUG─Compressed function LAB_Serverless file successful  DEBUG─Uploading service package to cos[sls-cloudfunction-ap-beijing-code]. sls-cloudfunction-default-LAB_Serverless-1582464464.zip  DEBUG─Uploaded package successful D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless\.serverless/LAB_Serverless.zip  DEBUG─Creating function LAB_Serverless  DEBUG─Created function LAB_Serverless successful  DEBUG─Setting tags for function LAB_Serverless  DEBUG─Creating trigger for function LAB_Serverless  DEBUG─Deployed function LAB_Serverless successful  DEBUG─Starting API-Gateway deployment with name MyComponent.TencentApiGateway in the ap-beijing region  DEBUG─Service with ID service-0ok85tqh created.  DEBUG─API with id api-ivk6tk0y created.  DEBUG─Deploying service with id service-0ok85tqh.  DEBUG─Deployment successful for the api named MyComponent.TencentApiGateway in the ap-beijing region.   MyComponent:    region:              ap-beijing    functionName:        LAB_Serverless    apiGatewayServiceId: service-0ok85tqh    url:                 http://service-0ok85tqh-1251901037.bj.apigw.tencentcs.com/test/   44s»MyComponent»done  D:\yuangezhizao\Documents\PycharmProjects\LAB_Serverless>
代码语言:javascript
复制

趁机看下部署成功之后的 .serverless 文件夹:

这里 Template.MyComponent.TencentCloudFunction.json 即云函数

代码语言:javascript
复制
代码语言:javascript
复制
{  "deployed": {    "Name": "LAB_Serverless",    "Runtime": "Python3.6",    "Handler": "api_service.handler",    "MemorySize": 128,    "Timeout": 10,    "Region": "ap-beijing",    "Description": "This is a template function"  }}

第三方包全在这里:

Template.MyComponent.TencentApiGateway.json 即 API 网关

代码语言:javascript
复制
{  "protocols": [    "http"  ],  "subDomain": "service-0ok85tqh-1251901037.bj.apigw.tencentcs.com",  "environment": "test",  "region": "ap-beijing",  "service": {    "value": "service-0ok85tqh",    "created": true  },  "apis": [    {      "path": "/",      "method": "ANY",      "apiId": {        "value": "api-ivk6tk0y",        "created": true      }    }  ]}

也就是说CLI自动帮我们创建SCF并将运行环境一并上传,再创建API 网关配置到SCF的触发器上。

代码语言:javascript
复制
代码语言:javascript
复制
apigatewayConf:    protocol: https    environment: test
代码语言:javascript
复制

到这里demo就搞定了,已经可以正常访问了 。

4.原理深入

去云函数看实际运行环境,发现把.idea文件夹也给上传了 另外,多了如下俩本地没有的文件: 

其实这就是Serverless的核心了,Serverless配置静态页面的原理自己是清楚的。比如Hexo就是生成页面之后上传到COS上就能访问了。

但是,对于动态页面就比较好奇了,这是怎么实现的呢?其实就是靠着serverless.wsgi 这个文件等等。能看到这个模块描述:此模块将 AWS APIGateway 代理请求转换为 WSGI 请求。

代码语言:javascript
复制
"""This module converts an AWS API Gateway proxied request to a WSGI request. Inspired by: https://github.com/miserlou/zappa Author: Logan Raarup <logan@logan.dk>"""

还是相当有意思的。

5.迁移 LAB

接下来就得一点儿一点儿进行迁移了,不难想到应该有非常多的坑的,比如如何访问自己的 MySQL、Redis、 MongoDB,再比如Celery计划任务,自己是用RabbitMQ 的消息队列,这东西要怎么上云?这些问题都是自己需要后期去解决的。毕竟上大学就开始写的网站,有非常非常多的依赖…… 

更新日志:

当前 git 版本:7a65018,总提交 824 次

迁移注定是一个大工程,鉴于微信文章长度限制,下一篇将详细介绍迁移遇到的各种坑和填坑操作。

作者介绍

  高晨远 研发工程师,建有个人博客和实验室两个站点。


毕业于沈阳工业大学,本科电子信息工程专业。在校期间担任校团委网络管理中心技术部副部长,并在校信息与数据管理中心兼职维护网络设备。

熟悉 Python 开发,常写 Web 和爬虫,GitHub(Bilibili)重度用户,也是腾讯云的云产品重度用户,积极参与各种产品体验与反馈。

敲黑板:参与 Serverless 社区内容贡献,即可 100% 获得社区提供的精美礼品包,还有机会成为 Serverless 社区核心贡献者,参与社区的日常运营与管理!供稿请戳~

免费上云,就用 Serverless Framework

目前,Serverless Framework 服务暂时免费,且 Serverless Framework 服务用到云函数 SCF、API 网关、对象存储 COS 等产品,均提供免费额度。

具体免费详情可查阅:

https://cloud.tencent.com/document/product/1154/38792

立即使用 Serverless,只需三步

Serverless Framework 是构建和运维 Serverless 应用的框架,简单三步,即可通过 Serverless Framework 快速实现服务部署。
1、创建本地应用
  • 通过 npm 安装 Serverless
代码语言:javascript
复制
$ npm install -g serverless
  • 基于 tencent_nodejs 模板创建 hello_world
代码语言:javascript
复制
$ serverless create --template tencent-nodejs --path my-service
2、安装相关依赖
  • 执行 npm install 安装相关依赖
代码语言:javascript
复制
$ cd my-service$ npm install
3. 部署
  • 扫描微信二维码一键登录腾讯云账号,部署函数到云端
代码语言:javascript
复制
$ serverless deploy
  • 触发云函数
代码语言:javascript
复制
$ serverless invoke -f hello_world

部署完成后,即可在命令行中看到部署情况,也可以在腾讯云控制台看到对应资源。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ServerlessCloudNative 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.TencentCloudServerless 介绍
  • 2.安装 Serverless Framework
  • 3.部署 Python Flask 框架
    • 1. 创建新项目
      • 2. 配置Serverless
        • 3. 部署
        相关产品与服务
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档