黃文俊:Serverless小程序后端技術分享

歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~

黃文俊,現任騰訊云SCF無服務器云函數高級產品經理,多年企業級系統開發和架構工作經驗,對企業級存儲、容器平臺、微服務架構、無服務器計算等領域均有涉獵。

clipboard.png

今天講的是怎么使用Serverless做后端技術分享。我的職業偏向是后端,可能不是寫前端,不是使用Node.js,更多是使用CR做后端語言,今天關注的微信小程序,我這一塊的分享更多是怎么實現它的后端。我所使用的是Serverless技術,也是在近兩年新出來的一種架構。講Serverless這個架構之前,我也給大家講一下小程序和傳統的后臺技術。

clipboard.png

小程序的后臺技術

小程序,是一種全新的連接用戶與服務的方式,它可以在微信內被便捷地獲取和傳播,同時具有出色的使用體驗。它的加載方式比傳統的APP方式更快速上線,體驗也不差,除了它本身的界面展示和刷新之外,小程序里面的數據獲取通過微信和后端進行交互,小程序的運行實際上是一個類前端的運行方式,整個運行是在微信內,它和后端的交互實際上通過微信進行轉發的,運行起來之后,它會提出一個api的請求,這個請求首先給到微信,微信再通過網絡apr轉到你自己的服務器上,服務器拿到這個請求以后進行數據的處理,然后再響應到前端,這就是小程序和后臺交互的一種架構。

clipboard.png

對于后端服務,這張圖是大家傳統做的方式,暴露api,這些都可以用來開發業務應用,業務應用之后需要有相應的存儲文件,結構化的數據存儲,或者是非結構化的數據存儲,需要有數據庫和緩存,為了實現這一套架構且不會由于某一塊的服務器宕掉,或者有一些漏洞等等,我們通常的實現是一個較為復雜的過程。比如說,我們為了保證的Serverless和服務器不會垮掉,需要建立一個集群,我們要對外提供服務,需要LB的請求,請求到之后分到某一臺服務器上。比如說文件存儲,如果單純只用一臺設備,這臺設備掛了,整個文件服務就掛了,所以我們要使用分布式存儲來解決文件存儲的問題。數據庫和緩存也是一樣的,需要構建集群,無論是兩臺還是三臺還是多臺,構建集群以后能確保不會由于某一個單點的問題導致整個服務不可用,從而導致服務癱瘓。

clipboard.png

clipboard.png

如果作為一個小程序開發者,這套架構在互聯網公司已經搭建了,作為個人來說這一道太重了,需要了解這里面的某一塊和它的配置,比如說數據庫的集群怎么配?讓大家沒法把精力集中到你的業務和小程序本身,而是過多耗在運維和支撐上。

Serverless架構

clipboard.png

我下面要介紹的Serverless架構,采用無服務器的方式,主要會介紹無服務器和云怎么結合,怎么利用云的服務減輕架構化的工作。介紹它的架構之前,我介紹一下Serverless架構,英文稱之為Serverless,中文稱之為無服務器,大家不用購買服務器,不用購買虛擬機或者物理機,這一塊怎么運行呢?它使用計算托管的方式,在Serverless這里,我們可以看成兩塊,第一塊就是函數即服務,它真正實現了你業務的托管計算。另外一種是后端即服務,包括對象存儲,大家不用自己構建分布式存儲,不用擔心數據的丟失和安全性問題;同時在云上提供的數據庫,消息隊列和對象存儲都是一樣的,不用購買服務器自己搭建,在購買使用的過程當中我們可以稱之為Serverless。因為這些都是托管型的,使用的時候不用關心它的安全性,不用關心可能服務器宕機導致的故障。

clipboard.png

Serverless的計算托管式云在服務函數內,下面來講一下云函數的架構。大家看到這個架構以后,我們后面在拿一個實際案例來看怎么把具體的api服務落地。云服務器架構本身是計算托管型的,計算托管意味著把真正的業務代碼托管到云上面,然后在云上面運行,它的運行方式有一個特點是觸發式運營,跟各個產品打通以后,各個產品產生的事件,后面的案例就是和API網關進行結合,從api網關來的事件就是api事件,當這個請求到達api網關時,我們就認為是一個事件,然后再運行。大家最初進行托管的時候,把代碼和觸發期的配置提交到云上面來,并不是說提交之后代碼就運行起來,而是事件到達才運行起來,代碼對這個事件進行處理。在這個過程中,對于每一次的事件,每一個代碼拉起的過程,實際上都是單獨處理一個事件,為什么呢?因為我們在這兒使用并發的模式,如果你有上萬個用戶同時訪問你的小程序,要同時對上萬的用戶進行服務,啟動上萬的實例,它是在事件時運行起來,沒有事件不能運行,這與微信小程序本身點開即用、用完即走的概念是符合的,有請求時才運行,沒有請求時不運行。產品的計費模式也是根據實際運行的時間計費的。

