Chris Coyier 的 Smashing Podcast 第 22 集:什麼是無服務器?

已發表: 2022-03-10
快速總結↬我們談論的是無服務器架構。 這意味著什麼,它與我們目前構建網站的方式有何不同? Drew McLellan 與 Chris Coyier 交談以找出答案。

今天,我們談論的是無服務器架構。 這意味著什麼,它與我們目前構建網站的方式有何不同? 我與 Chris Coyier 進行了交談以了解情況。

顯示註釋

  • Chris 的微型網站 前端開發人員的無服務器的力量
  • 克里斯在推特上
  • ShopTalk Show 播客

每週更新

  • “設置 Redux 以在實際應用程序中使用”,
    通過傑里納維
  • “你能為五種感官設計一個網站嗎?”
    蘇珊娜·斯卡卡
  • “使用 Sapper 和 Strapi 創建靜態博客,”
    作者 Daniel Madalitso Phiri
  • “React 應用中的產品導覽實用指南”,
    by Blessing Krofegha
  • “如何使用草圖創建保時捷 911,”
    尼古拉·拉扎雷維奇

成績單

克里斯·科耶爾的照片 Drew McLellan:他是一名網頁設計師和開發人員,您可能從 CSS-Tricks 認識他,這是一個他在 10 多年前創建的網站,對於那些構建網站的人來說,這仍然是一個極好的學習資源。 他是 CodePen 的聯合創始人,這是一個基於瀏覽器的編碼遊樂場和社區,被世界各地的前端人員用來分享他們所做的事情並從他們關注的人那裡尋找靈感。 與 Dave Rupert 一起是 ShopTalk Show 的共同主持人,這是一個關於製作網站的播客。 所以我們知道他對 Web 開發了解很多,但你知道他曾經僅靠他的魅力贏得了吃熱狗比賽嗎? 我的好朋友,請歡迎 Chris Coyier。 你好克里斯,你好嗎?

Chris Coyier:嘿,我太棒了。

Drew:我今天想和你討論的不是 CodePen,我也不一定想和你討論 CSS-Tricks,這是我相信每個人都知道出現在 Google 頂部的令人驚嘆的資源之一查找有關任何 Web 開發問題的答案時的搜索結果。 彈出你的臉,你或你的一位來賓貢獻者寫了一篇有用的博客文章。

克里斯:哦,我曾經真的這樣做過。 有一個……我不知道,可能是在谷歌擁有那個奇怪的社交網絡的時候。 那是什麼? 谷歌加?

德魯:哦,另外,是的。

克里斯:是的,他們會將網站與 Plus 帳戶相關聯,所以我的 Plus 帳戶有一個頭像,頭像就是我,所以它會出現在搜索結果中。 我想那些日子已經一去不復返了。 我想如果你…

德魯:我想是的,是的——

克里斯:是的。

Drew:但我有點想和你談談一些你的興趣愛好,那就是無服務器架構的概念。

克里斯:嗯(肯定的)。

德魯:這是你一段時間以來一直在學習的東西。 那正確嗎?

克里斯:是的,是的。 我只是一個粉絲。 這似乎很適合前端開發的發展,我覺得我至少在這方面擁有一些專業知識。 我認為自己在前端比後端更有用得多,而不是我……我這些天都在做。 我已經有足夠長的時間了,所以我不害怕看一點 Ruby 代碼,這是肯定的。 但我更喜歡前端。 我研究了更多。 我在那個級別上參與的項目更多,然後出現了一種新的範式,它說“你可以在服務器上使用你的 JavaScript 技能”,這很有趣。 你懂的? 我就是這麼想的。 它的意義遠不止於此,但這就是我關心的原因,因為我覺得前端開發人員已經對 JavaScript 進行瞭如此深入的研究。 現在我們可以在其他地方使用同樣的技能。 嗯,很酷。

Drew:似乎一個全新的世界已經打開,而如果你只是一個前端編碼員......我說,只是一個前端編碼員,我不應該。 如果您是前端編碼員,並且您習慣於與同事或朋友一起幫助您進行後端實現,那麼突然之間就開放了。 而且您可以自己管理更多的整個堆棧。

克里斯:是的,是的。 而已。

德魯:對著房間裡的大象講話,就在頂部。 我們正在談論無服務器,顯然,命名事物是困難的。 我們都知道。 無服務器架構並不意味著沒有服務器,不是嗎?

克里斯:我認為這是強制性的,例如,如果這是您第一次聽到它的播客,或者在第一次……您只是在前十幾次聽到“無服務器”這個詞時才聽到它,那麼您必須有一種本能的反應並有這種“哦,但仍然有服務器”。 沒關係。 如果您現在正在發生這種情況,請知道,這是其中的必要步驟。 就像生活中的其他任何事情一樣。 理解是有階段的。 第一次聽到,你需要稍微拒絕一下,然後十幾次,或者證明對你有點價值,你才能進入更深的階段這裡的理解。 但是這個詞已經贏了,所以如果你還在反對“無服務器”這個詞,我不想告訴你,火車已經離開了那裡的車站。 這個詞已經成功了。 你不會贏得這個。 非常抱歉。

Chris:但我確實認為有趣的是……它開始變得像,也許有時實際上不涉及服務器。 我認為將無服務器作為一個概念鎖定的事情之一是 AWS Lambda。 他們是現場的第一批人。 lambda 就像你給 AWS 的一個函數,它把它放在神奇的天空中,然後……它有一個 URL,你可以點擊它,它會運行那個函數並返回一些你想要的東西。 你懂的? 那隻是HTTP或其他。 這就是它的工作原理,……當你第一次聽到這個的時候,你會想,“為什麼? 我不在乎。” 但是,有一些顯而易見的事情。 它可以知道其他人無法訪問的我的 API 密鑰。 這就是你開始運行後端的原因,因為它知道不必在客戶端的 JavaScript 中存在的秘密內容。 因此,如果它需要與數據庫通信,它就可以做到。 它可以安全地做到這一點,而無需在其他地方公開 API 密鑰。 甚至這些數據在哪里或如何獲取它,它是……

