溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

基于Serverless Component 全棧解決方案是怎樣的

發(fā)布時(shí)間:2021-12-06 11:43:53 來源:億速云 閱讀:114 作者:柒染 欄目:云計(jì)算

今天就跟大家聊聊有關(guān)基于Serverless Component 全棧解決方案是怎樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

什么是 Serverless Component

Serverless Component 是 Serverless Framework 的,支持多個(gè)云資源編排和組織的場(chǎng)景化解決方案。

Serverless Component 的目標(biāo)是磨平不同云服務(wù)平臺(tái)之間差異,你可以將它看作是可以更輕松地構(gòu)建應(yīng)用程序的依賴模塊。目前 Serverless Component 已經(jīng)形成一個(gè)由社區(qū)貢獻(xiàn)驅(qū)動(dòng)的生態(tài)系統(tǒng),你可以瀏覽和使用社區(qū)的所有組件,快速開發(fā)一款自己想要的應(yīng)用。

Serverless Component 工作原理

基于 Serverless Component 架構(gòu),你可以將任何云服務(wù)打包成一個(gè)組件。這個(gè)組件將含有一份 serverless.yml 配置文件,并且通過簡(jiǎn)單地進(jìn)行配置就可以使用。本文以 @serverless/tencent-express 來舉例。

如果我們要使用它,只需要新建一個(gè)項(xiàng)目 express-demo,然后修改 serverless.yml 配置如下:

express:
  component: '@serverless/tencent-express'
  inputs:
    region: ap-shanghai

因?yàn)?serverless 框架部署到云的鑒權(quán)都是基于 dotenv 注入全局的變量來實(shí)現(xiàn)的,所以還得在根目錄下新增 .env 文件,并配置對(duì)應(yīng)的鑒權(quán)參數(shù)。

之后我們就可以在 app.js 中輕松的編寫基于 express 的接口服務(wù)了:

const express = require('express')
const app = express()
app.get('/', function(req, res) {
  res.send('Hello Express')
})
// 不要忘了導(dǎo)出,因?yàn)樵摻M件會(huì)對(duì)它進(jìn)行包裝,輸出成云函數(shù)
module.exports = app

這背后所有的流程邏輯都是組件內(nèi)部實(shí)現(xiàn)的,包括:云函數(shù)的部署,API 網(wǎng)關(guān)的生成等。

下面是一張簡(jiǎn)單的組件依賴圖:

基于Serverless Component 全棧解決方案是怎樣的

通過此圖可以清晰地查看組件帶來的收益,借助社區(qū)現(xiàn)有的 @serverless/tencent-express 和 @serverless/tencent-website 組件,我們就可以很快構(gòu)建想要的全棧應(yīng)用。

全棧應(yīng)用實(shí)戰(zhàn)

接下來將介紹如何借助 Serverless Component 快速開發(fā)全棧 Web 應(yīng)用。

基于Serverless Component 全棧解決方案是怎樣的

在開始所有步驟前,需執(zhí)行 npm install -g serverless 命令,全局安裝 serverless cli

準(zhǔn)備

新建項(xiàng)目目錄 fullstack-application-vue,在該項(xiàng)目目錄下新增 apidashboard 目錄。然后新增 serverless.yml.env 配置文件,項(xiàng)目目錄結(jié)構(gòu)如下:

├── README.md 		// 項(xiàng)目說明文檔
├── api					  // Restful api 后端服務(wù)
├── dashboard			// 前端頁(yè)面
├── .env					// 騰訊云相關(guān)鑒權(quán)參數(shù):TENCENT_APP_ID,TENCENT_SECRET_ID,TENCENT_SECRET_KEY
└── serverless.yml	// serverless 文件

后端服務(wù)開發(fā)

進(jìn)入目錄 api,新增 app.js 文件,編寫 express 服務(wù)代碼,這里先新增一個(gè)路由 /,并返回當(dāng)前服務(wù)器時(shí)間:

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

app.use(cors())
app.get('/', (req, res) => {
  res.send(JSON.stringfy({ message: `Server time: ${new Date().toString()}` }))
})
module.exports = app

前端頁(yè)面開發(fā)

本案例使用的是 Vue.js + Parcel 的前端模板,當(dāng)然你可以使用任何前端項(xiàng)目腳手架,比如 Vue.js 官方推薦的 Vue CLI 生成的項(xiàng)目。進(jìn)入 dashboard 目錄,靜態(tài)資源你可以直接復(fù)制我準(zhǔn)備好的 項(xiàng)目模板,編寫入口文件 src/index.js:

// 這里初始是沒有 env.js 模塊的,第一次部署后會(huì)自動(dòng)生成
require('../env')

const Vue = require('vue')

module.exports = new Vue({
  el: '#root',
  data: {
    message: 'Click me!',
    isVisible: true,
  },
  methods: {
    async queryServer() {
      const response = await fetch(window.env.apiUrl)
      const result = await response.json()
      this.message = result.message
    },
  },
})