Serverless的使用

clipboard.png

怎么使用Serverless呢?傳統的架構就是前面說的web服務,然后是使用存儲、緩存,我們對外服務以后,有對外暴露相應的api,實際上用戶的業務邏輯都是放在云函數內,需要結構化存儲,需要進行緩存或者對象存儲,我們需要數據服務或者云緩存服務等,其他的服務都可以直接在線服務,這些服務直接通過代碼調用。

前面講了Serverless的架構介紹,后面是對于這個后臺開發的介紹,后面也是基于這個方式進行詳細案例的說明。

clipboard.png

小程序除了本身的頁面啟動,后續與網絡的交互都是由小程序發起,經過微信本身以后,首先請求到達api網關,對于對外的api的管理,把這個api暴露到官網上,可以被要程序訪問得到。它本身也能夠提供api的發布和版本的切換能力,api網關之后就是云函數。云函數就是實際處理業務的邏輯,如果你需要使用數據庫,就在代碼內發數據庫的連接,需要存儲文件,就調用相應的窗口寫文件。

基于這個方案我們來看一下,傳統提供的是中間的一塊,因為前端是用戶的小程序,后端是微信本身提供的接口服務,中間建議的是開發者自己的服務器。我們現在要展示的一個案例,也就是怎么把中間的開發者服務器替換掉,用Serverless的方案落地,我們使用了api網關加云數據庫實現開發者服務器所能夠做到的事情,不需要購買服務器而落地我們的api。

首先從最前面的小程序來看,這個案例也是小程序開發者上面的demo,demo的前端包括登陸端口,以及session展示,我們在小程序這端首先獲取一個talk,開發者拿到以后再跟微信交互,驗證合法以后,我們這里選擇了記錄到云數據庫,這就是小程序界面提供點擊登陸的位置,后面的業務會發送請求到云上面來。

對于這個小程序的核心,我們在某一個api上面的路徑就是在hos的login url上發起GET操作,根據Wx.login構造請求的頭部,body內容,發送獲取到的code及加密數據到后臺。

clipboard.png

api網關

我們看一下api網關做的事情,它對外以一個api的接口呈現出來,我們直接提供了對外訪問的域名,用戶基于這個域名綁定自己所擁有的域名,這種情況下可以實現發布的要求,微信小程序的開發者要求域名要備案,把自己的域名綁定到api的服務上面來,對外提供,在右側api的網關上,配一個/login Get,在后臺還未實現之前,可以配置為mock方法,解耦前后端,小程序可以基于api構造的mock數據開發。實現云函數后,對接api到云函數并更新發布api,避免開發的同時影響到在線業務。

云函數的處理流程

從云函數的方面來說,用戶會承載計算業務。按照我們最開始用戶給的官方圖,拿到api的請求以后,解析請求內容,根據規范連接微信認證服務器,獲取認證情況并記錄session,返回session信息給到請求端。拿到微信服務器的返回以后可以判斷用戶的登陸過程是成功還是失敗,如果成功以后可以拿到用戶相應的值,這個地方我們發起到數據庫的連接,建立一個masico的連接,完成session的記錄。

云函數的處理流程之后,下面展示的是我們怎么和數據庫建立連接,登陸信息的細節流程,創建連接并可復用連接,拼裝SQL語句并執行。

數據庫的配置

這個地方就是我們購買以后,數據庫啟動并且做了登陸以后,可以進入到數據庫里面查看數據,查看session的記錄。

實操案例——用戶登陸及session展示

創建并初始化實例,按照mysql標準化使用方式操作,計算托管式的優勢用戶關心核心的代碼,不用關心周邊的運維,由于托管式業務,無論是個人請求,個人開發者的小程序,很有可能你的一個小程序就成為爆款,爆款以后可能訪問量就是突增的形式。

我們利用session的架構實現小程序,而且不用去擔心運維;秒級啟動,彈性計算能力滿足用戶上萬的并發。核心點關注業務代碼,而不用關注web,這就是快速的應用實現小程序的落地的方法。