克里斯:所以這很酷。 我可以編寫一個與數據庫對話的函數,獲取一些數據,然後返回。 涼爽的。 所以,Lambda 就是這樣,但 AWS 可以工作。 你必須選擇一個地區。 你就像,“我不知道。 它應該在哪裡,弗吉尼亞? 俄勒岡? 我應該選擇澳大利亞的嗎? 我不知道。” 他們有 20、30 個。我什至不知道他們現在有多少,但即使是 lambdas 也有區域。 我認為,他們現在有 Lambda@Edge,這意味著它是所有地區,這很酷。 但他們是第一個,現在每個人都有像 Lambda 這樣的東西。 所有的雲服務。 他們想要在這個世界上獲得某種服務。 其中之一是 CloudFlare。 CloudFlare 有工人。 他們擁有比 AWS 更多的位置,但他們執行它的時間也有所不同……就像 CloudFlare 工作人員的方式……它類似於 lambda,因為您可以運行 Node.js。 您可以運行 JavaScript。 你也可以運行許多其他語言,但是……我主要考慮這些東西,最有趣的語言是 JavaScript,只是因為它的流行。

克里斯:它只發生在 CDN 級別,我猜它是服務器,但我傾向於不將 CDN 視為服務器。 不像其他東西那麼明顯。 最近開始感覺更加無服務器。 CDN 是服務器嗎? 我的意思是,我猜它是某處的計算機,但感覺更像是更少的服務器。

Drew:感覺就像,是的,CDN 可能是服務器,但它是服務器的最簡化版本。 如果您願意,它就像一台瘦服務器。

克里斯:是的。 當然。

德魯:好的。 我聽說過……不幸的是,我不記得要歸功於的來源,但我聽說無服務器被描述為“就像使用像 Uber 或 Lyft 這樣的拼車服務”或其他什麼。 你可以無車而不擁有汽車,但這並不意味著你從不使用汽車。

克里斯:是的,這並不意味著汽車不存在。 嗯,不錯。

德魯:你只是在需要的時候召喚一輛,但同時,你不需要支付汽車的前期購買成本。 你不支付維修費或燃料費或-

克里斯:對,定價也很合理,對吧? 那很好。 我認為這是一個很好的類比。 然後,因為它也在 CDN 級別,所以它只是攔截已經發生的 HTTP 請求,這意味著你不問它……你不向它發送請求,它會發回請求。 它只是在請求期間自然發生,這也使它感覺不那麼服務器化。 我不知道,這很有趣。 這肯定很有趣。 不過,這很重要,因為您提出了定價問題。 你只需為你使用的東西付費。 這也很重要,因為……比方說,您是一名後端開發人員,他一生都習慣於運行服務器。 他們計算成本,“我需要這種具有這種內存、這種 CPU 和這種規格的服務器。 這就是它的成本。” 無服務器的出現並削減了該定價。

克里斯:所以,即使你是一個不太喜歡這個的後端開發人員,他們只是不喜歡它,就像你的技能是多年來的樣子,你比較價格你會說,“什麼? 我可以支付我之前支付的 1% 的費用嗎?” 你不能不在乎這個,對吧? 如果你是這個後端開發人員,為他們的服務支付的費用是他們需要支付的費用的一百倍,那麼你的工作就有點糟糕了。 不好意思說。 這種情況已經出現,並且在很多方面都破壞了定價。 你必須關心這一點。 其他人很酷……這並不是說您根本不必擔心安全性,但這不是您的服務器。 您沒有……您的 lambda 或云功能,或者您的工作人員,或其他任何東西,都沒有位於您自己網絡上一些真正敏感數據旁邊的服務器上。 它不在您的數據庫旁邊。

克里斯:如果有人編寫的代碼以某種方式試圖將自己從工人或 lambda 或其他任何東西中彈出,並試圖以他們的方式訪問其他事物,那麼就沒有什麼可取的了。 所以安全性也很重要,所以再次強調,如果這是你作為服務器管理員的工作,那就是處理這件事的安全性。 運行它,在 Lambda 中運行某些東西,你會從中獲得一些自然的安全性,這很棒。 所以,便宜多了。 這樣更安全。 它鼓勵這些小型模塊化架構,這可能是一個好主意。 好主意的多米諾骨牌在這裡似乎是多米諾骨牌。 這就是它引人注目的原因。 你懂的?

Drew:是的,我的意思是,傳統上我們已經在網絡上運行了幾十年的基於服務器的架構,你有一個你自己運行的網絡服務器。 它包含您的前端代碼、後端代碼、數據庫和所有內容。 然後你需要維護它並讓它運行並支付賬單,即使它沒有被使用,它也在那裡計時。 用戶會發出一個請求,它會從數據庫中構建所有 HTML 查詢內容,然後將其全部發送到瀏覽器。 這個過程有效。 這就是大量事物的構建方式。 這可能是構建 Web 的主要方式。 這就是 WordPress 之類的工作方式。 這真的是我們需要解決的問題嗎? 我的意思是,我們已經談到了一些成本。 還有什麼其他問題,我們……我們需要解決,無服務器可能會幫助我們?

克里斯:是的,老派方法的問題。 是的,我不知道,也許沒有。 我的意思是,我並不是說整個網絡需要在一夜之間改變他們的整體……整個事情。 我不知道。 也許它不是真的,但我認為它打開了大門。 看起來,當好的想法像這樣出現時,它們只是慢慢地改變了網絡的運作方式。 所以,如果有一些 CMS 以某種方式構建,期望數據庫在那裡,這意味著未來的主機可能會開始以有趣的方式利用它。 也許你覺得它仍然只是一個傳統的服務器,但是主機本身已經將它、它們的運行方式、到無服務器架構中。 所以你甚至不知道這種情況正在發生,但他們已經找到了一種方法來通過以無服務器方式託管你需要的東西來削減成本。 也許是的,作為開發人員甚至不需要關心,但在元層面上,這就是正在發生的事情。 可能是。 我不知道。

