Serverless实践-Node服务上线部署

1,513 阅读6分钟

Serverless实践-Node服务上线部署

这是我参与更文挑战的第16天,活动详情查看:更文挑战

本文旨在帮助不懂运维/网络/服务器知识的小白,在不租用云服务器实现Node服务(Node开发的后端应用)的上线部署

本系列已更新:

超多图预警!!!

该手把手Serverless实践系列预计会出几篇包含静态站点,云函数,Node服务等等

如有表述不清,内容错误等还请评论区斧正

腾讯云Serverless服务为例

创建Serverless应用

进入控制台面板,通常在首页右上角

图片

然后在左上角的云产品列表中找到Serverless应用中心

图片

然后你能看到如下的界面

图片

点击新建,可以看见有很多模板可供选择,咱这里先选择Express应用,然后点击下一步

图片

基本配置包含:

  • 应用的名称:随心所欲填
  • 环境(dev/test/prod):随心所欲的选
  • 地域(服务器所在地区):随心所欲的选

高级配置包含:

  • 内存:默认128MB,可以根据服务的情况选择256或者更高,服务会在流量大的情况下动态扩容(建立新服务实例分摊流量)不用担心因为配置问题服务挂掉
  • 超时时间:默认3s,建议改长一点(10s左右),因为服务存在冷启动问题,所以在3s的时候部分请求可能会由于服务还未启动或者未及时响应导致接口调用失败
  • 环境变量:(可以忽略,建议配在项目的.env文件中)

图片

填完基本信息后紧接着点击完成即可

图片

赖心等待几分钟服务就初始化完毕了

在Serverless应用中心首页可以看到使用额度数据

图片

线上访问地址

应用创建完成后能在卡片处看见后端服务的线上地址:

图片

比如我这个demo服务地址:service-rbji0bev-1256505457.cd.apigw.tencentcs.com/release/

访问默认效果如下:

图片

模板的源代码

选择卡片中的 开发部署 -> 更新应用

图片

紧接着 选择 本地开发 ,点击下载项目

图片

模板目录结构

/home/sugar/Downloads/source
├── index.html             
├── layer                  
|  └── serverless.yml      
├── package-lock.json      
├── package.json           
├── serverless.yml   
├── sls.js
└── src.map

directory: 1 file: 7

需要关注的就只有serverless.yml配置文件与sls.js

其中serverless.yml文件就是Serverless服务的一个配置文件

没有特殊需求咱可以不用管它,它是生成好了的与你创建的项目一一对应

其中sls.js文件才是咱们项目的源代码

sls.js源代码

点击查看完整源码
const express = require('express')
const path = require('path')
const app = express()

// Routes
app.get(`/`, (req, res) => {
  res.sendFile(path.join(__dirname, 'index.html'))
})

app.get('/user', (req, res) => {
  res.send([
    {
      title: 'serverless framework',
      link: 'https://serverless.com'
    }
  ])
})

app.get('/user/:id', (req, res) => {
  const id = req.params.id
  res.send({
    id: id,
    title: 'serverless framework',
    link: 'https://serverless.com'
  })
})

app.get('/404', (req, res) => {
  res.status(404).send('Not found')
})

app.get('/500', (req, res) => {
  res.status(500).send('Server Error')
})

// Error handler
app.use(function(err, req, res, next) {
  console.error(err)
  res.status(500).send('Internal Serverless Error')
})

app.listen(8080)

module.exports = app

省去无关代码,核心上就只有短短4行

const express = require('express')
const app = express()

// 省略注册的路由

// 省略Error handler

app.listen(8080)

module.exports = app
  1. 引入express
  2. 执行express实例化
  3. 调用listen方法监听一个端口,以启动服务福
  4. 导出这个实例

所以要部署咱们自己的Node - Express项目(其它Node项目类似),只需要简单的2步:

  1. 拷贝serverless.yml 文件到自己项目对应目录
  2. 小小修改sls.js文件,先引入自己的express实例,再将其导出即可

可参看后面的现有Express项目改造示例

serverless.yml配置文件解释

只关注根目录下的那个serverless.yml文件,不关注layer/serverless.yml

