八股文場景題

如何預估接口上線后的 QPS

問題引入

這個問題其實是一個非常實際的問題,因為我們在開發需求后,例如:新增了一個接口

有一個步驟是值得做的,那就是預估這個接口的QPS

因為我們是可以去調配對應服務器的數量和運行配置的

  • 例如我可以從2個節點新增為4個節點
  • 例如我可以將節點的內存從2G變成4G,2核CPU變成4核CPU

如果因為 沒有正確的預估 以及 沒有正確的調整,導致接口的QPS過高,扛不住系統崩潰,那就是嚴重的外網事故了

注意,這里說的預估QPS,是假設有一個真實的項目、真實的環境,預估這個接口上線后會有多少 QPS而不是在預估我們的系統接口本身能抗住多少QPS而不崩潰

如何預估

預估一個接口的 QPS,本質上是在考慮這個接口被調用的頻繁程度

1.分析業務

  • 業務類型: 不同的業務類型的QPS是不太一樣的,再細化一些,接口的做的事情是不同的,QPS是不同的,例如這個接口是 獲取商城首頁數據(QPS估計會高)、刪除好友(QPS估計會低)
  • 活躍用戶: 有多少活躍用戶,活躍用戶多(QPS估計會高),活躍用戶少(QPS估計會低)

2.計算平均的QPS:根據活躍用戶數和業務類型估算

  • 假設有100w個活躍用戶(數值由活躍用戶決定)
  • 假設經過歷史數據的統計,每個用戶平均每天產生10次請求(數值由業務類型決定)
  • 則可估算出平均每秒請求量(QPS)為 (10 * 100w)/ 86400= 116

3.計算峰值的QPS:假設業務類型是有峰值情況(特殊事件帶來的流量波動)的,即我們的接口可能會達到更高的QPS

  • 峰值情況通常是的平均值的數倍,假設峰值為平均值的3倍,則峰值QPS約為348

通過預估接口上限后可能的峰值QPS后,就可以相對應的調整服務器節點的數量、服務器的運行配置需要能抗住峰值QPS,記得給自己留點緩沖,即把值設置的略大一些

如何預估/回答接口本身能抗住多少 QPS

與哪些因素有關

后端服務器集群節點數量,數量越多,QPS越高

后端服務器節點的運行配置:運行內存、Cpu核數等等,硬件資源決定單節點處理能力

接口本身做的事情

  1. 做的事情多耗時長(預估QPS會相對應低)
  2. 做的事情少耗時短(預估QPS會相對應高)

系統架構:

  1. 完善的流量負載均衡架構,實現流量的有效分發和負載均衡,避免成為QPS瓶頸
  2. 緩存技術,減輕數據庫的壓力,避免數據庫成為QPS瓶頸
  3. 集群模式的數據庫,避免數據庫成為QPS瓶頸
  4. 靜態資源通過CDN加速,避免成為QPS瓶頸

如何預估?

首先需要知道一個請求處理完畢的時間(這個請求里可能做很多事情,但是這個我們暫時不管),一個請求處理完畢的時間我們是可以知道的。(我們去調用這個接口多次得到平均值即可)

理論計算公式

QPS(單節點) = 線程數(如 Tomcat 線程池)/ 平均請求處理時間(秒)

  • 例如:若線程池大小為 200,單個請求處理時間為 50ms(0.05秒)
  • SprigBoot 默認使用Tomcat,而Tomcat線程池的最大線程數就是200,所以在默認配置下,SprigBoot 應用可以并發處理 200 請求則 QPS(單節點) = 200 / 0.05= 4000

QPS(集群)= QPS(單節點)* 節點數

  • 例如集群有4個節點,則 QPS(集群)= 4000 * 4 = 16000

單個請求處理的時間是受到 “系統架構”、“接口本身做的事情”“后端服務器節點運行配置”“后端服務器節點數量”等等因素共同影響的 但這實際上是一個近似已知值(我們去調用這個接口多次得到平均值即可)

QPS瓶頸

我們想想QPS的瓶頸在哪?其實很多方面,就像前面說的QPS與哪些因素有關但一般來說 QPS 最可能的瓶頸在于數據庫 (例如MySQL)

應該說多少QPS

面試官如果問接口的QPS多少,如何回答比較合理?

首先我們一定可以知道這個接口處理的平均耗時是多久?假設是200ms