克里斯:這也不意味著……數據庫仍然存在。 如果事實證明在架構上擁有一個關係數據庫是存儲該數據的正確方法,那就太好了。 我提到這一點是因為這個無服務器世界與 JAMstack 是同時成長起來的。 JAMstack 是這樣一種架構,“你應該從靜態主機上為你的網站提供服務,除了……之外什麼都不運行。”它們就像小型 CDN。 他們就像,“我無能為力。 我不運行 PHP。 我不運行 Ruby。 我什麼都不跑。 我在一個很小的 Web 服務器上運行,該服務器僅設計用於提供靜態文件。”

克里斯: “然後,如果你需要做的不止這些,如果你需要從關係數據庫中提取數據,那麼請在其他時間做,而不是在服務器時間。 你可以提前在構建過程中完成,然後將這些東西從數據庫中提取出來,預先構建靜態文件,我會為這些文件提供服務,或者在運行時完成。” 這意味著你得到了一個文檔的外殼,然後它發出一個 JavaScript 請求來獲取一些數據並預填充它。 因此,您可以提前或之後進行,但這並不意味著“不要使用關係數據庫”。 它只是意味著,“不要讓服務器在請求文檔時生成它”,這是一個……我不知道,這有點範式轉變。

克里斯:不僅僅是 JAMstack。 我們也生活在 JavaScript 框架時代。 我們生活在這樣一個時代,人們開始對 JavaScript 應用程序的啟動方式有了更多期望,即它會掛載一些組件,並且隨著這些組件的掛載,它會請求所需的數據。 因此,對於像 React 網站這樣的東西來說,它可能是一種很自然的選擇,“好吧,我只需點擊一個無服務器函數來獲取它需要的數據。 它本質上是一些 JSON API。 我得到了我需要的 JSON 數據,並根據這些數據構建了自己,然後渲染到頁面上。” 現在,無論這對網絡是好是壞,就像,“我不知道。 太糟糕了。 船已經航行了。 這就是很多人建造網站的方式。” 這只是客戶端渲染的東西。 因此,無服務器和現代 JavaScript 是齊頭並進的。

德魯:我想你不必批發……看一種或另一種建築。 中間有一個區域,基礎設施的一部分可能更傳統,而部分可能是無服務器的,我猜?

克里斯:是的。 好吧,無論如何,他們都想告訴你。 任何想把他們建築的任何部分賣給你的人都會說,“你現在不用買了。 就做一點點。” 因為當然,他們希望您將腳趾浸入他們出售的任何東西中,因為一旦您將腳趾浸入水中,您將自己濺入游泳池的機會就會高得多。 所以,我認為……這不是謊言,雖然,必然,雖然我發現運氣不太好……我不希望我的籌碼成為一切的一點點。 我認為那裡有一些我並不總是想吞下的技術死亡。

德魯:嗯(肯定)。

克里斯:但有可能做到。 我認為引用最多的一個是……假設我有一個包含電子商務元素的網站,這意味著……假設大規模電子商務,所以 10,000 種產品或其他東西,這個 JAMstack 架構還沒有達到靜態重建它總是特別有效。 所以,想法是,“那就不要”。 讓那部分自然水合物......點擊無服務器功能並獲取它需要的數據,然後做所有這些。 但是網站的其餘部分,不是……沒有那麼多頁面,沒有那麼多數據,你可以預渲染或其他什麼。 所以兩者都有一點。

Drew:當然,很多人都在處理遺留系統……一些建於 2000 年代的舊數據庫東西,他們可能能夠在上面粘貼某種 JSON API 層……

克里斯:是的。

Drew: ……並構建更現代的東西,也許是無服務器的,然後仍然通過以一種奇怪的方式將它們完全粘合起來與這些遺留系統交互。

克里斯:是的。 不過我喜歡這樣,不是嗎? 不是……大多數網站已經存在。 我們中有多少人是完全綠色的網站? 我們大多數人都在處理一些已經存在但出於某種原因需要被拖到未來的垃圾,因為我不知道,開發人員想要更快地工作,或者你不能再僱用 COBOL 中的任何人,或者其他任何故事是。 你懂的?

Drew:從術語上講,我們談論的是 JAMstack,這是一種在瀏覽器中運行代碼的方法,從 CDN 提供服務。 因此,服務器上沒有任何動態。 然後當我們談論無服務器時,我們談論的是在其他地方的服務器上運行的那些小功能。 那正確嗎? 我們正在談論這些雲功能——

克里斯:是的,我的意思是,它們現在恰好是兩種熱門想法。 因此,談論一個並談論另一個很容易。 但他們不一定需要在一起。 您可以運行一個與無服務器無關的 JAMstack 站點。 您只是在這樣做,您只需預先構建站點並運行它,您就可以使用無服務器而無需關心 JAMstack。 事實上,CodePen 根本不做 JAMstack。 並不是說我們一定要談論 CodePen,但它是一個 Ruby on Rails 應用程序。 它在一大堆 AWS EC2 實例和各種其他架構上運行以實現它。 但是我們盡可能使用無服務器的東西,因為它便宜又安全,而且是一種很好的工作方式。 因此,根本沒有使用 JAMstack,但到處都是無服務器的。

德魯:這很有趣。 您在 CodePen 上放置了哪些無服務器任務?

克里斯:嗯,有很多東西。 其中之一是,我認為,希望相當明顯的是,我需要...... CodePen 的重點是你在瀏覽器中編寫每個 HTML、CSS 和 JavaScript,它會呈現在你面前,對嗎? 但是您也可以選擇預處理器語言。 假設你喜歡 Sass。 您在 CSS 中打開 Sass,然後編寫 Sass。 好吧,有些東西必須處理 Sass。 這些天來,Sass 是用 Dart 或其他東西編寫的。

克里斯:理論上,你可以在客戶端中做到這一點。 但是這些進行預處理的庫非常大。 我不認為我想把整個 Sass 庫發給你,只是為了運行那個東西。 我不想......它只是不是,這必然不是正確的架構。 也許它在路上,我的意思是,我們可以談論離線廢話,yada,yada,Web Workers。 我們可以做一百萬種建築方面的事情。 但這就是它現在的工作方式,是否有 lambda。 它處理 Sass。 它有一個微小的、微小的、微小的、微小的工作。