clipboard.png

Q/A

Q:在api網關部署HTTPS證書嗎?
A:對,這個證書是騰訊云提供的,綁定你自己域名的時候,可以實現HTTPS的支持。

Q:我們在生產環境的時候由騰訊云提供的證書?
A:對。

Q:在生產環節需要騰訊云提供的證書上線我們的服務?
A:對,這是小程序方面的要求,因為小程序要求必須使用自有域名和小程序打通。

Q:小程序即用即刪,如果手機里面有很多會很卡,如果小程序用過在微信上面的頁面會顯示出來,如果上萬個對微信本身有什么影響?
A:可以從一些限制可以看到,現在對于微信小程序的大小有限制的,它本身的大小是要求,目前我記得是5兆包2兆包的大小,如果是上千個,對于你手機來說可能是多存儲了一些數據,每個包最大用滿可能就是5兆,本身小程序頁面的加載都是有限制的,這個限制從微信角度來考慮,都是為了保證小程序的流暢運行,不會對用戶的手機造成很大的沖擊,這一塊要微信的同學介紹,我是偏后端的。

Q:我再舉個例子,小程序進入的時候加載速度比較快的,舉一個比較極端的,比如說跳一跳,第一次使用的時候,它的加載速度,比如說今天用完了,刪掉,過一段時間再進去,相比來說加載速度有差別嗎?或者第二次用的時候快一些嗎?原因是什么?
A:這個要由微信的同學解答比較好一些,因為這些都是小程序本身的體現,或者說速度的一種體現。

Q:你好,我是做后端開發的,什么樣的模型不是用Serverless來做的。
A:Serverless它本身的一些特性也限制了它的使用場景,比如說對于內存的配置,cpu的配置,運行時間的限制,不是所有場合都適用,它本身對運行時間有限制的,不能長時間的運用,包括內存的使用,包括cpu的應用,比如說動畫的渲染,長時間的批量計算,這些都不適合api的服務,由于它的請求到達以后必須快速響應用戶,api比較適合的。

更多分享資料,請戳下面的鏈接:
使用 serverless 構建小程序后臺.pdf

問答
微信小程序如何與數據庫交互?
相關閱讀
朱展:騰訊云小程序解決方案
施德來:有贊電商小程序的實踐
鄒偉:如何開發一款小游戲

此文已由作者授權騰訊云+社區發布,原文鏈接:https://cloud.tencent.com/dev...
圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451812.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451812.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451812.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

最少編碼原則

本文作者是一位資深軟件工程師,他根據多年的編程經驗,把自己的觀點組織整理成本文,希望能給大家一點啟發。 “最少編碼原則”并不是說寫的代碼少到令意思表達不清楚。其實在很多情況下,可以只寫幾行代碼就能執行相同的邏輯&#x…

什么是標記接口

標識接口的作用 標識接口是沒有任何方法和屬性的接口。標識接口不對實現它的類有任何語義上的要求,它僅僅表明實現它的類屬于一個特定的類型。 標接口在Java語言中有一些很著名的應用,比如java.io.Serializable和java.rmi.Remote等接口便是標識接口。標識…

18--兩數之和 II - 輸入有序數組