配置

前后端代碼都準(zhǔn)備好了,現(xiàn)在我們還需要簡(jiǎn)單配置下 serverless.yml 文件了:

name: fullstack-application-vue

frontend:
  component: '@serverless/tencent-website'
  # inputs 為 @serverless/tencent-website 組件的輸入
  # 具體配置說明參考:https://github.com/serverless-components/tencent-website/blob/master/docs/configure.md
  inputs:
    code:
      src: dist
      root: frontend
      hook: npm run build
    env:
      # 下面的 API服務(wù)部署后,獲取對(duì)應(yīng)的 api 請(qǐng)求路徑
      apiUrl: ${api.url}

api:
  component: '@serverless/tencent-express'
  # inputs 為 @serverless/tencent-express 組件的輸入
  # 具體配置說明參考:https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md
  inputs:
    code: ./api
    functionName: fullstack-vue-api
    apigatewayConf:
      protocol: https

簡(jiǎn)單的介紹下配置:首先,該文件定義了 frontendapi 兩個(gè)模塊,分別通過 component 屬性指定依賴的 Serverless Component。對(duì)于一個(gè)標(biāo)準(zhǔn)的 Serverless Component,都會(huì)接受一個(gè) inputs 屬性參數(shù),然后組件會(huì)根據(jù) inputs 的配置進(jìn)行處理和部署,具體有關(guān)配置的參數(shù)說明,請(qǐng)參考相關(guān)組件的官方配置說明。

部署

以上所有的步驟都完成后,接下來就是第一次部署了。

為什么不是直接聯(lián)調(diào)開發(fā)呢?因?yàn)楹蠖朔?wù)是云函數(shù),但是到目前為止,所有代碼都是在本地編寫,前端頁(yè)面接口請(qǐng)求鏈接還不存在。所以需要先將云函數(shù)部署到云端,才能進(jìn)行前后端調(diào)試。這個(gè)也是本人目前遇到的痛點(diǎn),因?yàn)槊看涡薷暮蠖朔?wù)后,都需要重新部署,然后進(jìn)行前端開發(fā)調(diào)試。如果你有更好的建議,歡迎評(píng)論指教~

部署時(shí),只需要運(yùn)行 serverless 命令就行,當(dāng)然如果你需要查看部署中的 DEBUG 信息,還需要加上 --debug 參數(shù),如下:

$ serverless
# or
$ serverless --debug

然后終端會(huì) balabalabala~, 輸出一大堆 DEBUG 信息,最后只需要看到綠色的 done 就行了:

基于Serverless Component 全棧解決方案是怎樣的

這樣一個(gè)基于 Serverless Component 的全棧應(yīng)用就開發(fā)好了。趕緊點(diǎn)擊你部署好的鏈接體驗(yàn)一下吧~

在線 Demo

數(shù)據(jù)庫(kù)連接

既然是全棧,怎么少得了數(shù)據(jù)庫(kù)的讀寫呢?接下來介紹如何添加數(shù)據(jù)庫(kù)的讀寫操作。

準(zhǔn)備

想要操作數(shù)據(jù)庫(kù),必須先擁有一臺(tái)數(shù)據(jù)庫(kù)實(shí)例,騰訊云 MySQL 云數(shù)據(jù)庫(kù) 現(xiàn)在也很便宜,可以購(gòu)買一個(gè)最基本按量計(jì)費(fèi) 1 核 1G 內(nèi)存 的 1 小時(shí)收費(fèi)不到 4 毛錢,是不是非常劃算。購(gòu)買好之后初始化配置,然后新增一個(gè) serverless 數(shù)據(jù)庫(kù),同時(shí)新增一張 users 表:

CREATE TABLE if not exists `test` ( `name` varchar (32) NOT NULL ,`email` varchar (64) NOT NULL ,`site` varchar (128) NOT NULL ) ENGINE = innodb DEFAULT CHARACTER SET = "utf8mb4" COLLATE = "utf8mb4_general_ci"

前端修改

首先修改前端入口文件 frontend/src/index.js 新增相關(guān)函數(shù)操作:

require('../env')

const Vue = require('vue')
const axios = require('axios')
module.exports = new Vue({
  el: '#root',
  data: {
    // ...
    form: {
      name: '',
      email: '',
      site: '',
    },
    userList: [],
  },
  methods: {
    // ...
    // 獲取用戶列表
    async getUsers() {
      const res = await axios.get(window.env.apiUrl + 'users')
      this.userList = (res.data && res.data.data) || []
    },
    // 新增一個(gè)用戶
    async addUser() {
      const data = this.form
      const res = await axios.post(window.env.apiUrl + 'users', data)
      console.log(res)
      if (res.data) {
        this.getUsers()
      }
    },
  },
  mounted() {
    // 視圖掛在后,獲取用戶列表
    this.getUsers()
  },
})