Chris:你把這個 Sass 的 blob 發給它,它把東西發回給你,這是經過處理的 CSS,可能是一個站點地圖,等等。 它有一個很小的工作,我們可能會為那個 lambda 支付,比如 4 美分或其他東西。 因為 lambdas 非常便宜,你也可以錘擊它。 您不必擔心規模。 您只需隨心所欲地打那個東西,您的賬單就會便宜得驚人。 有些時候,無服務器開始越過過於昂貴的界限。 我不知道那是什麼,我不是那種東西的大師。 但一般來說,我們所做的任何無服務器的東西,我們基本上……幾乎都算免費的,因為它很便宜。 但是 Sass 有一個。 有一個少。 有一個給巴貝爾的。 TypeScript 有一個。 有一個用於……所有這些都是我們運行的單個 lambda。 這是一些代碼,把它交給 lambda,它會回來,然後我們就可以用它做任何事情。 但我們使用它的用途遠不止於此,即使是最近。

克里斯:這是一個例子。 CodePen 上的每一支 Pen 都有一個屏幕截圖。 這有點酷,對吧? 因此,人們製作了一個東西,然後我們需要一個 PNG 或 JPEG 或類似的東西,這樣我們就可以……這樣,當你發推文時,你會得到它的小預覽。 如果你在 Slack 中分享它,你會得到它的小預覽。 我們在網站本身上使用它來渲染……而不是 iframe,如果我們可以檢測到 Pen 沒有動畫,因為 iframe 的圖像要輕得多,那麼為什麼不使用圖像呢? 反正也不是動畫。 只是這樣的性能提升。 因此,顯然,這些屏幕截圖中的每一個都有一個 URL。 我們已經對其進行了架構,以便該 URL 實際上是一個無服務器功能。 是一名工人。 因此,如果該 URL 被點擊,我們可以非常快速地檢查我們是否已經截取了該屏幕截圖。

Chris:這實際上是由 CloudFlare Workers 啟用的,因為 CloudFlare Workers 不僅僅是一個無服務器功能,而且它們也有一個數據存儲。 他們有一個叫做鍵值存儲的東西,所以它的 ID,我們可以快速檢查,它會是,“真假,你有沒有?” 如果它得到它,它會為它服務。 它通過 CloudFlare 提供服務,一開始就超級快。 然後也給你所有這些能力。 因為它是一個圖像 CDN,你可以說,“好吧,以最佳格式提供它。 把它當作這些維度來服務。” 我不必製作這些尺寸的圖像。 您只需將尺寸放在 URL 中,它就會神奇地返回該尺寸。 所以這真的很好。 如果沒有它,它會要求另一個無服務器功能使其變得非常快。 所以它會成功,然後把它放在某個桶裡……因為你必須有圖像的來源,對嗎? 您通常必須將其實際託管在某個地方。 因此,我們很快將其放入 S3 存儲桶中,然後提供服務。

克里斯:所以沒有排隊服務器,什麼都沒有。 就像無服務器功能管理這些圖像的創建、存儲和服務一樣。 大約有 5000 萬或 8000 萬個。 它很多,因此它可以很好地處理規模。 我們只是不碰它。 它只是發生。 這一切都發生得非常快。 超好。

Drew:我猜是這樣……好吧,無服務器功能非常適合需要很少了解事物狀態的任務。 我的意思是,您提到了 CloudFlare 存儲鍵值對的能力,以查看您是否已經緩存了某些內容。

克里斯:是的。 不過,這就是他們試圖解決的問題。 那些鍵值對是……我認為傳統上是正確的。 他們就像,“避免事物中的狀態”,因為你不能指望它。 CloudFlare Workers 就像,“是的,實際上,你可以在某種程度上處理狀態。” 它不像……我不知道,它是鍵值,所以它是值中的鍵。 它不像一個嵌套的、關係性的花哨的東西。 所以可能有一些限制。 但這是嬰兒的日子。 我認為這些東西會變得更強大,所以你確實有能力做一些類似狀態的東西。

Drew:有時限制,那種維持狀態的有限能力,或者你沒有......你根本不想保持任何狀態的事實,有點推動你進入一個給你這種......好吧,當我們談論“小塊鬆散連接”的軟件理念,不是嗎?

克里斯:嗯(肯定的)。

德魯:每個小組件都做一件事並且做得很好。 並且並不真正了解它周圍的其他生態系統。 似乎這確實適用於無服務器功能的概念。 你同意嗎?

克里斯:是的。 我認為無論這是否是一個好主意,您都可以進行哲學辯論。 你懂的? 我認為有些人喜歡單體應用。 我認為有可能……有辦法過度這樣做,並製造太多難以完全測試的小部件。 很高興有這樣的測試,“哦,我想知道我的 Sass 函數是否正常工作。 好吧,讓我們為它寫一個小測試,並確保它是。” 但是讓我們說,對用戶來說重要的是其中的七個字符串。 你如何一起測試所有七個? 我覺得這個故事有點複雜。 我不知道如何以超級智能的方式與所有這些東西交談,但我知道這不一定是這樣,如果你使用所有無服務器功能,那麼它會自動成為比任何其他架構更好的架構。 我喜歡。 這對我來說很有道理,但我不知道這是所有架構的最終目的。 你懂的?

Drew:對我來說,它感覺非常像網絡,因為……這正是 HTML 的工作原理,不是嗎? 您提供一些 HTML,然後瀏覽器將去獲取您的圖像並獲取您的 JavaScript 並獲取您的 CSS。 這似乎是它的擴展——

克里斯:很好。

德魯: ……有點想法。 但是,我們對網絡了解的一件事是,它被設計為具有彈性,因為網絡很脆弱。

克里斯:嗯(肯定的)。

Drew:這種無服務器方法有多強大? 如果有什麼……如果其中一個小碎片消失了,會發生什麼?

克里斯:那會很糟糕。 你懂的? 這將是一場災難。 我猜你的網站會像任何其他服務器一樣宕機,如果它碰巧宕機了。