一些項目背景暫時假設為如下情況,因個人而定

  1. 假設有 n 臺后端服務器
  2. 假設后端服務器的配置是 2核4G內存
  3. 假設接口做了一些事情
  4. 假設對于一些系統架構上,做了一些優化、或者沒有做優化

那么

  1. QPS(單節點) = 線程數(如 Tomcat 線程池)/ 平均請求處理時間(秒)若線程池大小為 200,單個請求處理時間為 100ms(0.01秒)則 QPS(單節點) = 200 / 0.01= 2000
  2. QPS(集群)= QPS(單節點)* 節點數 = 2000 * n

沒有壓測的情況下,我們就可以說這個理論計算得出的值。但是理論僅僅是理論如果有壓測,那其實是另外更好的一種情況,因為壓測得到的數據往往是更加準確的。例如壓測過程:使用 JMeter 進行了壓力測試,逐步增加并發線程數,直到接口的響應時間超過預設閾值(如 200ms)或錯誤率超過 1%。此時就可以知道接口可以抗住的QPS

示例

面試官:“你在項目中負責的訂單查詢接口,QPS 是多少?”

你的回答: “訂單查詢接口的 QPS 在‘雙11’大促期間峰值達到 5,000,日常平均 QPS 約為 1,200。我們通過以下步驟得出這一數據:

  1. 壓測階段:JMeter 進行了壓力測試,逐步增加并發線程數,發現當 QPS 達到 2,000 時,響應時間達到300ms。
  2. 瓶頸分析:通過 Arthas 追蹤發現,80% 的請求耗時在數據庫查詢上。
  3. 優化措施(僅為舉例,具體情況依據個人而定):引入 Redis 緩存熱點商品數據,緩存命中率提升至 90%;對訂單表按用戶 ID 進行分庫分表,單表數據量從 1 億減少到 1 千萬;將日志記錄改為異步寫入 Kafka,減少主線程耗時。
  4. 優化結果:最終壓測 QPS 提升到 5,000,且響應時間穩定在 80ms 以內。 此外,線上監控顯示,實際高峰期的 QPS 與壓測結果基本一致,系統未出現超時或宕機。”

如何設計一個秒殺系統

秒殺系統場景特點

  • 秒殺一般是訪問請求數量遠遠大于庫存數量,只有少部分用戶能夠秒殺成功
  • 秒殺時大量用戶會在同一時間同時進行搶購,網站瞬時訪問流量激增
  • 秒殺業務流程比較簡單,一般就是下訂單減庫存

秒殺架構設計理念

  • 限流: 鑒于只有少部分用戶能夠秒殺成功,所以要限制大部分流量,只允許少部分流量進?服務后端秒殺程序。
  • 削峰:對于秒殺系統瞬時會有大量用戶涌入,所以在搶購一開始會有很高的瞬間峰值。高峰值流量是壓垮系統很重要的原因,所以如何把瞬間的高流量變成一段時間平穩的流量也是設計秒殺系統很重要的思路。實現削峰
    的常用的方法有前端添加一定難度的驗證碼,后端利用緩存和消息中間件等技術。
  • 異步處理:秒殺系統是一個高并發系統,采用異步處理模式可以極大地提高系統并發量,其實異步處理就是削峰的一種實現方式。
  • 內存緩存:秒殺系統最大的瓶頸一般都是數據庫讀寫,由于數據庫讀寫屬于磁盤IO,性能很低,如果能夠把部分數據或業務邏輯轉移到內存緩存,效率會有極大地提升。
  • 可拓展:當然如果我們想支持更多用戶,更大的并發,最好就將系統設計成彈性可拓展的,如果流量來了,拓展機器就好了。像淘寶、京東等雙十一活動時會增加大量機器應對交易高峰。

設計思路

  • 將請求攔截在系統上游,降低下游壓力:秒殺系統特點是并發量極大,但實際秒殺成功的請求數量卻很少,所以如果不在前端攔截很可能造成數據庫讀寫鎖沖突,甚至導致死鎖,最終請求超時
  • 充分利用緩存:利?緩存預減庫存,攔截掉大部分請求
  • 消息隊列:這是?個異步處理過程,后臺業務根據自己的處理能力,從消息隊列中主動的拉取請求消息進行業務處理

前端方案

  • 頁面靜態化:將活動頁面上的所有可以靜態的元素全部靜態化,并盡量減少動態元素。通過CDN來抗峰值。
  • 禁止重復提交:用戶提交之后按鈕置灰,禁止重復提交
  • 用戶限流:在某一時間段內只允許用戶提交一次請求,比如可以采取IP限流

后端方案
服務端控制器層(網關層)
限制uid(UserID)訪問頻率:我們上面攔截了瀏覽器訪問的請求,但針對某些惡意攻擊或其它插件,在服務端控制層需要針對同?個訪問uid,限制訪問頻率。

服務層
? 上面只攔截了一部分訪問請求,當秒殺的用戶量很大時,即使每個用戶只有一個請求,到服務層的請求數量還是很大。比如我們有100W用戶同時搶100臺手機,服務層并發請求壓力至少為100W。

  • 把需要秒殺的商品的主要信息以及庫存初始化到redis緩存中
  • 做請求合法性的校驗(比如是否登錄),如果請求非法,直接給前端返回錯誤碼,進行相應的提示
  • 進行內存標識的判斷 (true 已經秒殺結束,false 未秒殺結束,下面第4步會寫入),如果內存標識為true,直接返回秒殺結束
  • redis中使用 decr 進行預減庫存操作,判斷:如果decr后庫存量小于0,則把內存標記置為true (已經秒殺結束,第3步會用到),且返回秒殺結束
  • 用redis的布隆過濾器來判斷是否已經秒殺到了(下面第7步會寫入),防止重復秒殺,如果重復秒殺,直接返回重復秒殺的錯誤碼。具體做法是:先用redis的布隆過濾器來判斷是否秒殺過,如果布隆過濾器判斷已經秒殺過了, 則再次查庫確認是否秒殺過了,之所以再次查庫確認是因為布隆過濾器對可能存在的數據是有誤判率的;但是它對不存在的數據的判斷是百分百準確的,所以如果redis的布隆過濾器判斷沒秒殺過,就直接放過去進行秒殺
  • 發送成功秒殺到的MQ消息給相應的業務端進行處理,并給用戶端返回排隊中,如果客戶端收到排隊中的消息,則自動進行輪詢查詢,直到返回秒殺成功或者秒殺失敗為止
  • 相應的業務端進行處理:真正處理秒殺的業務端,再次進行校驗(比如秒殺是否結束,庫存是否充足等)、將用戶和商品id作為key存入redis的布隆過濾器來標識該用戶秒殺該商品成功(第5步會用到)、減庫存(這里的是真正的減庫存,操作數據庫的庫存)、生成秒殺訂單、返回秒殺成功

注意:就算請求走到了真正處理業務的這一端,也有可能秒殺失敗,比如秒殺結束,庫存不足,真正減庫存失敗,秒殺單生成失敗等等,一旦失敗,則返回秒殺結束

優化:將秒殺接口隱藏:用戶點擊秒殺按鈕的時候,根據用戶id生成唯一的加密串存入緩存并返回給客戶端,然后客戶端再次請求的時候帶著加密串過來,后端進行校驗是否合法,若不合法,直接返回請求非法

限制某個接口的訪問頻率:可以用攔截器配合自定義注解來實現,這么做可以和具體的業務分離減少?侵,使用起來也非常方便

數據庫層

  • 數據庫層是最脆弱的一層,一般在應用設計時在上游就需要把請求攔截掉,數據庫層只承擔“能力范圍內”的訪問請求。所以,上面通過在服務層引入隊列和緩存,讓最底層的數據庫高枕無憂
  • 為防止秒殺出現負數訂單數大于真正的庫存數,所以在真正減庫存,update 庫存的時候應該加上 where 庫存 > 0,而且需要給秒殺訂單表加上用戶id和商品id聯合的唯一索引

10億訂單表如何做分庫分表?

場景痛點:某電商平臺的MySQL訂單表達到7億行時,出現致命問題:

-- 簡單查詢竟需12秒!
SELECT * FROM orders WHERE user_id=10086 LIMIT 10;
?
-- 統計全表耗時278秒
SELECT COUNT(*) FROM orders;

核心矛盾

  1. B+樹索引深度達到5層,磁盤IO暴增。

  2. 單表超200GB導致備份時間窗突破6小時。

  3. 寫并發量達8000QPS,主從延遲高達15分鐘。

分庫分表核心策略

垂直拆分:先給數據做減法 ? ? ?
? ? 按列拆分:將一張寬表的字段按業務屬性分散到不同的表中?

優化效果: - 核心表體積減少60% - 高頻查詢字段集中提升緩存命中率

