溫馨提示×

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

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

如何開(kāi)發(fā)自己的第一個(gè) Serverless Component

發(fā)布時(shí)間:2021-12-16 11:20:24 來(lái)源:億速云 閱讀:102 作者:柒染 欄目:云計(jì)算

如何開(kāi)發(fā)自己的第一個(gè) Serverless Component,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

Serverless Component 運(yùn)行機(jī)制

在開(kāi)始開(kāi)發(fā)之前,我們先來(lái)了解下 Serverless Component 的運(yùn)行機(jī)制:

每個(gè) Serverless Component 實(shí)際上就是一個(gè) npm 包,你可以通過(guò) npm install 命令直接安裝。當(dāng)我們?cè)谝粋€(gè)依賴 Serverless Component 的應(yīng)用中,執(zhí)行命令 serverless --debug 部署時(shí),它首先會(huì)讀取 serverless.yml 文件中的 component 參數(shù)指定組件模塊,它會(huì)像安裝 npm 包一樣,自動(dòng)安裝到本地,然后自動(dòng)注入該組件模塊,同時(shí)執(zhí)行組件中的 default 函數(shù)(之后會(huì)講到),從而完成部署流程。

如何開(kāi)發(fā)自己的第一個(gè) Serverless Component

開(kāi)發(fā)步驟

一個(gè)完整組件的開(kāi)發(fā)流程應(yīng)該包括以下流程:

  1. 明確功能需求

  2. 定義組件配置:輸入和輸出參數(shù)

  3. 組件開(kāi)發(fā):default 函數(shù)、remove 函數(shù)(可選)

  4. 測(cè)試組件

  5. 發(fā)布 npm 包

接下來(lái)將按照以上步驟,一步一步實(shí)現(xiàn)騰訊云 CDN 組件。

1. 明確功能需求

騰訊云 CDN 控制臺(tái) 已經(jīng)提供了手動(dòng)配置加速域名的功能,但是作為一名懶惰的程序員,「手動(dòng)」 一直都是我嘗試規(guī)避的問(wèn)題。于是去看了看騰訊云文檔,看看官方有沒(méi)有提供相應(yīng)便捷的方式。果不其然騰訊云 API 已經(jīng)提供了相關(guān)接口,那么我們?yōu)槭裁床唤柚?API 實(shí)現(xiàn)一個(gè)能夠幫助我們自動(dòng)配置的 CDN 組件呢?

需求很明確:開(kāi)發(fā)一個(gè)能夠自動(dòng)配置 CDN 加速域名的組件,幫助我們節(jié)省手動(dòng)配置時(shí)間。

2. 定義組件配置

要實(shí)現(xiàn) CDN 域名的添加,需要借助 2 個(gè)騰訊云 API 接口:新增加速域名、HTTPS 配置。通過(guò)閱讀這兩份接口文檔,總結(jié)出一份配置說(shuō)明文件 config.md ,內(nèi)容如下:

MyCDN:
  component: '@serverless/tencent-cdn'
  inputs:
    host: abc.com
    hostType: cos
    origin: www.test.com
    backupOrigin: www.test.com
    serviceType: web
    fullUrl: on
    fwdHost: ww.test.com
    cache:
      - type: 0
        rule: all
        time: 1000
      - type: 0
        rule: all
        time: 1000
    cacheMode: simple
    refer:
      - type: 1
        list:
          - 'qq.baidu.com'
          - '*.baidu.com'
    accessIp:
      type: 1
      list:
        - '1.2.3.4'
        - '2.3.4.5'
    https:
      certId: 123
      cert: 123
      privateKey: 123
      http2: off
      httpsType: 2
      forceSwitch: -2

其中 inputs 就是組件的輸入?yún)?shù),其實(shí)這些參數(shù)都是從接口文檔中拷貝出來(lái)而已,實(shí)際開(kāi)發(fā)時(shí),需根據(jù)自己組件功能,定制化配置就好。

無(wú)服務(wù)框架的配置都是 yaml 文件,所以在定義組件配置時(shí),需要將 API 的參數(shù)做好 yaml 規(guī)范映射。比如 yaml 文件中,符號(hào) - 是用來(lái)定義數(shù)組的。如果對(duì) yaml 語(yǔ)法還不太熟,可以參考這份 YAML 語(yǔ)言教程。