德魯:有沒有辦法減輕這種情況,特別是——

克里斯:我不知道。

德魯: ……適合這種方法,你遇到過嗎?

克里斯:也許吧。 我的意思是,就像我說的,一個真正超級花哨的健壯的東西可能是……假設您訪問 CodePen,假設有一個 Sass 的 JavaScript 實現,我們注意到您在一個相當快的網絡上並且您處於空閒狀態現在。 也許我們會去拿那個 JavaScript,然後把它扔給一個服務工作者。 然後,如果我們檢測到 lambda 失敗,或者其他什麼,或者您已經安裝了這個東西,那麼我們將使用 service worker 而不是 lambda,並且 service worker 能夠離線工作。 所以,這也不錯。 那很有意思。 我的意思是,它們是同一種語言。 服務工作者是 JavaScript,很多雲函數都是 JavaScript,所以有一些......我認為這是一種可能性,雖然......只是,這是一些嚴肅的技術......它只是讓我害怕擁有你交付的這段 JavaScript對於成千上萬的用戶,您不一定知道他們擁有什麼,以及他們擁有什麼版本。 Eww,但這只是我自己的恐懼。 我敢肯定,有些人在這類事情上做得很好。

克里斯:我其實不知道。 也許你知道一些我不知道的關於無服務器彈性的策略。

Drew:我猜有一種失敗模式,一種失敗風格,這可能發生在無服務器函數中,你運行一個函數一次失敗,然後你可以立即再次運行它,它會成功,因為它可能會命中完全不同的服務器。 或者無論問題是什麼,當第二個請求可能不存在該運行時。 整個主機停機的問題是一回事,但也許有……你的機器有個別問題。 你有一個特定的服務器,它的內存已經壞了,它拋出了大量的錯誤,當你第一次點擊它時,它就會失敗。 第二次,這個問題可能已經根深蒂固。

克里斯:傾向於提供這種技術的公司,你必須信任他們,但他們也恰好是那種公司……這是他們的驕傲。 這就是人們使用它們的原因是因為它們是可靠的。 我敢肯定,人們可能會指出過去的一些 AWS 中斷,但它們往往有點少見,而且不是很常見。 如果您是在託管自己的垃圾,我敢打賭,他們會讓您從 SLA 百分比的水平上被擊敗。 你懂的? 所以這並不是說“不要以一種有彈性的方式建設”,但通常提供這些東西的公司類型非常可靠。 你因為搞砸了那個功能而失敗的機會比因為他們的架構失敗而失敗的機會要高得多。

Drew:我想,我的意思是,就像任何你使用 API 或可能失敗的東西一樣,只是確保你構建你的代碼以應對這種失敗模式,並知道接下來會發生什麼,而不是僅僅拋出給用戶一個錯誤,或者只是快死了,或者你有什麼。 它意識到這一點並要求用戶再試一次。 或者自己再試一次,或者別的什麼。

克里斯:是的,我喜歡嘗試不止一次的想法,而不僅僅是“哦,不。 失敗。 中止。” “我不知道,你為什麼不在那裡再試一次,伙計?”

Drew:所以我的意思是,當涉及到無服務器功能的測試和開發時,比如雲功能,可以在本地完成嗎? 必須在雲端完成嗎? 有辦法管理嗎?

克里斯:我認為有一些方法。 不知道這個故事是不是很精彩。 它仍然是一個相對較新的概念,所以我認為它會變得越來越好。 但據我所知,一方面,您正在編寫一個相當普通的 Node 函數。 假設您使用 JavaScript 來執行此操作,並且我知道特別是在 Lambda 上,它們支持各種東西。 您可以編寫一個有趣的 PHP 雲函數。 您可以編寫一個 Ruby 雲函數。 所以,我知道我是在專門談論 JavaScript,因為我有一種感覺,這些東西大部分都是 JavaScript。 我的意思是,無論它是什麼語言,您都可以在本地轉到命令行並執行該操作。 其中一些測試是……您只需像測試任何其他代碼一樣測試它。 您只需在本地調用該函數並查看它是否有效。

Chris:當您談論對它的 HTTP 請求時,情況就有些不同了,這就是您要測試的東西。 它是否正確響應請求? 它是否正確返回了這些東西? 我不知道。 網絡可能會參與其中。 因此,您可能希望在該級別編寫測試。 沒關係。 我不知道。 那裡的正常故事是什麼? 您啟動某種本地服務器或為其提供服務的東西。 使用郵遞員,我不知道。 但是有……框架也試圖提供幫助。 我知道無服務器“.com”非常令人困惑,但實際上有一家名為 Serverless 的公司,他們為編寫無服務器功能創建了一個框架來幫助您部署它們。

Chris:所以如果你喜歡 NPM install serverless,你會得到他們的框架。 它被廣泛認為非常好,因為它非常有幫助,但他們沒有自己的雲或其他任何東西。 你編寫這些,然後它可以幫助你把它們變成一個真正的 lambda。 或者它可能與多個雲提供商一起使用。 這些天我什至不知道,但他們存在的目的是使部署故事更容易。 我不知道是什麼…… AWS 並不以簡單而聞名。 你懂的? 有很多工具可以幫助您使用 AWS,它們就是其中之一。

克里斯:他們有某種付費產品。 我什至不知道它到底是什麼。 我認為他們所做的其中一件事是……使用它們的目的是為了測試,是為了擁有一個用於測試無服務器功能的開發環境。

德魯:是的,因為我猜這是工作流程中相當大的一部分,不是嗎? 如果您已經編寫了 JavaScript 函數,並且已經在本地對其進行了測試,那麼您就知道它會完成這項工作。 您如何實際選擇它將進入哪個提供商以及如何將其用於該服務? 現在,我的意思是,那是一個雷區,不是嗎?

克里斯:是的。 I mean, if you want to use no tooling at all, I think they have a really… like AWS, specifically, has a really rudimentary GUI for the thing. You can paste the code in there and hit save and be like, “Okay, I guess it's live now.” That's not the best dev story, but I think you could do it that way. I know CloudFlare workers have this thing called Wrangler that you install locally. You spin it up and it spins up a fake browser on the top and then dev tools below. Then you can visit the URL and it somehow intercepts that and runs your local cloud function against it. Because one of the interesting things about workers is… you know how I described how it… you don't hit a URL and then it returns stuff. It just automatically runs when you… when it intercepts the URL, like CDN style.