水平拆分:終極解決方案

按行拆分:將表數據按某種規則(如ID范圍、哈希值)分散到多個結構相同的表中。
?
分片鍵選擇三原則**:
? 1.離散性:避免數據熱點(如user_id優于status)
? 2.業務相關性:80%查詢需攜帶該字段
? 3.穩定性:值不隨業務變更(避免使用手機號)

?? 基因嵌入:將用戶的后幾位id編號(gene)嵌入到訂單ID的生成 ==>比較有名的就是淘寶19位訂單編號,后六位是用戶ID的后六位 然后再根據訂單編號的用戶ID進行分庫分表==>分8個庫 每個庫16張表? 注意這種建立起來的庫是用戶庫

關鍵突破**:通過基因嵌入,使相同用戶的訂單始終落在同一分片,同時支持通過訂單ID直接定位分片 ?
**跨分片查詢** ?

三個高頻場景對應三種查詢方式 :(缺少訂商家發貨)

  • ?? 核心矛盾:商家與訂單是多對多關系,一個商家的訂單會分散在所有分片中。
  • ?? 方案:Elasticsearch二級索引
  • ?? 思想:創建一個輔助索引,也就是附錄==>通俗來講,就好比字典的拼音查詢(主查詢)以及偏旁筆畫查詢(二級查詢) ?

實施步驟

將訂單數據同步到ES:

{"mappings": {"properties": {"merchant_id": { "type": "keyword" },"order_id": { "type": "keyword" },"user_gene": { "type": "integer" }}}
}

查詢實現:

SearchResponse response = client.prepareSearch("orders").setQuery(QueryBuilders.termQuery("merchant_id", merchantId)).addSort("create_time", SortOrder.DESC).setSize(100).get();

數據遷移

雙寫遷移方案

img

灰度切換步驟

  1. 開啟雙寫(新庫寫失敗需回滾舊庫)
  2. 全量遷移歷史數據(采用分頁批處理)
  3. 增量數據實時校驗(校驗不一致自動修復)
  4. 按用戶ID灰度流量切換(從1%到100%)

性能指標

場景拆分前拆分后
用戶訂單查詢3200ms68ms
商家訂單導出超時失敗8s完成
全表統計不可用1.2s(近似)

總結

  1. 分片鍵選擇大于努力:基因分片是訂單系統的最佳拍檔。
  2. 擴容預留空間:建議初始設計支持2年數據增長。
  3. 避免過度設計:小表關聯查詢遠比分布式Join高。效
  4. 監控驅動優化:重點關注分片傾斜率>15%的庫。

如何實現A網站登錄后,B網站自動登錄

有這么個場景,公司下有多個不同域名的站點,我們期望用戶在任意一個站點下登錄后,在打開另外幾個站點時,也是已經登錄的狀態,這么一過程就是單點登錄。因為多個站點都是用的同一套用戶體系,所以單點登錄可以免去用戶重復登錄,讓用戶在站點切換的時候更加流暢,甚至是無感知。

題述問題,本質上是 單點登錄 的問題

單點登錄(Single Sign-On,簡稱 SSO) :是一種用戶認證機制,允許用戶在一次登錄后,訪問多個系統或應用程序而無需再次登錄

基于Cookie

適用情況: A網站和B網站必須是同一域名下的兩個網站,如 a.example.com 和 b.example.com

可以通過共享 Cookie 的方式來實現 SSO

  • 優點是實現起來簡單,瀏覽器天然就支持
  • 缺點是限制必須不能跨域,如果是兩個不相關的網站,就不能通過Cookie實現SSO

基于Token

? ? ? 使用標準化的令牌(如 JWT)來攜帶用戶認證信息。用戶登錄后,服務端頒發一個令牌(Token)給到前端,前端在訪問其他的網站的時候,把這個 Token 放到 HTTP Header 中帶過去,然后就可以基于這個Tokne來驗證用戶身份了
? ? ?這個方案可以解決跨域的問題,只要支持HTTP的協議即可。但是缺點是Token可能會被泄漏。存在一定的安全隱患

基于共享Session

用戶登錄后,系統將用戶信息存儲到公共的第三方存儲,如Redis或數據庫

例如使用Redis,那么所有業務系統都必須知道該公共Redis的實例信息,才能夠訪問獲取用戶信息

通過CAS

CAS 是 Central Auth Service,也就是認證中心服務

注意和并發編程中的 Compare And Swap 區分