文章目錄1.問題描述2.解題代碼1.問題描述 給定一個已按照升序排列 的有序數組,找到兩個數使得它們相加之和等于目標數。 函數應該返回這兩個下標值 index1 和 index2,其中 index1 必須小于 index2。 說明: 返回的下標值(index1 和 index2&a…

阿里巴巴 連接池 druid 的使用、maven依賴

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 1. Druid是一個JDBC組件,它包括三部分: DruidDriver 代理Driver,能夠提供基于Filter-…

Oracle數據庫(二)—— 基本的SQL SELECT語句

(一)SQL語句分為一下三種類型 DML:Date Manipulation Language 數據操縱語言DDL:Data Definition Language 數據定義語言DCL:Data Control Language 數據控制語言DML:用于查詢與修改數據記錄 包括如下SQL語句&#xff…

簡單 3 步實現高效編程

本文的內容可能部分開發者已經了解,并且已經按照這些方法實施了。但本文還是想強調這些方法,因為這些簡單的方法可以讓你的工作更加高效。要想實現高效編程,最主要的是集中注意力,但這往往也是比較難以實現的,因為你在…

bootstrap table footerFormatter用法 統計列求和 sum、average等

其實上一篇blog里已經貼了代碼,簡單解釋一下吧: 1、showFooter: true,很重要,設置footer顯示: $(cur_table).bootstrapTable({url: /etestpaper/getPaperQType,method: get,queryParams: {strParentID: parentid},ajaxOptions: {s…

19--兩數之和

文章目錄1.題目要求2.代碼詳情1.題目要求 2.代碼詳情 java:暴力求解法hashmap法 class Solution {// 方法一&#xff1a;暴力求解法// public int[] twoSum(int[] nums, int target) {// int n nums.length;// for (int i0; i<n; i){// for (int ji1; j…

單利設計模式

單利設計模式 A&#xff1a;保證對象在內存中只有一個。 B&#xff1a;如何保證&#xff1f; **不能讓其他類來創建對象。 **本類中要創建一個本類對象。 **對外提供公共的訪問。 C&#xff1a;步驟 我們的類是Student **private Student(){} **Student s new Student(); **p…

MVC表示層框架——Velocity技術

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Velocity&#xff0c;名稱字面翻譯為&#xff1a;速度、速率、迅速&#xff0c;用在Web開發里&#xff0c;用過的人可能不多&#xff0c…

redis的配置文件

redis的配置文件 之前在實習的時候才開始接觸redis&#xff0c;隨著對redis的理解加深&#xff0c;才慢慢明白它的強大&#xff0c;也逐漸對他的配置有了一定的了解。下面就分享給大家&#xff0c;以便日后查看。 位置 redis的配置文件名為redis.conf在它的安裝目錄下。 參數說…

你的代碼(軟件)安全嗎?【信息圖】

2011年安全事件層出不窮&#xff0c;幾乎可以稱為“黑客年”。以前黑客通常是利用程序漏洞來造成破壞&#xff0c;令網站陷入尷尬的境地&#xff0c;但如今他們卻是為了竊取數據、IP地址&#xff0c;或者通過在網站中植入木馬將惡意軟件安裝到訪客的電腦里&#xff0c;更有甚者…

20--兩個數組的交集

文章目錄1.問題描述2.代碼詳情1.問題描述 給定兩個數組&#xff0c;編寫一個函數來計算它們的交集。 示例 1&#xff1a; 輸入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 輸出&#xff1a;[2] 示例 2&#xff1a; 輸入&#xff1a;nums1 [4,9,5], nums2 [9,4,9,8,4] 輸…

MD5密碼加密

using System; using System.Security.Cryptography; using System.Text; namespace DimoNetwork.Common.DEncrypt { public enum MD5ResultMode : byte { Strong 0, Weak 1 } /// /// 在應用程序中定義用于單向加密文本的方法 /// public class TextEncrypt { private TextE…

跳出IT運維怪圈 看南方報業如何主動出擊

雖說世界上沒有一勞永逸的事情&#xff0c;不過借助某些方案&#xff0c;IT運維倒可做到事半功倍。近日&#xff0c;南方報業傳媒集團采用新華三智動遠程運維服務解決方案&#xff0c;利用7*24級別安仔的桌面服務&#xff0c;實現IT運維智能化、自動化管理&#xff0c;有效保障…

ORA-01841: (完整) 年份值必須介于 -4713 和 +9999 之間, 且不為 0情況解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 報錯&#xff1a;ORA-01841: (完整) 年份值必須介于 -4713 和 9999 之間, 且不為 0 2. 我的sql是&#xff1a; <!-- 查詢 推薦下載…

網絡傳輸與加密

談到網絡&#xff0c;就必然會涉及網絡安全。但“安全”這個事情&#xff0c; 一下子就會讓人聯想到黑客&#xff0c;進而把“安全”這個事情無限放大為各種高大上、神秘莫測、不可知。這不是一個engineer應有的態度&#xff08;《一次艱難debug的反思》&#xff09;。 要討論網…

21--最小棧

文章目錄1.問題描述2. 代碼詳情1.問題描述 設計一個支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常數時間內檢索到最小元素的棧。 push(x) —— 將元素 x 推入棧中。 pop() —— 刪除棧頂的元素。 top() —— 獲取棧頂元素。 getMin() —— 檢索棧中的…

python讀取excel

1 import xlrd2 book xlrd.open_workbook(app_student.xls)3 sheet book.sheet_by_index(0)4 # sheet2 book.sheet_by_name(shee1)5 # print(sheet.cell(0,0).value) #指定sheet頁里面行和lie獲取數據6 # print(sheet.cell(1,0).value) #指定sheet頁里面行和lie獲取數據7 # …