Chris: So, one of the things it can do is manipulate the HTML on the way through. The worker, it has access to the complete HTML document. They have a jQuery-esque thing that's like, “Look for this selector. Get the content from it. Replace it with this content. And then continue the request.” So you can mess with code on the way through it. To test that locally, you're using their little Wrangler tool thing to do that. Also, I think the way we did it was… it's also a little dangerous. The second you put it live, it's affecting all your web traffic. 這是一件大事。 You don't want to screw up a worker. 你懂的? You can spin up a dev worker that's at a fake subdomain, and because it's CloudFlare, you can… CloudFlare can just make a subdomain anyway. 我不知道。 It's just kind of a nice way to do a… as you're only affecting sub-domain traffic, not your main traffic yet. But the subdomain's just a mirror of a production anyway, so that's kind of a… that's a testing story there.

Chris: It brings up an interesting thing, though, to me. It's like… imagine you have two websites. One of them is… for us it's like a Ruby on Rails app. 任何。 這是一回事。 But we don't have a CMS for that. That's just like… it's not a CMS, really. I think there's probably Ruby CMSs, but there's not any renowned ones. 你懂的? It seems like all the good CMSs are PHP, for some reason. So, you want a quality CMS. Drew, you've lived in the CMS market for a long time -

Drew: Absolutely.

Chris: … so you know how this goes. Let's say you want to manage your sites in Perch or whatever, because it's a good CMS and that's the proper thing to use to build the kind of pages you want to build. But you don't want to run them on the same server. Unless you want to manage the pages on one site, but show them on another site. Well, I don't know, there's any number of ways to do that. But one JavaScript way could be, “Okay, load the page. There's an empty div there. Run some JavaScript. Ask the other site for the content of that page and then plunk it out on the new page.” That's fine, I guess, but now you're in a client side rendered page. It's going to be slow. It's going to have bad SEO, because… Google will see it eventually, but it takes 10 days or something. It's just a bad story for SEO. It's not very resilient, because who knows what's going to happen in the network. It's not the greatest way to do this kind of “content elsewhere, content on site B, show page of site A”, situation.

Chris: You could also do it on the server side, though. Let's say you had… Ruby is capable of granting a network request too, but that's even scarier because then if something fails on the network, the whole page could die or something. It's like a nervous thing. I don't love doing that either. But we did this just recently with a worker, in that we… because the worker's JavaScript, it can make a fetch request. So, it fetches site A, it finds this div on the page, and then it goes and asks site B for the content. Gets the content. Plugs it into that div, and serves the page before it gets anything. So it looks like a server rendered page, but it wasn't. It all happened at the… on the edge, at the worker level, at the serverless level.

Chris: So it's kind of cool. I think you can imagine a fetch request on the browser probably takes, I don't know, a second and a half or something. It probably takes a minute to do it. But because these are… site B is hosted on some nice hosting and Cloudflare has some… who knows what kind of super computers they use to do it. 他們是這樣。 Those are just two servers talking to each other, and that fetch request happens just so super duper, duper fast. It's not limited to the internet connection speed of the user, so that little request takes like two milliseconds to get that data. So it's kind of this cool way to stitch together a site from multiple sources and have it feel like, and behave like, a server rendered page. I think there's a cool future to that.

Drew: Are there any sort of conventions that are sort of springing up around serverless stuff. I'm sort of thinking about how to architect things. Say I've got something where I want to do two sort of requests to different APIs. I want to take in a postal address and geocode it against one, and then take those coordinates and send that to a florist who's going to flower bomb my front yard or something. How would you build that? Would you do two separate things? Or would you turn that into one function and just make the request once from the browser?

Chris: Mm (affirmative). That's a fascinating question. I'd probably have an architect function or something. One function would be the one that's in charge of orchestrating the rest of them. It doesn't have to be, your website is the hub and it only communicates to this array of single sources. Serverless functions can talk to other serverless functions. So I think that's somewhat common to have kind of an orchestrator function that makes the different calls and stitches them together, and returns them as one. I think that is probably smart and faster, because you want servers talking to servers, not the client talking to a whole bunch of servers. If it can make one request and get everything that it needs, I think that's probably generally a good idea-

Drew: Yeah, that sounds smart. 是的。

Chris: But I think that's the ultimate thing. You get a bunch of server nerds talking, they'll talk about the different approaches to that exact idea in 10 different ways.

德魯:是的。 No, that sounds pretty smart. I mean, you mentioned as well that this approach is ideal if you're using APIs where you've got secret information. You've got API keys or something that you don't want to live in the client. Because I don't know, maybe this florist API charges you $100 dollars every time flower bomb someone.

Chris: Easily.

Drew: You can basically use those functions to almost proxy the request and add in the secret information as it goes, and keep it secret. That's a viable way to work?

Chris: Yeah, yeah. 我想是這樣。 I mean, secrets are, I don't know, they're interesting. They're a form of buy in I think to whatever provider you go with, because… I think largely because of source control. It's kind of like, you could just put your API key right in the serverless function, because it's just going to a server, right? You don't even have to abstract it, really. The client will never see that code that executes, but in order for it to get there, there's probably a source control along the way. It's probably like you commit to master, and then master… then some kind of deployment happens that makes that thing go to the serverless function. Then you can't put your API key in there, because then it's in the repo, and you don't put your API keys in repos. 這是個好建議。 Now there's stuff. We've just done… at CodePen recently, we started using this git-crypt thing, which is an interesting way to put keys safely into your repos, because it's encrypted by the time anybody's looking at that file.

Chris: But only locally they're decrypted, so they're useful. So it's just kind of an interesting idea. I don't know if that helps in this case, but usually, cloud providers of these things have a web interface that's, “Put your API keys here, and we'll make them available at runtime of that function.” Then it kind of locks… it doesn't lock you in forever but it kind of is… it's not as easy to move, because all your keys are… you put in some input field and some admin interface somewhere.