多個需要實現單點登錄的系統,都接入這個統一認證中心,所有的登錄、認證都通過這個認證中心來實現

  1. 用戶訪問子系統時重定向到 CAS 服務器登錄
  2. CAS 服務器驗證用戶身份并返回一個票據(Ticket)
  3. 子系統使用票據向 CAS 驗證,獲取用戶信息

這個方案一般適合于企業內部做集成,可以讓業務系統不再關心登錄、授權,而是只關注業務邏輯,只需要做一次接入就行了。比如說公司的很多內部平臺之間,就可能是用了同一個登錄服務。

優點就是接入成本低,缺點就是這個認證中心本身的開發成本還是挺高的。

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

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

相關文章

【Web安全】深入淺出理解“SQL注入-偽靜態注入”及空格限制繞過技巧

文章目錄什么是偽靜態注入?偽靜態注入中如何繞過空格限制?1. 用注釋符替代空格2. 用不可見字符(URL 編碼)替代3. 用括號分隔語句4. 用特殊符號替代核心邏輯往期文章【Web安全】一次性搞懂 ReDOS 漏洞原理/檢測/防御 【Web安全】一…

【讀論文】Step-Audio 2 深度解讀:邁向工業級語音交互的「全能型選手」

引言:step-Audio升級 語音交互技術,作為人機交互最自然、最直接的方式之一,正以前所未有的速度發展。從簡單的語音指令到流暢的語音對話,我們對 AI 的期望越來越高。然而,要讓 AI 真正成為我們的“知心伙伴”,僅僅能“聽懂”和“說出”還遠遠不夠。 一個理想的語音 AI,…

java web 重定向

目錄結構 demo\day20\src\com\demo\service\Dome1.javademo\day20\src\com\demo\service\Dome2.javademo\day20\src\com\demo\service\Dome3.javademo\day20\src\com\demo\service\Dome4.javademo\day20\web\WEB-INF\lib\javax.servlet.jardemo\day20\web\index.jspdemo\day20\…

MySQL(配置)——MariaDB使用

一、簡介 MariaDB 和 MySQL 作為兩個流行的關系型數據庫管理系統,它們的區別可以從多個角度來探討。盡管 MariaDB 最初是 MySQL 的一個分支,但隨著時間的推移,它們逐漸在功能、性能和開發方向上有所不同。MariaDB 是 MySQL 的一個分支&#x…

Web3:賽道劃分與發展趨勢解析

區塊鏈技術現在已經從單一的加密貨幣支付系統發展為涵蓋金融、藝術、組織治理和社區文化的多元生態系統。這次我們將深入解析 DeFi(去中心化金融)、NFT(非同質化代幣)、DAO(去中心化自治組織)與 MEME&#…

LeetCode 283 - 移動零

思路 使用雙指針法,一次遍歷完成原地修改。 慢指針 slow:指向下一個非零元素應該被放置的位置。快指針 fast:遍歷整個數組,尋找非零元素。 當 fast 遇到非零數時,將其值賦給 slow 指向的位置,然后 slow 前進…

8. 網絡層

在復雜的網絡環境中確定一個合適的路徑.1. IP協議1. 基本概念IP協議:提供一種能力(有非常大的概率,做到某事),把數據報從主機A,跨網絡,送到主機B --> 必須要有方式,標識通信兩端唯一性!&…

【通識】線性代數(Linear Algebra)

線性代數被廣泛應用于抽象代數和泛函分析中;通過解析幾何,線性代數能被具體表示,線性代數被泛化為算子理論。而非線性模型被近似為線性模型,應用場景多為自然科學和社會科學。 費馬和笛卡爾的工作,線性代數出現于十七世…

Qt 嵌入式界面優化技術

在嵌入式系統中,界面性能直接影響用戶體驗和系統穩定性。由于嵌入式設備通常資源受限(如低性能 CPU、有限內存、小尺寸屏幕),需針對性優化 Qt 界面以實現流暢顯示和高效交互。本文從渲染引擎、資源管理、布局優化到硬件加速&#…

去除視頻字幕 4 : 下一步,打算研究 Video Inpainting (視頻修復):

就是說,到現在,才算是真正開始,才發現真正的問題。 嘗試去除視頻上的字幕,使用 IOPaint, 效果很初級。。。問題描述 請幫我分析此時的效果。 此時的右側字幕區域,閃爍不停!我原本以為效果會很好。實際非常…

代碼隨想錄算法訓練營第五十五天|圖論part5

并查集理論基礎 初始化: void init() {for (int i 0; i < n; i) {father[i] i;} } 尋根&#xff1a; // 并查集里尋根的過程 int find(int u) {return u father[u] ? u : father[u] find(father[u]); // 路徑壓縮 } 判斷u跟v是否同根 // 判斷 u 和 v是否找到同一個根 b…

安卓模擬器 adb Frida hook 抓包

基本步驟 adb connect 127.0.0.1:62001adb forward tcp:27042 tcp:27042 adb forward tcp:27043 tcp:27043adb shell./data/local/tmp/frida-server再開啟cd D:\linuxdir\python\fridapython main.py下載夜神模擬 https://www.yeshen.com/ 安裝adb 點擊下載adb&#xff08…

編程與數學 03-002 計算機網絡 14_網絡性能分析

編程與數學 03-002 計算機網絡 14_網絡性能分析一、網絡性能指標&#xff08;一&#xff09;帶寬、時延、吞吐量等指標的定義與測量方法&#xff08;二&#xff09;性能指標對網絡應用的影響二、網絡性能的測試方法&#xff08;一&#xff09;使用網絡測試工具&#xff08;如Wi…

AT9880B參數特征

AT9880B 是一款高性能北斗單模衛星導航接收機 SOC 單芯片&#xff0c;芯片集成射頻前端和數字基帶、北斗多頻衛星信號處理引擎、電源管理功能。 芯片支持接收中國北斗二號和北斗三號&#xff0c;支持接收 B1I、B1C、B2I、B3I、B2a 和 B2b 等頻點信號。主要特征 支持北斗二號/三…

eBPF 賦能云原生: WizTelemetry 無侵入網絡可觀測實踐

引言 隨著 KubeSphere 企業版 4.2.0 的正式發布&#xff0c;WizTelemetry 可觀測平臺 2.0 也同步亮相。作為本次升級中的重磅模塊之一&#xff0c;它迅速引發了開發與運維團隊的廣泛關注。 本系列文章將系統解讀 WizTelemetry 的核心能力與落地實踐。繼前兩篇介紹了平臺架構與指…

【JAVA安全-Fastjson系列】Fastjson 1.2.24 反序列化漏洞分析及測試環境構建【復習回顧】

Fastjson 1.2.24 反序列化漏洞分析及測試環境構建 漏洞背景 Fastjson 是阿里巴巴開源的一個高性能 Java JSON 庫&#xff0c;廣泛用于 Java 對象的序列化和反序列化。在 1.2.24 及之前的版本中&#xff0c;存在一個嚴重的安全漏洞&#xff0c;攻擊者可以通過構造惡意的 JSON 字…

關于神經網絡CNN的搭建過程以及圖像卷積的實現過程學習

通過如下博客內容學習了CNN搭建的步驟&#xff0c;按照博主的思路完成了cnn網絡的構建并完成50個epoch的訓練并畫出損失函數的曲線圖時有滿滿的成就感 PyTorch深度學習實戰&#xff08;3&#xff09;——使用PyTorch構建神經網絡_pytorch 神經網絡-CSDN博客 通過如下博客內容…

nodejs 實現Excel數據導入數據庫,以及數據庫數據導出excel接口(核心使用了multer和node-xlsx庫)

項目地址&#xff1a;https://gitee.com/LiangDouJun/nodejsExcel 一、實現效果 1、數據庫數據導出 2、excel導入 二、代碼實現 // 根據環境加載對應的配置文件 const env process.env.NODE_ENV || development; require(dotenv).config({ path: .env.${env} });const expr…

VUE2 學習筆記8 v-text/html/cloak/once/pre/自定義

除了之前已經介紹過的v-on v-bind v-for v-if v-show&#xff0c;vue還有很多其他的指令。v-textv-text是Vue內置指令。內置指令&#xff0c;是Vue內部定義好的&#xff0c;開發的時候直接拿來用就行了。v-text用于向其所在的標簽添加文本。<body><div id"root&q…

vue 使用postcss-pxtorem 實現適老化

1. 安裝依賴 npm install postcss-pxtorem -D2. 配置 Vite (vite.config.js) import { defineConfig } from vite import vue from vitejs/plugin-vue import postcsspxtorem from postcss-pxtoremexport default defineConfig({plugins: [vue()],css: {postcss: {plugins: [po…