組件輸入定義好了,還需要定義輸出內(nèi)容,只需要大致的組織 API 請(qǐng)求返回結(jié)構(gòu)就行,盡量簡(jiǎn)潔明了:

{
	host: 'abc.com',
	hostId: '123'
	origin: 'www.test.com',
	cname: 'www.test.com.cdn.dnsv1.com',
	https: true
}

3. 組件開(kāi)發(fā)

對(duì)于一個(gè)標(biāo)準(zhǔn)的 Serverless Component ,結(jié)構(gòu)如下:

// serverless.js
const { Component } = require('@serverless/core')
class MyComponent extends Component {
  /*
   * Default (必須)
   * - default 是用來(lái)執(zhí)行、準(zhǔn)備和更新你的組建的函數(shù)
   * - 執(zhí)行命令 `$ serverless` 會(huì)運(yùn)行此函數(shù)
   * - You can run this function by running the "$ serverless" command
   */
  async default(inputs = {}) {
    return {}
  }

  /*
   * Remove (可選)
   * - 如果你的組件需要?jiǎng)h除基礎(chǔ)設(shè)施,推薦你添加他
   * - 執(zhí)行命令 `$ serverless remove` 會(huì)運(yùn)行此函數(shù)
   */
  async remove(inputs = {}) {
    return {}
  }

  /*
   * Anything (可選)
   * - 如果你想發(fā)布帶有額外功能的組件,你可以將邏輯寫(xiě)在一個(gè)函數(shù)里,函數(shù)名可以自定義
   * - 執(zhí)行命令 `$ serverless anything` 會(huì)運(yùn)行此函數(shù)
   */
  async anything(inputs = {}) {
    return {}
  }
}
module.exports = MyComponent

了解了組件的結(jié)構(gòu),接下來(lái),就開(kāi)始開(kāi)發(fā)吧~

3.1 初始化項(xiàng)目

創(chuàng)建項(xiàng)目目錄 tencent-cdn,執(zhí)行 npm init 初始化項(xiàng)目,根據(jù)命令指引,填寫(xiě)相關(guān)信息就行:

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (cdn-module) tencent-cdn
version: (1.0.0)
description: Tencent Cloud CDN Component
entry point: (index.js) serverless.js
test command:
git repository:
keywords: cdn,serverless,serverless-component,serverlesscomponent,tencent
author: yugasun
license: (ISC) MIT
About to write to /Users/yugasun/Desktop/Develop/serverless/cdn-module/package.json:

{
  "name": "tencent-cdn",
  "version": "1.0.0",
  "description": "Tencent Cloud CDN Component",
  "main": "serverless.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "cdn",
    "serverless",
    "serverless-component",
    "serverlesscomponent",
    "tencent"
  ],
  "author": "yugasun",
  "license": "MIT"
}


Is this OK? (yes)

然后新建 serverless.js 文件,復(fù)制上面的模板代碼到 serverless.js 文件中。

3.2 編寫(xiě) default 函數(shù)

default 函數(shù)代碼,這里就不貼出來(lái)了,有點(diǎn)多 o(╯□╰)o。

主要思路就是,根據(jù) inputs 輸入?yún)?shù),規(guī)范成接口請(qǐng)求參數(shù),然后請(qǐng)求接口,執(zhí)行配置就好。

對(duì)于騰訊云 API,所有的接口請(qǐng)求都需要鑒權(quán),所以這里需要先實(shí)例化一個(gè) Capi,如下:

import { Capi } from '@tencent-sdk/capi'
const capi = new Capi({
	SecretId: this.context.credentials.tencent.SecretId,
  SecretKey: this.context.credentials.tencent.SecretKey,
  ServiceType: 'cdn',
})

注意:關(guān)于請(qǐng)求云 API 庫(kù) @tencent-sdk/capi 說(shuō)明文檔已經(jīng)很全面了,當(dāng)然你也可以在這里看到 源碼.

它需要傳入 SecretId、SecretKey、ServiceType 三個(gè)參數(shù),SecretIdSecretKey 可以通過(guò) this.context.credentials.tencent 來(lái)獲取,執(zhí)行 serverless 命令在執(zhí)行時(shí),它會(huì)根據(jù)用戶項(xiàng)目根目錄配置的 .env 文件,自動(dòng)注入到 this.context.credentials.tencent 上。ServiceType 是當(dāng)前服務(wù)類型,這是騰訊云 API 定義的,針對(duì)不同業(yè)務(wù)配置相應(yīng)參數(shù)就行。

注意:不同的云服務(wù)商掛到 this.context.credentials 上的屬性也是不一樣,比如這里騰訊云是 tencent,AWS 是 aws,目前支持的所有云服務(wù)商的屬性配置源碼,在這里可以找到,@serverless/cli

然后請(qǐng)求 新增加速域名 接口:

// cdnInputs 就是我們組裝好的請(qǐng)求參數(shù)
await AddCdnHost(capi, cdnInputs)

這里有個(gè)重點(diǎn):請(qǐng)求 新增加速域名 接口成功返回后,CDN 并不會(huì)立即部署成功,這個(gè)是需要時(shí)間的,所以我們執(zhí)行后,需要輪訓(xùn)當(dāng)前新增域名的狀態(tài),當(dāng)為部署成功時(shí),我們才能進(jìn)行之后的邏輯。

3.3 組件狀態(tài)保存

Serverless Component 在執(zhí)行 default 函數(shù)時(shí),它會(huì)產(chǎn)生一些狀態(tài),比如新增 CDN 域名成功后,會(huì)產(chǎn)生一個(gè) hostId,我們可以保存在 this.state 對(duì)象中,通過(guò)執(zhí)行 this.save() 函數(shù),它會(huì)將 this.state 保存到項(xiàng)目根目錄的 .serverless 文件夾中一個(gè)名為 Template.MyCDN.jsonMyCDN 是我定義的當(dāng)前 Serverless 應(yīng)用的名稱)文件中,方便之后在做組件建刪除時(shí)使用。

3.4 編寫(xiě) remove 函數(shù)

Serverless Component 刪除的邏輯,就是再 serverless remove 命令時(shí),它會(huì)讀取 default 函數(shù)執(zhí)行保存到 .serverless 中的狀態(tài)文件,并注入到 this.state 上 , 然后我們可以根據(jù) state 中的值進(jìn)行移除,比如我這里會(huì)用到 host, 因?yàn)?刪除加速域名接口 需要傳遞 host 參數(shù)。

3.5 完善說(shuō)明文檔

開(kāi)源項(xiàng)目的 README 一定要寫(xiě)的清晰明了,方便開(kāi)發(fā)者順利的使用和開(kāi)發(fā)。

4. 測(cè)試組件

到這里我們組件的基本開(kāi)發(fā)完成了,在發(fā)布之前,還得進(jìn)行本地測(cè)試,Serverless Framework 提供了一個(gè)很好地本地調(diào)試方法,就是應(yīng)用的 serverless.ymlcomponent 可以指定本地項(xiàng)目路徑,比如在 tencent-cdn 目錄下,創(chuàng)建 test 文件夾,然后新增 serverless.yml 配置如下:

MyCDN:
  component: ../
  inputs:
    host: abc.com
    ...

這里的 ../ 就是相對(duì)路徑,因?yàn)?tencent-cdn 組件的 serverless.js 文件在 tencent-cdn 根目錄下,之后我們就可以進(jìn)入 test 目錄,執(zhí)行部署和移除操作,來(lái)測(cè)試我們的組件了。

注意:雖然一個(gè) Serverless Component 是一個(gè) npm 模塊,我們可以通過(guò) package.json 中的 main 屬性指定項(xiàng)目中任意的文件入口,但是如果沒(méi)有 serverless.js 文件,serverless 命令是沒(méi)法通過(guò) component 指定的本地路徑調(diào)試的。

5. 發(fā)布 npm 包

發(fā)布 npm 包,首先需要你擁有一個(gè) npm 賬號(hào),請(qǐng)先前往 npm官網(wǎng) 注冊(cè),然后本地執(zhí)行 npm login 登錄你的賬號(hào)。

經(jīng)過(guò)測(cè)試沒(méi)問(wèn)題,就可以執(zhí)行 npm publish 就可以發(fā)布到 npm 倉(cāng)庫(kù)了。

源碼

最終實(shí)現(xiàn)源碼:@serverless/tencent-cdn。

組件引用

每個(gè)組件實(shí)例,都會(huì)有個(gè) load 方法,我們可以通過(guò)此方法來(lái)加載其他組件,如下:

const cdnComp = await this.load('@serverless/tencent-cdn', 'cdnComp');

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(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