Drew: Yeah, I think that's the way that Netlify manage it.

Chris: They all do, you know?

德魯:是的。 You have the secret environment variables that you can set from the web interface. That seems to work quite nicely.

Chris: Yeah, right. But then you got to leave… I don't know, it's not that big of a deal. I'm not saying they're doing anything nefarious or anything. How do you deal with those secrets? Well, it's a hard problem. So they kind of booted it to, I don't know, “Just put them in this input field and we'll take care of it for you, don't worry about it.”

Drew: Is there anything that you've seen that stands out as an obvious case for things that you can do with serverless, that you just couldn't do with a traditional kind of serverfull approach? Or is it just taking that code and sort of almost deploying it in a different way?

Chris: It's probably mostly that. I don't know that it unlocks any possibility that you just absolutely couldn't run it any other way. Yeah, I think that's a fair answer, but it does kind of commoditize it in an interesting way. Like, if somebody writes a really nice serverless function… I don't know that this exists quite yet, but there could kind of a marketplace, almost, for these functions. Like, I want a really good serverless function that can take a screenshot. That could be an open source project that lots of eyeballs around, that does a tremendously good job of doing it and solves all these weird edge cases. That's the one I want to use. I think that's kind of cool. 你懂的? That you can kind of benefit from other people's experience in that way. I think that will happen more and more.

Drew: I guess it's the benefit that we talked about, right at the top, of enabling people who write JavaScript and may have written JavaScript only for the front-end, to expand and use those skills on the back-end as well.

克里斯:是的,是的。 我想是的,我認為那是……因為有些時候……您不必非常熟練地知道什麼是合適的,什麼不適合網站。 就像,前一周我做了一個小教程,有這個故障的地方使用這些......當你保存一個故障時,他們會給你一個你建造的東西的蛞蝓,那就是,“威士忌,探戈,狐步舞。 1000 個。” 這就像一個聰明的小東西。 它獨特的機會非常高,因為我認為他們甚至會在其上附加一個數字或其他東西。 但它們最終變成了這些有趣的小東西。 他們開源了包含所有這些單詞的庫,但它就像一百、數千個單詞。 文件很大。 你懂的? 它只是一個單詞字典的兆字節大。 您可能在開發的第一年就學會了“不要發布一個字典大小為 MB 的 JavaScript 文件”。 這不是一件好事。 你懂的? 但是 Node 不在乎。 您可以運送數百個。 它與服務器上的速度無關。

德魯:是的。

克里斯:在服務器上沒關係。 所以,我可能會說,“嗯,好吧,那我就用 Node 來做吧。” 我將有一個聲明說,“單詞相等需要單詞”或其他任何內容,並在頂部添加一個註釋,“讓它隨機化一個數字。 將其從陣列中拉出並歸還。” 因此,無服務器功能是八行代碼,帶有一個打包的@JSON,可以引入這個開源庫。 然後是我的前端代碼,有一個無服務器函數的 URL。 它點擊了那個 URL。 URL 返回一個單詞或一組單詞或其他任何內容。 你為它構建了自己的小 API。 而現在,我有一個非常好的、高效的東西。 這樣做的好處是,它是如此簡單。 我不擔心它的安全性。 我不……你知道嗎?

Chris:這只是……我認為,一個非常普通或初學者的 JavaScript 開發人員可以做到這一點,這很酷。 這是他們以前沒有的使能的東西。 之前,他們會說,“嗯,這是一個 2MB 的單詞數組。” “哦,我不能把那個寄給客戶。” “哦,那你就關機吧。” 你可能會碰到這堵牆,就像,“那時我不能做那部分。 我需要請其他人幫助我,或者乾脆不做,或者選擇更無聊的蛞蝓或其他一些……”只是,你必須走其他對你來說是一堵牆的路,因為你做不到。 而現在,你會說,“哦,好吧,我就……”我不會把它放在我的腳本斜杠或我的源斜杠腳本文件夾中,而是把它放在我的函數文件夾中。

克里斯:你有點像將腳本從一個文件夾移到另一個文件夾。 而那個恰好被部署為無服務器功能。 多麼酷啊? 你懂的? 你幾乎使用了相同的技能。 它仍然有一些粗糙的邊緣,但它非常接近。

德魯:太酷了。 你已經建立了一個關於這些想法的小型微型網站,不是嗎?

克里斯:是的。 我參加比賽有點早。 不過,我今天只是在處理它,因為……它會收到拉取請求。 這個想法......嗯,它在 serverless.css-tricks.com 並且......順便說一句,CSS-Tricks 中有一個破折號。 所以它是 CSS-Tricks 的一個子域,我也無服務器地構建了它,所以這是…… CSS-Tricks 就像一個 WordPress 站點,但這是一個靜態站點生成器站點。 它的所有內容都在開源的 GitHub 存儲庫中。 所以如果你想改變網站的內容,你可以提交一個投票請求,這很好,因為隨著時間的推移已經有一百個左右。 但我構建了所有原始內容。

Drew:這是一個非常有用的地方,因為它列出了......

克里斯:就是這樣,幾乎就是技術列表。 是的。

德魯:這很好,因為否則,你只是在谷歌上搜索,你不知道你在尋找什麼。 是的,它是幫助你做這些事情的 API 提供者的列表。

克里斯: Forms 就是其中的一個例子,因為……所以當你選擇……假設你要去 JAMstack,我知道這不一定是重點,但你會看到它們是如何攜手並進的. 突然之間,您沒有 PHP 文件或任何可以用來處理該表單的文件。 你如何在 JAMstack 網站上做表格? 好吧,有很多方法可以做到這一點。 顯然,每個人和他們的姐姐都想幫助你解決這個問題。 所以我想如果我是 JAMstack 這個詞的發明者,那麼他們自然會嘗試幫助你,但你不必使用它們。

