Linux性能優化之某應用CPU使用率100%,該如何?

来源:https://www.cnblogs.com/LHXW/archive/2018/11/30/10043692.html
-Advertisement-
Play Games

最常用什麼指標來描述系統的 CPU 性能呢?可能不是平均負載,也不是 CPU 上下文切換,而是另一個更直觀的指標—— CPU 使用率。 我們前面說過,CPU 使用率是單位時間內 CPU 使用情況的統計,以百分比的方式展示。諸 如 top、ps 之類的性能工具展示的 %user、%nice、 %sys ...


最常用什麼指標來描述系統的 CPU 性能呢?可能不是平均負載,也不是 CPU 上下文切換,而是另一個更直觀的指標—— CPU 使用率

我們前面說過,CPU 使用率是單位時間內 CPU 使用情況的統計,以百分比的方式展示。諸 如 top、ps 之類的性能工具展示的 %user、%nice、 %system、%iowait 、%steal 等等,它們之間有什麼的不同嗎? 瞭解 CPU 使用率的內容,同時,我也會以我們最常用的反向代理伺服器 Nginx 為 例,一步步操作和分析中深入理解。

CPU 使用率

在上一期我曾提到,Linux 作為一個多任務操作系統,將每個 CPU 的時間劃分為很短的時間片,再通過調度器輪流分配給各個任務使用,因此造成多任務同時運行的錯覺。

為了維護 CPU 時間,Linux 通過事先定義的節拍率(內核中表示為 HZ),觸發時間中斷,並使用全局變數 Jiffies 記錄了開機以來的節拍數。每發生一次時間中斷,Jiffies 的值就加 1。

節拍率 HZ 是內核的可配選項,可以設置為 100、250、1000 等。不同的系統可能設置不同數 值,你可以通過查詢 /boot/config 內核選項來查看它的配置值。比如在我的系統中,節拍率設置成了 250,也就是每秒鐘觸發 250 次時間中斷。

$ grep 'CONFIG_HZ=' /boot/config-$(uname -r)
CONFIG_HZ=250

同時,正因為節拍率 HZ 是內核選項,所以用戶空間程式並不能直接訪問。為了方便用戶空間程 序,內核還提供了一個用戶空間節拍率 USER_HZ,它總是固定為 100,也就是 1/100 秒。這 樣,用戶空間程式並不需要關心內核中 HZ 被設置成了多少,因為它看到的總是固定值 USER_HZ。

Linux 通過 /proc 虛擬文件系統,向用戶空間提供了系統內部狀態的信息,而 /proc/stat 提供 的就是系統的 CPU 和任務統計信息。比方說,如果你只關註 CPU 的話,可以執行下麵的命 令:

# 只保留各個 CPU 的數據
$ cat /proc/stat | grep ^cpu
cpu 280580 7407 286084 172900810 83602 0 583 0 0 0
cpu0 144745 4181 176701 86423902 52076 0 301 0 0 0
cpu1 135834 3226 109383 86476907 31525 0 282 0 0 0

這裡的輸出結果是一個表格。其中,第一列表示的是 CPU 編號,如 cpu0、cpu1 ,而第一行沒有編號的 cpu ,表示的是所有 CPU 的累加。其他列則表示不同場景下 CPU 的累加節拍數,它的單位是 USER_HZ,也就是 10 ms(1/100 秒),所以這其實就是不同場景下的 CPU 時間。

當然,這裡每一列的順序並不需要你背下來。你只要記住,有需要的時候,查詢 man proc 就 可以。不過,你要清楚 man proc 文檔里每一列的涵義,它們都是 CPU 使用率相關的重要指 標,你還會在很多其他的性能工具中看到它們。下麵,我來依次解讀一下。

  • user(通常縮寫為 us),代表用戶態 CPU 時間。註意,它不包括下麵的 nice 時間,但包括 了 guest 時間。

nice(通常縮寫為 ni),代表低優先順序用戶態 CPU 時間,也就是進程的 nice 值被調整為 1- 19 之間時的 CPU 時間。這裡註意,nice 可取值範圍是 -20 到 19,數值越大,優先順序反而 越低。

  • system(通常縮寫為 sys),代表內核態 CPU 時間。
  • idle(通常縮寫為 id),代表空閑時間。註意,它不包括等待 I/O 的時間(iowait)。
  • iowait(通常縮寫為 wa),代表等待 I/O 的 CPU 時間。
  • irq(通常縮寫為 hi),代表處理硬中斷的 CPU 時間。
  • softirq(通常縮寫為 si),代表處理軟中斷的 CPU 時間。
  • steal(通常縮寫為 st),代表當系統運行在虛擬機中的時候,被其他虛擬機占用的 CPU 時 間。
  • guest(通常縮寫為 guest),代表通過虛擬化運行其他操作系統的時間,也就是運行虛擬機 的 CPU 時間。
  • guest_nice(通常縮寫為 gnice),代表以低優先順序運行虛擬機的時間。

而我們通常所說的 CPU 使用率,就是除了空閑時間外的其他時間占總 CPU 時間的百分比,用 公式來表示就是:

根據這個公式,我們就可以從 /proc/stat 中的數據,很容易地計算出 CPU 使用率。當然,也可 以用每一個場景的 CPU 時間,除以總的 CPU 時間,計算出每個場景的 CPU 使用率。

不過先不要著急計算,你能說出,直接用 /proc/stat 的數據,算的是什麼時間段的 CPU 使用率 嗎? 看到這裡,你應該想起來了,這是開機以來的節拍數累加值,所以直接算出來的,是開機以來的 平均 CPU 使用率,一般沒啥參考價值。

事實上,為了計算 CPU 使用率,性能工具一般都會取間隔一段時間(比如 3 秒)的兩次值,作 差後,再計算出這段時間內的平均 CPU 使用率,即

這個公式,就是我們用各種性能工具所看到的 CPU 使用率的實際計算方法。

現在,我們知道了系統 CPU 使用率的計算方法,那進程的呢?跟系統的指標類似,Linux 也給 每個進程提供了運行情況的統計信息,也就是 /proc/[pid]/stat。不過,這個文件包含的數據就 比較豐富了,總共有 52 列的數據。

當然,不用擔心,因為你並不需要掌握每一列的含義。還是那句話,需要的時候,查 man proc 就行。

回過頭來看,是不是說要查看 CPU 使用率,就必須先讀取 /proc/stat 和 /proc/[pid]/stat 這兩 個文件,然後再按照上面的公式計算出來呢?

當然不是,各種各樣的性能分析工具已經幫我們計算好了。不過要註意的是,性能分析工具給出 的都是間隔一段時間的平均 CPU 使用率,所以要註意間隔時間的設置,特別是用多個工具對比 分析時,你一定要保證它們用的是相同的間隔時間。

比如,對比一下 top 和 ps 這兩個工具報告的 CPU 使用率,預設的結果很可能不一樣,因為 top 預設使用 3 秒時間間隔,而 ps 使用的卻是進程的整個生命周期。

怎麼查看 CPU 使用率

知道了 CPU 使用率的含義後,我們再來看看要怎麼查看 CPU 使用率。說到查看 CPU 使用率的 工具,我猜你第一反應肯定是 top 和 ps。的確,top 和 ps 是最常用的性能分析工具:

  • top 顯示了系統總體的 CPU 和記憶體使用情況,以及各個進程的資源使用情況。
  • ps 則只顯示了每個進程的資源使用情況。

比如,top 的輸出格式為:

# 預設每 3 秒刷新一次
$ top
top - 11:58:59 up 9 days, 22:47, 1 user, load average: 0.03, 0.02, 0.00
Tasks: 123 total, 1 running, 72 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8169348 total, 5606884 free, 334640 used, 2227824 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 7497908 avail Mem
 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
 1 root 20 0 78088 9288 6696 S 0.0 0.1 0:16.83 systemd
 2 root 20 0 0 0 0 S 0.0 0.0 0:00.05 kthreadd
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H
...

這個輸出結果中,第三行 %Cpu 就是系統的 CPU 使用率,具體每一列的含義上一節都講過,只 是把 CPU 時間變換成了 CPU 使用率,我就不再重覆講了。不過需要註意,top 預設顯示的是 所有 CPU 的平均值,這個時候你只需要按下數字 1 ,就可以切換到每個 CPU 的使用率了。

繼續往下看,空白行之後是進程的實時信息,每個進程都有一個 %CPU 列,表示進程的 CPU 使用率。它是用戶態和內核態 CPU 使用率的總和,包括進程用戶空間使用的 CPU、通過系統調 用執行的內核空間 CPU 、以及在就緒隊列等待運行的 CPU。在虛擬化環境中,它還包括了運行 虛擬機占用的 CPU。

所以,到這裡我們可以發現, top 並沒有細分進程的用戶態 CPU 和內核態 CPU。那要怎麼查 看每個進程的詳細情況呢?你應該還記得上一節用到的 pidstat 吧,它正是一個專門分析每個進 程 CPU 使用情況的工具。

比如,下麵的 pidstat 命令,就間隔 1 秒展示了進程的 5 組 CPU 使用率,包括:

  • 用戶態 CPU 使用率 (%usr);
  • 內核態 CPU 使用率(%system);
  • 運行虛擬機 CPU 使用率(%guest);
  • 等待 CPU 使用率(%wait);
  • 以及總的 CPU 使用率(%CPU)。

 最後的 Average 部分,還計算了 5 組數據的平均值。

# 每隔 1 秒輸出一組數據,共輸出 5 組
$ pidstat 1 5
15:56:02 UID PID %usr %system %guest %wait %CPU CPU Command
15:56:03 0 15006 0.00 0.99 0.00 0.00 0.99 1 dockerd
...
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 15006 0.00 0.99 0.00 0.00 0.99 - dockerd

CPU 使用率過高怎麼辦? 通過 top、ps、pidstat 等工具,你能夠輕鬆找到 CPU 使用率較高(比如 100% )的進程。接 下來,你可能又想知道,占用 CPU 的到底是代碼里的哪個函數呢?找到它,你才能更高效、更針對性地進行優化。

我猜你第一個想到的,應該是 GDB(The GNU Project Debugger), 這個功能強大的程式調 試利器。的確,GDB 在調試程式錯誤方面很強大。但是,我又要來“挑刺”了。請你記住, GDB 並不適合在性能分析的早期應用。

為什麼呢?因為 GDB 調試程式的過程會中斷程式運行,這線上上環境往往是不允許的。所以, GDB 只適合用在性能分析的後期,當你找到了出問題的大致函數後,線下再藉助它來進一步調 試函數內部的問題。

那麼哪種工具適合在第一時間分析進程的 CPU 問題呢?我的推薦是 perf。perf 是 Linux 2.6.31 以後內置的性能分析工具。它以性能事件採樣為基礎,不僅可以分析系統的各種事件和內核性 能,還可以用來分析指定應用程式的性能問題。

使用 perf 分析 CPU 性能問題,我來說兩種最常見、也是我最喜歡的用法。

第一種常見用法是 perf top,類似於 top,它能夠實時顯示占用 CPU 時鐘最多的函數或者指 令,因此可以用來查找熱點函數,使用界面如下所示:

$ perf top
Samples: 833 of event 'cpu-clock', Event count (approx.): 97742399
Overhead Shared Object Symbol
 7.28% perf [.] 0x00000000001f78a4
 4.72% [kernel] [k] vsnprintf
 4.32% [kernel] [k] module_get_kallsym
 3.65% [kernel] [k] _raw_spin_unlock_irqrestore
...

輸出結果中,第一行包含三個數據,分別是採樣數(Samples)、事件類型(event)和事件總 數量(Event count)。比如這個例子中,perf 總共採集了 833 個 CPU 時鐘事件,而總事件數 則為 97742399。

另外,採樣數需要我們特別註意。如果採樣數過少(比如只有十幾個),那下麵的排序和百分比 就沒什麼實際參考價值了。

再往下看是一個表格式樣的數據,每一行包含四列,分別是:

  • 第一列 Overhead ,是該符號的性能事件在所有採樣中的比例,用百分比來表示。
  • 第二列 Shared ,是該函數或指令所在的動態共用對象(Dynamic Shared Object),如內 核、進程名、動態鏈接庫名、內核模塊名等。
  • 第三列 Object ,是動態共用對象的類型。比如 [.] 表示用戶空間的可執行程式、或者動態鏈 接庫,而 [k] 則表示內核空間。
  • 最後一列 Symbol 是符號名,也就是函數名。當函數名未知時,用十六進位的地址來表示。 

 還是以上面的輸出為例,我們可以看到,占用 CPU 時鐘最多的是 perf 工具自身,不過它的比 例也只有 7.28%,說明系統並沒有 CPU 性能問題。 perf top 的使用你應該很清楚了吧。

接著再來看第二種常見用法,也就是 perf record 和 perf report。 perf top 雖然實時展示了系 統的性能信息,但它的缺點是並不保存數據,也就無法用於離線或者後續的分析。而 perf record 則提供了保存數據的功能,保存後的數據,需要你用 perf report 解析展示。

$ perf record # 按 Ctrl+C 終止採樣
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.452 MB perf.data (6093 samples) ]
$ perf report # 展示類似於 perf top 的報告

在實際使用中,我們還經常為 perf top 和 perf record 加上 -g 參數,開啟調用關係的採樣,方 便我們根據調用鏈來分析性能問題。

案例

下麵我們就以 Nginx + PHP 的 Web 服務為例,來看看當你發現 CPU 使用率過高的問題後, 要怎麼使用 top 等工具找出異常的進程,又要怎麼利用 perf 找出引發性能問題的函數。

你的準備

案例 基於 Ubuntu 18.04,同樣適用於其他的 Linux 系統。我使用的案例環境如下所示:

  • 機器配置:2 CPU,8GB 記憶體
  • 預先安裝 docker、sysstat、perf、ab 等工具,如 apt install docker.io sysstat linuxtools-common apache2-utils

我先簡單介紹一下這次新使用的工具 ab。ab(apache bench)是一個常用的 HTTP 服務性能 測試工具,這裡用來模擬 Ngnix 的客戶端。由於 Nginx 和 PHP 的配置比較麻煩,我把它們打 包成了兩個 Docker 鏡像,這樣只需要運行兩個容器,就可以得到模擬環境。

註意,這個案例要用到兩台虛擬機,其中一臺用作 Web 伺服器,來模擬性能問題;另一臺用作 Web 伺服器的客戶端,來給 Web 服務增加壓力請求。使用兩台虛擬機是為了相互隔離,避 免“交叉感染”。

接下來,我們打開兩個終端,分別 SSH 登錄到兩台機器上,並安裝上面提到的工具。還是同樣的“配方”。下麵的所有命令,都預設假設以 root 用戶運行,如果你是普通用戶身份 登陸系統,一定要先運行 sudo su root 命令切換到 root 用戶。到這裡,準備工作就完成了。

不過,操作之前,我還想再說一點。這次案例中 PHP 應用的核心邏輯比較簡單,大部分人一眼 就可以看出問題,但你要知道,實際生產環境中的源碼就複雜多了。

所以,我希望你在按照步驟操作之前,先不要查看源碼(避免先入為主),而是把它當成一個黑 盒來分析。這樣,你可以更好地理解整個解決思路,怎麼從系統的資源使用問題出發,分析出瓶 頸所在的應用、以及瓶頸在應用中的大概位置。

操作和分析

接下來,我們正式進入操作環節。

首先,在第一個終端執行下麵的命令來運行 Nginx 和 PHP 應用:

$ docker run --name nginx -p 10000:80 -itd feisky/nginx
$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm

接著,我們來測試一下這個 Nginx 服務的性能。在第二個終端運行下麵的 ab 命令:

# 併發 10 個請求測試 Nginx 性能,總共測試 100 個請求
$ ab -c 10 -n 100 http://192.168.0.10:10000/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
...
Requests per second: 11.63 [#/sec] (mean)
Time per request: 859.942 [ms] (mean)
...

從 ab 的輸出結果我們可以看到,Nginx 能承受的每秒平均請求數只有 11.63。你一定在吐槽, 這也太差了吧。那到底是哪裡出了問題呢?我們用 top 和 pidstat 再來觀察下。

這次,我們在第二個終端,將測試的請求總數增加到 10000。這樣當你在第一個終端使用性能 分析工具時, Nginx 的壓力還是繼續。

繼續在第二個終端,運行 ab 命令:

$ ab -c 10 -n 10000 http://10.240.0.5:10000/

接著,回到第一個終端運行 top 命令,並按下數字 1 ,切換到每個 CPU 的使用率:

$ top
...
%Cpu0 : 98.7 us, 1.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 99.3 us, 0.7 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
...
 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21514 daemon 20 0 336696 16384 8712 R 41.9 0.2 0:06.00 php-fpm
21513 daemon 20 0 336696 13244 5572 R 40.2 0.2 0:06.08 php-fpm
21515 daemon 20 0 336696 16384 8712 R 40.2 0.2 0:05.67 php-fpm
21512 daemon 20 0 336696 13244 5572 R 39.9 0.2 0:05.87 php-fpm
21516 daemon 20 0 336696 16384 8712 R 35.9 0.2 0:05.61 php-fpm

這裡可以看到,系統中有幾個 php-fpm 進程的 CPU 使用率加起來接近 200%;而每個 CPU 的 用戶使用率(us)也已經超過了 98%,接近飽和。這樣,我們就可以確認,正是用戶空間的 php-fpm 進程,導致 CPU 使用率驟升。

那再往下走,怎麼知道是 php-fpm 的哪個函數導致了 CPU 使用率升高呢?我們來用 perf 分析 一下。在第一個終端運行下麵的 perf 命令:

# -g 開啟調用關係分析,-p 指定 php-fpm 的進程號 21515
$ perf top -g -p 21515

按方向鍵切換到 php-fpm,再按下回車鍵展開 php-fpm 的調用關係,你會發現,調用關係最 終到了 sqrt 和 add_function。看來,我們需要從這兩個函數入手了。

 

我們拷貝出 Nginx 應用的源碼,看看是不是調用了這兩個函數:

# 從容器 phpfpm 中將 PHP 源碼拷貝出來
$ docker cp phpfpm:/app .
# 使用 grep 查找函數調用
$ grep sqrt -r app/ # 找到了 sqrt 調用
app/index.php: $x += sqrt($x);
$ grep add_function -r app/ # 沒找到 add_function 調用,這其實是 PHP 內置函數

OK,原來只有 sqrt 函數在 app/index.php 文件中調用了。那最後一步,我們就該看看這個文 件的源碼了:

$ cat app/index.php
<?php
// test only.
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
 $x += sqrt($x);
}
echo "It works!"

呀,有沒有發現問題在哪裡呢?我想你要笑話我了,居然犯了一個這麼傻的錯誤,測試代碼沒刪 就直接發佈應用了。為了方便你驗證優化後的效果,我把修複後的應用也打包成了一個 Docker 鏡像,你可以在第一個終端中執行下麵的命令來運行它:

# 停止原來的應用
$ docker rm -f nginx phpfpm
# 運行優化後的應用
$ docker run --name nginx -p 10000:80 -itd feisky/nginx:cpu-fix
$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:cpu-fix

接著,到第二個終端來驗證一下修複後的效果。首先 Ctrl+C 停止之前的 ab 命令後,再運行下 面的命令:

$ ab -c 10 -n 10000 http://10.240.0.5:10000/
...
Complete requests: 10000
Failed requests: 0
Total transferred: 1720000 bytes
HTML transferred: 90000 bytes
Requests per second: 2237.04 [#/sec] (mean)
Time per request: 4.470 [ms] (mean)
Time per request: 0.447 [ms] (mean, across all concurrent requests)
Transfer rate: 375.75 [Kbytes/sec] received
...

從這裡你可以發現,現在每秒的平均請求數,已經從原來的 11 變成了 2237。

你看,就是這麼很傻的一個小問題,卻會極大的影響性能,並且查找起來也並不容易吧。當然, 找到問題後,解決方法就簡單多了,刪除測試代碼就可以了。

小結

CPU 使用率是最直觀和最常用的系統性能指標,更是我們在排查性能問題時,通常會關註的第 一個指標。所以我們更要熟悉它的含義,尤其要弄清楚用戶(%user)、Nice(%nice)、系統 (%system) 、等待 I/O(%iowait) 、中斷(%irq)以及軟中斷(%softirq)這幾種不同 CPU 的使用率。比如說:

  • 用戶 CPU 和 Nice CPU 高,說明用戶態進程占用了較多的 CPU,所以應該著重排查進程的 性能問題。
  • 系統 CPU 高,說明內核態占用了較多的 CPU,所以應該著重排查內核線程或者系統調用的 性能問題。
  • I/O 等待 CPU 高,說明等待 I/O 的時間比較長,所以應該著重排查系統存儲是不是出現了 I/O 問題。
  • 軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程式占用了較多的 CPU,所以應該著重排查 內核中的中斷服務程式。

碰到 CPU 使用率升高的問題,你可以藉助 top、pidstat 等工具,確認引發 CPU 性能問題的來 源;再使用 perf 等工具,排查出引起性能問題的具體函數。

技巧:

1.cpu使用率,就是cpu被使用的比例,也就是空閑之外的使用比例。 發現cpu使用率高後,先用perf來抓取cpu消耗棧,很容易發現瓶頸。 另外,用mpstat -P ALL 來看各個cpu核心的使用率情況,因為top之類的看的是系統總使用率,不一定能發現問題,特別是多進程或者多線程應用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • umask命令 作用:用於顯示、設置文件的預設許可權 格式:umask [-S] -S表示以rwx形式顯示新建文件預設許可權 系統的預設掩碼是0022 文件創建時的預設許可權 = 0666 - umask 目錄創建時的預設許可權 = 0777 - umask 所以創建文件的許可權是 0666 - 0022 = ...
  • $ : > filename $ > filename $ echo "" > filename $ echo > filename $ cat /dev/null > filename ...
  • 項目中遇到的比較奇葩的問題,從網上找到一份源碼,https://blog.csdn.net/qq125096885/article/details/70766206 稍微整理了下,VS可以直接編譯 ...
  • 安裝mysql 1、檢測是否已安裝mysql [root@localhost bin]# rpm -qa | grep mysql mysql-libs-5.1.71-1.el6.i686 [root@localhost bin] 2、安裝mysql和mysql-server [root@local ...
  • atril、gimp和evince,三者均可以打開application/pdf格式文件。gimp為一款圖像處理軟體;atril為mate環境下常用的文檔查看器;evince為gnome環境下常用的文檔查看器。 某mate桌面和gnome伺服器環境中配置文件mimeapps.list都定義了appl ...
  • naconda修改國內鏡像源 國外網路有時太慢,可以通過配置把下載源改為國內的通過 conda config 命令生成配置文件,這裡使用清華的鏡像: https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ 首先,打開Anaconda Prom ...
  • 在記憶體管理的上下文中, 初始化(initialization)可以有多種含義. 在許多CPU上, 必須顯式設置適用於Linux內核的記憶體模型. 例如在x86_32上需要切換到保護模式, 然後內核才能檢測到可用記憶體和寄存器. 而我們今天要講的bootmem分配器就是系統初始化階段使用的記憶體分配器. 為 ...
  • 1 Scope of Document This document describes 4G hardware design, support quectel ec20 4G module/ Simcom 7600 CE 4G module 2 Requiremen 2.1 Function Req ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...