component: express
name: express-jskJUp-v4
org: '1256505457'
app: suixinsuoyu
stage: dev
inputs:
  src:
    src: ./
    exclude:              # 上传代码时,需要排除的目录或文件
      - .env
      - node_modules/**
  region: ap-chengdu
  runtime: Nodejs10.15
  apigatewayConf:
    protocols:
      - http
      - https
    environment: release
    serviceTimeout: 60
    autoCreateDns: false
  isAutoCiDeploy: false
  functionConf:
    eip: false
    timeout: 3           # 配置的响应超时时间,超过此时间接口未响应,就直接返回错误
    memorySize: 128      # 配置的服务使用的内存大小
  layers:
    - name: '${output:${stage}:${app}:suixinsuoyu-layer.name}'
      version: '${output:${stage}:${app}:suixinsuoyu-layer.version}'

咱们只用关心 配置中加了注释的项

不同的框架/服务类型配置由些许差异

完整的配置介绍可翻阅文档:Serverless应用中心-yml文件规范

测试发现,服务自动安装package.json中的依赖有些问题,为问题造成的避免影响,所以需要上传本地的node_modules目录

现有Express项目改造示例

原目录结构

├── README.md
├── _tests_
|  └── index.test.js
├── docs
|  ├── api
|  └── db.md
├── jest.config.js
├── package.json
├── src
|  ├── app.js
|  ├── config
|  ├── constants
|  ├── db
|  ├── routes
|  └── utils
└── yarn.lock

src/app.js源码,省略部分代码

const dotenv = require('dotenv')
const express = require('express')

// 读取-打印环境变量
// 读取.env环境变量配置文件
console.log(dotenv.config())

const { serverConfig } = require('./config')
// 用户的所有路由
const mainRouter = require('./routes')

// 实例化express
const app = express()

// 注册一些中间件
app.use(express.urlencoded({ extended: false }))
app.use(express.json({ strict: true }))

// 首先进入的路由(全局的拦截器)
app.route('*').all(async (req, res, next) => {
  //  -------跨域支持-----------
  // 登录校验
  next()
})
// 注册所有路由
app.use(mainRouter)

app.listen(serverConfig.port, serverConfig.hostname, () => {
  console.log(`server start at ${serverConfig.hostname}:${serverConfig.port}`)
})

改造步骤

参考上面叙述的两个步骤:

  1. sls.js,serverless.yml文件拷贝(一共3个),拷贝后的目录如下
├── LICENSE
├── README.md
├── _tests_
|  └── index.test.js
├── docs
|  ├── api
|  └── db.md
├── jest.config.js
├── layer       
|  └── serverless.yml # 1
├── package.json
├── serverless.yml   # 2
├── sls.js           # 3
├── src
|  ├── app.js
|  ├── config
|  ├── constants
|  ├── db
|  ├── routes
|  └── utils
└── yarn.lock

directory: 10 file: 11
  1. 小小修改 app.js 与 sls.js中的源码

src/app.js改动

// 省略其它代码
app.listen(serverConfig.port, serverConfig.hostname, () => {
  console.log(`server start at ${serverConfig.hostname}:${serverConfig.port}`)
})

// 添加的一行导出app实例
module.exports = app

sls.js源码

// 引入导出的app
const app = require('./src/app')

// 再将其导出
module.exports = app

大功改成,改造完毕

线上WebIDE查看源码

回到Serverless-应用选择我们刚刚创建的应用,回到熟悉的卡片页

图片

点击云函数蓝色的那个函数名称(是一个链接),就会跳转到WebIDE页面

图片

咱就能通过WebIDE查看到我们模板项目的源代码,其中还有一些不是模板中的代码,咱不管它,也不去修改

部署上线

下面咱简单修改一下我们刚才的那个模板项目,然后部署上线

简单修改模板

点击查看 index.html 修改后的内容
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>随心所欲Demo - Express.js</title>
</head>

<body>
  <h1>
    接口列表(随心所欲Demo)
  </h1>
  <ul>
    <li><span>首页</span><span>GET:</span>/</li>
    <li><span>获取随机数字</span><span>GET:</span>/random/code</li>
    <li><span>登录</span><span>POST:</span>/user/login</li>
    <li><span>404</span><span>GET:</span>/404</li>
  </ul>
</body>

</html>
点击查看 sls.js 修改后的内容
const express = require('express')
const path = require('path')
const app = express()

// Routes
app.get(`/`, (req, res) => {
  res.sendFile(path.join(__dirname, 'index.html'))
})

app.get('/random/code',(req,res)=>{
  res.send({
    num:Math.random()
  })
})
app.post('/user/login', (req, res) => {
  res.send({
    code:0,
    data:{
      token:'test-token'
    },
    msg:'ok'
  })
})

app.get('/404', (req, res) => {
  res.status(404).send('Not found')
})

// Error handler
app.use(function(err, req, res, next) {
  console.error(err)
  res.status(500).send('Internal Serverless Error')
})

app.listen(8080)

module.exports = app

前置环境

  • Node.js

确保电脑上有Node.js环境,没有可参考菜鸟教程:Node.js 安装

打开你的终端工具查看是否拥有Node环境

node -v

图片

Serverless Framework

安装Serverless Framework

npm install -g serverless

验证是否安装完成

sls -v

图片

部署

在项目跟路径执行部署指令

部署

sls deploy

会在终端界面中出现一个二维码,使用微信扫一扫即可实现登录

此时静静等待几秒

图片

出现此图说明部署成功

image.png

示例访问地址:service-rbji0bev-1256505457.cd.apigw.tencentcs.com/release/

部署的GET接口地址:

访问结果可以看出我们改造后的模板项目已经上去了

图片

到此从0-1的创建应用到部署上线的流程都走完了

TODO

  • 补全原生Node使用HTTP模块开发的应用部署
  • 补全koa项目的部署
  • 探究一下终端如何展示二维码的,展示图片的可能性