克里斯:事實上,我很驚訝把這個網站放在一起。 讓我們來看看。 現在有六、九、十二、十五、十八、二十一、二十二個服務,它們希望幫助您立即在此站點上無服務器地處理您的表單。 如果你想成為第 23 名,歡迎你,但你有一些競爭。 所以這背後的想法是你用 HTML 編寫一個表單,就像字面上的表單元素一樣。 然後是表單的action屬性,它內部不能指向任何地方,因為沒有什麼可以指向的。 你不能處理,所以它指向外部。 它指向他們想要你指向的任何東西。 他們將處理表單,然後他們傾向於做您希望他們做的事情,例如發送電子郵件通知。 或者發送一個 Slack 的東西。 或者然後將其發送到 Zapier,然後 Zapier 會將其發送到其他地方。 他們都有略微不同的功能集、定價和東西,但他們都在努力為你解決這個問題,比如,“你不想處理自己的表單嗎? 沒問題。 我們會為您處理。”

德魯:是的,這是一個超級有用的資源。 我真的建議大家去看看。 它是 serverless.css-tricks.com。 所以,我一直在學習關於無服務器的一切。 克里斯,你最近在學習什麼?

克里斯:嗯,我仍然非常喜歡這個世界,並且正在學習無服務器的東西。 我有個主意……我很久以前玩過這個在線角色扮演遊戲。 我最近才發現它還活著。 這是一款基於文本的中世紀奇幻遊戲。 我在 AOL 成立的時候玩過它,因為 AOL 想要這些遊戲,你必須登錄才能玩,因為他們希望你在 AOL 上花費數小時和數小時,這樣他們就可以向你發送巨額賬單,這是,我敢肯定,為什麼他們在某些時候做得這麼好。

德魯:所以按秒計費。 是的。

克里斯:是的。 所以遊戲對他們來說很重要。 如果他們能讓你在那里和其他人一起玩遊戲。 所以這款遊戲有點……它並沒有在那里首次亮相,但它轉移到了 AOL,因為我確信他們得到了一個多汁的交易,但它是如此……我的意思是,它只是,不可能更書呆子了。 你是一個矮人法師,你會從你的皮鞘中得到符文法杖。 你可以像終端一樣在其中輸入命令。 然後遊戲會回應你。 我玩那個遊戲很長時間了。 我非常喜歡它。 我進入了它的社區和它的精神。 這有點……就像我一個人在我的電腦前,但我回顧我生命中的那段時光,就像,“那是我生命中美好的時光。” 我真的……我只是喜歡這裡的人和遊戲等等。 但後來我長大了,不再玩它了,因為生活發生在你身上。

克里斯:我最近才知道,因為有人又開始做播客了……我不知道我是怎麼知道的,但我就是這麼做的。 我當時想,“這個遊戲在當今世界還很活躍,你在開玩笑嗎? 這個基於文本的東西。” 而且我非常高興能夠重新激活並讓我的舊角色回歸併播放它。 但只是發現他們為這個遊戲下載的客戶端根本沒有發展。 他們很糟糕。 他們幾乎假定您使用的是 Windows。 只有這些非常俗氣的糟糕渲染......而且它是基於文本的,你認為它至少有很好的排版。 不,所以我想,“我可以參與其中。 我可以為這個遊戲寫一個客戶端。 把漂亮的字體放進去。” 只是把它現代化,我認為遊戲的玩家會喜歡它,但它讓我感到不知所措。 “我該怎麼做?” 但是我發現了一些開源項目。 其中之一就像……你可以通過一個實際的終端窗口玩遊戲,它使用一些開源庫從終端窗口中製作一個 GUI。

德魯:真的嗎?

克里斯:我不知道。 所以這有點酷。 我當時想,“如果他們寫了那個,那裡面肯定有代碼來說明如何連接到遊戲並讓一切順利進行之類的。 所以至少我有一些入門代碼。” 我試圖使用這個應用程序,“也許我會用 Flutter 或其他什麼東西來做”,所以最終的產品應用程序可以在手機上運行,“我真的可以讓這個東西現代化。” 但後來我不知所措。 我當時想,“啊,這太大了……我不能。 我很忙。” 但我找到了另一個有同樣想法的人,他們的想法更進一步,所以我可以在設計層面做出貢獻。 工作真的很有趣,但我也學到了很多東西,因為我很少參與一個別人喜歡的項目,我只是貢獻了一點點,這完全不同比我曾經選擇的技術選擇。

克里斯:這是一個電子應用程序。 他們選擇了那個,這也是一種很酷的方式,因為這是我的網絡技能……所以我沒有學任何太奇怪的東西,而且它是跨平台的,這很棒。 所以,我一直在學習很多關於 Electron 的知識。 我認為這很有趣。

德魯:這很有趣。 令人驚訝的是,我們為了好玩而做的一些小項目和事情,最終成為我們有時學習最多的地方。 並學習可以反饋到我們日常工作中的技能。

克里斯:這是我學習東西的唯一途徑。 我被捲入了一些……我當時想,“他們不是……”它是用一個名為 Mithril 的 JavaScript 庫呈現的,它是……我不知道你是否聽說過它,但這很奇怪。 不是……這幾乎就像在沒有 JSX 的情況下編寫 React。 你必須“創造元素”並完成所有這些……但它應該比它更好地進行基準測試……這實際上很重要,因為在這個基於文本的遊戲中,文本只是在飛行。 有很多數據操作,就像……你會認為這個基於文本的遊戲對於瀏覽器窗口來說非常容易運行,但實際上並非如此。 發生瞭如此多的數據操作,你真的必須真的……我們必須認真對待渲染的速度。 你懂的?

德魯:這很迷人——

克里斯:很酷。

德魯:是的。 親愛的聽眾,如果您想從 Chris 那裡聽到更多信息,您可以在 Twitter 上找到他,他是 @chriscoyier。 當然,CSS-Tricks 可以在 css-tricks.com 和 CodePen 在 codepen.io 上找到。 但最重要的是,如果您還沒有訂閱 ShopTalk Show 播客,我建議您在 shoptalkshow.com 上訂閱。 感謝您今天加入我們,克里斯。 你有什麼離別詞嗎?

克里斯: Smashingpodcast.com。 我希望這是真正的網址。