當(dāng)然你還需要修改視圖模板文件 frontend/index.html,在頁(yè)面模板中新增用戶列表和用戶表單:

<!-- user form -->
<section class="user-form" action="#">
  <div class="form-item">
    <label for="name">
      Name:
    </label>
    <input name="name" v-model="form.name" type="text" /><br />
  </div>
  <div class="form-item">
    <label for="email">
      Email:
    </label>
    <input name="email" v-model="form.email" type="email" /><br />
  </div>
  <div class="form-item">
    <label for="site">
      Site:
    </label>
    <input name="site" v-model="form.site" type="text" /><br />
  </div>
  <button @click="addUser">Submit</button>
</section>

<!-- user list -->
<section class="user-list">
  <ul v-if="userList.length > 0">
    <li v-for="item in userList" :key="item.id">
      <p>
        <b>Name: {{ item.name }}</b>
        <b>Email: {{ item.email }}</b>
        <b>Site: {{ item.site }}</b>
      </p>
    </li>
  </ul>
  <span v-else>No Data</span>
</section>

注意:如果還不熟悉 Vue.js 語(yǔ)法,請(qǐng)移至 官方文檔,當(dāng)然如果你想快速上手 Vue.js 開發(fā),也可以閱讀這份 Vue 從入門到精通 教程。

后端修改

這里使用 .env 來進(jìn)行數(shù)據(jù)庫(kù)連接參數(shù)配置,在 api 目錄下新增 .env 文件,將之前的數(shù)據(jù)庫(kù)配置填入文件中,參考 api/.env.example 文件。然后添加并安裝 dotenv 依賴,同時(shí)添加 mysql2 模塊進(jìn)行數(shù)據(jù)庫(kù)操作,body-parser 模塊進(jìn)行 POST 請(qǐng)求時(shí)的 body 解析。

之后新增后端 api,進(jìn)行數(shù)據(jù)庫(kù)讀寫,修改后的 api/app.js 代碼如下:

'use strict'
require('dotenv').config()
const express = require('express')
const cors = require('cors')
const mysql = require('mysql2')
const bodyParser = require('body-parser')

// init mysql connection
function initMysqlPool() {
  const { DB_HOST, DB_PORT, DB_DATABASE, DB_USER, DB_PASSWORD } = process.env

  const promisePool = mysql
    .createPool({
      host: DB_HOST,
      user: DB_USER,
      port: DB_PORT,
      password: DB_PASSWORD,
      database: DB_DATABASE,
      connectionLimit: 1,
    })
    .promise()

  return promisePool
}

const app = express()
app.use(bodyParser.json())
app.use(cors())

if (!app.promisePool) {
  app.promisePool = initMysqlPool()
}

app.get('/', (req, res) => {
  res.send(JSON.stringify({ message: `Server time: ${new Date().toString()}` }))
})

// get user list
app.get('/users', async (req, res) => {
  const [data] = await app.promisePool.query('select * from users')
  res.send(
    JSON.stringify({
      data: data,
    })
  )
})

// add new user
app.post('/users', async (req, res) => {
  let result = ''
  try {
    const { name, email, site } = req.body
    const [res] = await app.promisePool.query('INSERT into users SET ?', {
      name: name,
      email: email,
      site: site,
    })
    result = {
      data: res && res.insertId,
      message: 'Insert Success',
    }
  } catch (e) {
    result = {
      data: e,
      message: 'Insert Fail',
    }
  }

  res.send(JSON.stringify(result))
})

module.exports = app

配置修改

這里數(shù)據(jù)庫(kù)訪問需要通過騰訊云私有網(wǎng)絡(luò),所以還需要為云函數(shù)配置私有網(wǎng)絡(luò)(VPC),同時(shí)還需要配置能夠操作數(shù)據(jù)庫(kù)的角色(關(guān)于角色配置,可以直接到 角色管理頁(yè)面),這里我新建了一個(gè) QCS_SCFFull 的角色,可以用來訪問數(shù)據(jù)庫(kù)。然后修改 serverless.yml 中的配置:

# ...
api:
  component: '@serverless/tencent-express'
  # more configuration for @serverless/tencent-website,
  # refer to: https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md
  inputs:
    code: ./api
    functionName: fullstack-vue-api
    role: QCS_SCFFull # 此角色必須具備訪問數(shù)據(jù)庫(kù)權(quán)限
    functionConf:
      # 這個(gè)是用來訪問新創(chuàng)建數(shù)據(jù)庫(kù)的私有網(wǎng)絡(luò),可以在你的數(shù)據(jù)庫(kù)實(shí)例管理頁(yè)面查看
      vpcConfig:
        vpcId: vpc-6n5x55kb
        subnetId: subnet-4cvr91js
    apigatewayConf:
      protocol: https

最后重新部署一下就行了。

看完上述內(nèi)容,你們對(duì)基于Serverless Component 全棧解決方案是怎樣的有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI