前言 首先介紹下在本文出現(xiàn)的幾個比較重要的概念:
函數(shù)計算(Function Compute): 函數(shù)計算是一個事件驅(qū)動的服務(wù),,通過函數(shù)計算,,用戶無需管理服務(wù)器等運行情況,只需編寫代碼并上傳,。函數(shù)計算準(zhǔn)備計算資源,,并以彈性伸縮的方式運行用戶代碼,而用戶只需根據(jù)實際代碼運行所消耗的資源進(jìn)行付費,。函數(shù)計算更多信息 參考,。
Fun: Fun 是一個用于支持 Serverless 應(yīng)用部署的工具,能幫助您便捷地管理函數(shù)計算,、API 網(wǎng)關(guān),、日志服務(wù)等資源。它通過一個資源配置文件(template.yml),,協(xié)助您進(jìn)行開發(fā),、構(gòu)建、部署操作,。Fun 的更多文檔 參考,。
2.0 版本的 Fun,在部署這一塊做了很多努力,,并提供了比較完善的功能,,能夠做到將云資源方便、平滑地部署到云端,。但該版本,,在本地開發(fā)上的體驗,還有較多的工作要做,。于是,,我們決定推出 Fun Local 彌補這一處短板。
Fun Local: Fun Local 作為 Fun 的一個子命令存在,,只要 Fun 的版本大于等于 2.6.0,,即可以直接通過 fun local 命令使用。Fun Local 工具可以將函數(shù)計算中的函數(shù)在本地完全模擬運行,,并提供單步調(diào)試的功能,,旨在彌補函數(shù)計算相對于傳統(tǒng)應(yīng)用開發(fā)體驗上的短板,并為用戶提供一種解決函數(shù)計算問題排查的新途徑,。
《開發(fā)函數(shù)計算的正確姿勢》系列除本篇是為用戶介紹 fun local 的使用方法外,,其他幾篇都會向用戶展示 Fun Local 對于函數(shù)計算開發(fā)所帶來的效率上的巨大提升。
Fun Local 命令格式 使用 fun local invoke -h 可以查看 fun local invoke 的幫助信息:
$ fun local invoke -h Usage: invoke [options] <[service/]function>
Run your serverless application locally for quick development & testing.
Options:
-d, --debug-port <port> used for local debugging
-c, --config <ide> print out ide debug configuration. Options are VSCode
-e, --event <path> event file containing event data passed to the function
-h, --help output usage information
本地運行函數(shù) 運行函數(shù)的命令格式為:
fun local invoke [options] <[service/]function> 其中 options、service 都是可以省略的,。 從調(diào)用方式上,,可以理解為,,fun local invoke 支持通過 函數(shù)名 調(diào)用,,或者 服務(wù)名/函數(shù)名 的方式調(diào)用,,即
fun local invoke function fun local invoke service/function 比如,,如果要運行名為 php72 的函數(shù),,可以直接通過以下命令完成:
fun local invoke php72 調(diào)用結(jié)果為:
再比如,,要運行名為 nodejs8 的函數(shù),,可以使用:
fun local invoke nodejs8 會得到如下結(jié)果:
如果 template.yml 中包含多個服務(wù),而多個服務(wù)中包含相同名稱的函數(shù)時,,通過函數(shù)名的方式調(diào)用 fun 只會運行第一個名稱匹配的函數(shù),。
如果想要精準(zhǔn)匹配,可以使用 服務(wù)名/函數(shù)名 的方式,。
比如想要調(diào)用 localdemo 下的 php72,,可以使用:
fun local invoke localdemo/php72 在本例中,會得到和 fun local invoke php72 一致的結(jié)果,。
以下是一個運行 nodejs8 函數(shù)的演示:
本地運行 java 類型的函數(shù) java 不同于解釋型的語言,,在作為函數(shù)運行前,需要先編譯,。在我們的例子中,,可以進(jìn)入到 demo 中的 java8 目錄,然后執(zhí)行:
mvn package 可以看到 log:
[INFO] skip non existing resourceDirectory /Users/tan/code/fun/examples/local/java8/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo --- [INFO] No tests to run. [INFO] [INFO] --- maven-dependency-plugin:2.8:copy-dependencies (copy-dependencies) @ demo --- [INFO] fc-java-core-1.0.0.jar already exists in destination. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ demo --- [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.223 s [INFO] Finished at: 2018-11-22T10:45:14 08:00 [INFO] Final Memory: 15M/309M [INFO] ------------------------------------------------------------------------ 該命令會在 java8/target 目錄下生成 demo-1.0-SNAPSHOT.jar 文件,。
由于我們在 template.yml 中配置的 CodeUri 為 java8/target/demo-1.0-SNAPSHOT.jar,,因此不需要任何改動,可以直接通過以下命令運行:
fun local invoke java8 運行結(jié)果如下:
本地調(diào)試 fun local invoke 支持 -d, --debug-port <port> 選項,,可以對函數(shù)進(jìn)行本地單步調(diào)試,。本文檔只介紹如何配置調(diào)試,并不涉及調(diào)試技巧,,更多文章,,請參考。
備注:Fun Local 涉及到的 debugging 技術(shù)全部都基于各個語言通用的調(diào)試協(xié)議實現(xiàn)的,,因此無論什么語言的開發(fā)者,,即使不喜歡用 VSCode,只要使用對應(yīng)語言的 remote debugging 方法都可以進(jìn)行調(diào)試,。
本地調(diào)試 nodejs、python 類型的函數(shù) 對于 nodejs6,、nodejs8,、python2.7、python3,、java8 類型的函數(shù),,調(diào)試方法基本一致,。下面拿 nodejs8 舉例。
我們上面演示了可以通過 fun local invoke nodejs8 來運行名稱為 nodejs8 的函數(shù),,如果想對該函數(shù)進(jìn)行調(diào)試,,只需要使用 -d 參數(shù),并配置相應(yīng)的端口號即可,。
比如我們以調(diào)試方式運行函數(shù),,并將調(diào)試端口設(shè)定在 3000,可以通過下面的命令:
fun local invoke -d 3000 nodejs8 另外,,推薦添加 --config 參數(shù),,在調(diào)試的同時,可以輸出用來調(diào)試的 IDE 的配置信息:
fun local invoke -d 3000 --config VSCode nodejs8 命令執(zhí)行結(jié)果如下:
skip pulling images ... you can paste these config to .vscode/launch.json, and then attach to your running function ///////////////// config begin ///////////////// { "version": "0.2.0", "configurations": [ { "name": "fc/localdemo/nodejs8", "type": "node", "request": "attach", "address": "localhost", "port": 3000, "localRoot": "/Users/tan/code/fun/examples/local/nodejs8", "remoteRoot": "/code", "protocol": "inspect", "stopOnEntry": false } ] } ///////////////// config end ///////////////// Debugger listening on ws://0.0.0.0:3000/b65c288b-bd6a-4791-849b-b03e0d16b0ce For help see https:///en/docs/inspector 程序會阻塞在這里,,并不會繼續(xù)往下執(zhí)行,。只有 IDE 的連接上來后,程序才會繼續(xù)執(zhí)行,。接下來,,我們針對 VSCode 配置、VSCode 調(diào)試兩個方面分別進(jìn)行講解,。
其中 VSCode 配置只有在第一次對函數(shù)進(jìn)行調(diào)試時才需要,,如果已經(jīng)配置過,則不需要再次配置,。
VSCode 配置 創(chuàng)建 vscode launch.json 文件
復(fù)制日志中的 config begin 與 config end 之間的配置到 launch.json 中,。
完成上面配置后,在 Debug 視圖可以看到配置的函數(shù)列表,。
至此,,VSCode 配置完成。VSCode 更多配置知識可以參考官方文檔,。
VSCode 調(diào)試 VSCode 配置成功后,,只需要在 VSCode 編輯器側(cè)邊欄單擊設(shè)置斷點,然后點擊“開始調(diào)試”按鈕,,即可開始調(diào)試,。
本地調(diào)試 java 類型的函數(shù) 調(diào)試 java 函數(shù)的過程和 nodejs、python 是類似的,。但由于 java 程序員通常喜歡用 IDEA,、Eclipse 這樣的 IDE,所以我們單獨拿出來說一下,。
使用 VSCode 調(diào)試 java 使用 VSCode 調(diào)試 java 時,,需要安裝兩個插件:Language Support for Java(TM) by Red Hat、Debugger for Java,。利用 VSCode 的插件市場安裝插件很簡單,,可以 參考,。
使用 IDEA 調(diào)試 java IDEA 配置 IDEA 配置 remote debugging 還是比較簡單的,首先在菜單欄依次點擊 Run -> Edit Configurations...:
然后新建一個 Remote Debugging:
然后我們隨意輸出一個名字,,并配置端口號為 3000.
以下是一個配置 IDEA remote debugging 的完整流程演示:
使用 IDEA 開始調(diào)試 首先將 java 函數(shù)以 debug 的方式運行起來:
fun local invoke -d 3000 java8
可以看到函數(shù)卡在這里了,,接著我們使用 IDEA 連接并開始調(diào)試??梢酝ㄟ^菜單欄上的 Run -> Debug... 或者工具欄直接點擊 Debug 按鈕,,即可開始調(diào)試。
以下是一個用 IDEA 進(jìn)行 remote debugging 的完整流程演示:
本地調(diào)試 php 類型的函數(shù) php 的調(diào)試與其他類型的函數(shù)調(diào)試在流程上有一些不同,。
首先,,php 的運行通過 fun local invoke php72 命令完成,這與其他類型的函數(shù)一致,。調(diào)試時,,也像其他類型的函數(shù)一樣,通過 -d 參數(shù)以調(diào)試模式啟動函數(shù):
fun local invoke -d 3000 --config VSCode php72 但不同的是,,以 debug 方式運行 php 函數(shù)后,,php 函數(shù)并沒有阻塞等待 vscode 調(diào)試器的連接,而是直接運行結(jié)束,。
skip pulling images ... you can paste these config to .vscode/launch.json, and then attach to your running function ///////////////// config begin ///////////////// { "version": "0.2.0", "configurations": [ { "name": "fc/localdemo/php72", "type": "php", "request": "launch", "port": 3000, "stopOnEntry": false, "pathMappings": { "/code": "/Users/tan/code/fun/examples/local/php7.2" }, "ignore": [ "/var/fc/runtime/**" ] } ] } ///////////////// config end ///////////////// FunctionCompute php7.2 runtime inited. FC Invoke Start RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 FC Invoke End RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 hello world
RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 Billed Duration: 48 ms Memory Size: 1998 MB Max Memory Used: 58 MB 這是因為,,對于 php 程序,需要首先啟動 vscode 的調(diào)試器,。
php 類型的函數(shù)啟動 VSCode 調(diào)試器的流程與其他類型的函數(shù)一致:復(fù)制上面日志中的 vscode 配置到 launch.json,,單擊“開始調(diào)試”即可。
然后在終端重新以調(diào)試模式啟動 php 函數(shù)即可開始調(diào)試:
fun local invoke -d 3000 php72
Event 事件源 函數(shù)計算提供了豐富的觸發(fā)器,,包括但不局限于對象存儲觸發(fā)器,、日志服務(wù)觸發(fā)器、CDN 事件觸發(fā)器等,。在本地?zé)o論是運行還是調(diào)試函數(shù)時,,為了能夠完全模擬線上環(huán)境,通常需要構(gòu)造觸發(fā)事件,。
觸發(fā)事件可以是一段可讀的 json 配置,,也可以是一段非可讀的二進(jìn)制數(shù)據(jù)。這里我們拿 json 舉例,,假設(shè)觸發(fā)事件內(nèi)容為:
{ "testKey": "testValue" } 想要將這段事件內(nèi)容傳給函數(shù),,可以通過以下三種途徑:
管道: echo '{"testKey": "testValue"}' | fun local invoke nodejs8 文件: 將的 json 內(nèi)容寫入到文件,文件名隨意,,比如 event.json,。然后通過 -e 指定文件名:fun local invoke -e event.json nodejs8 重定向: fun local invoke nodejs8 < event.json 或者 fun local invoke nodejs8 <<< '{"testKey": "testValue"}' 等等。更多信息可以參考這篇文章,。 環(huán)境變量 在 template.yml 中配置的 EnvironmentVariables 會與線上行為一致,,當(dāng)函數(shù)運行時,可以通過代碼獲取到,。更多信息參考,。
在本地運行函數(shù)時,除了 EnvironmentVariables 配置的環(huán)境變量,,fun 還會額外提供一個 local=true 的環(huán)境變量,,用來標(biāo)識這是一個本地運行的函數(shù)。
通過這個環(huán)境變量,,用戶可以區(qū)分是本地運行還是線上運行,,以便于進(jìn)行一些特定的邏輯處理。
Initializer 在 template.yml 中配置的 Initializer 屬性會與線上行為一致,,當(dāng)函數(shù)運行時,,會首先運行 Initializer 指定的方法。Initializer 更多信息 參考,。
Credentials 用戶可以通過 Credentials 中存儲的 ak 信息訪問阿里云的其他服務(wù),。Fun local 在本地運行函數(shù)時,會按照與 fun deploy 相同的 策略 尋找 ak 信息,。
關(guān)于函數(shù)計算 Credentials 的描述,,可以參考。
以下是一個根據(jù)本地,、線上環(huán)境的不同,,利用函數(shù)提供的 Credentials 配置 oss client 的例子:
local = bool(os.getenv('local', "")) if (local): print 'thank you for running function in local!!!!!!' auth = oss2.Auth(creds.access_key_id, creds.access_key_secret) else: auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token) 附錄
代碼 本文講解涉及到的 demo 代碼,托管在 github 上,。項目目錄結(jié)構(gòu)如下:
. ├── java8 │ ├── pom.xml │ ├── src │ │ └── main │ │ └── java │ │ └── example │ │ └── App.java │ └── target │ └── demo-1.0-SNAPSHOT.jar ├── nodejs6 │ └── index.js ├── nodejs8 │ └── index.js ├── php7.2 │ └── index.php ├── python2.7 │ └── index.py ├── python3 │ └── index.py └── template.yml template.yml 定義了函數(shù)計算模型,,其中定義了一個名為 localdemo 的服務(wù),并在該服務(wù)下,,定義了 6 個函數(shù),,名稱分別是 nodejs6、nodejs8,、php72,、python27、python3,、java8,。它們對應(yīng)的代碼目錄由 template 中的 CodeUri 定義,分別位于 nodejs6,、nodejs8,、php7.2、python2.7、python3,、java8 目錄,。
更多參考 Fun Repo Fun specs Fun examples Fun 發(fā)布 2.0 新版本啦 函數(shù)計算工具鏈新成員 —— Fun Local 發(fā)布啦 來源:http://www./content-4-91901.html
|