Systemd簡介與使用

来源:https://www.cnblogs.com/Franken-Fran/archive/2018/11/21/my_systemd.html
-Advertisement-
Play Games

關於systemd的學習筆記,講述了主要用法指令、配置以及如何自定義單元等 ...


按下電源鍵,隨著風扇轉動的聲音,顯示器上開啟的圖標亮起。之後,只需要靜靜等待幾秒鐘,登錄界面顯示,輸入密碼,即可愉快的玩耍了。
這是我們大概每天都做的事情。那麼中間到底發生了什麼?
簡單地說,從BIOS或者UEFI開始讀取硬碟。接下來,進入bootloader(LILO或者GRUB),bootloader開始載入內核,內核初始化完畢後,緊接著進入用戶空間的初始化。
用戶空間的啟動的第一個進程即pid=1,就是從一個叫init的程式開始的,這也是本文的主角

1. Systemd簡介與使用

1.1. 用戶空間的啟動順序

用戶的空間的大致啟動順序如下:

  • init
  • 基礎底層服務,如udevd(設備管理器),syslogd(日誌管理)
  • 網路配置
  • 中高層服務,如cron(定時器)
  • 登錄提示符(getty)、GUI、mysql(如果設置開機啟動的話)

init是內核啟動的第一個用戶空間進程,主要負責啟動、終止系統中的基礎服務進程。

Linux下,init主要有三個實現版本:

  • System V,傳統的init
  • Upstart,Ubuntu後期針對sys-v的一個改進實現版本
  • systemd,是一套中央化系統及設置管理程式(init),包括有守護進程、程式庫以及應用軟體,相容sys-v。現代大部分桌面版都使用此實現。也是本文主要介紹的一個...emmmm...框架。是的,systemd更像一個服務管理框架。

1.2. SystemV

先說說傳統的SystemV,他其實就是利用一系列腳本來啟動服務,之後的事就撒手不管了。

SystemV init依賴一個特定的啟動順序每次只能啟動執行一個啟動任務。

這些都是通過一個核心配置文件tab(/etc/init)和一組啟動腳本以及符號鏈接集執行的,本質上為系統提供了合理的啟動順序,
支持不同的運行級別。

他的好處是依賴關係簡單,任務之間涇渭分明的一個一個啟動,即使某個基礎服務出了錯也便於排查。但也正因為如此,他的啟動性能很不好。
服務無法並行啟動不說,而且只能按照預先規定的順序啟動服務。如果你安裝了新的硬體或者新服務,他不提供及時支持的標準方法。

time
圖1

我們把用戶空間init的服務分別叫做Job AJob B...圖1可以看到,在SysV init之下,服務必須一個接一個的順序啟動,前面的服務初始化完畢,後面才可以開始。因此,啟動時間就是所有服務啟動時間之和。

他的改進版Upstart在此基礎上就做了優化——互不相關的服務可以並行啟動,這樣啟動總時間就等於時間消耗最大的一組服務,而不是所有服務之和。systemd在並行啟動上採取了比Upstart更加激進的方案

systemd-time
圖2

圖2是systemd的並行啟動方式,他讓配置所有的服務同時啟動。如果Job Aing依賴Job B怎麼辦呢?首先兩個Job是同時啟動的,A如果先啟動,就向B發送請求服務,B會先將請求緩存起來,等到B初始化完畢之後,再處理緩存的請求。
相比SysV init,這也帶來了不確定性,即你不知道此時到底哪些服務起了,哪些沒起,全依賴系統管理

1.2.1. 運行級別

運行級別的概念最早應該也是來自於SysV init.

簡單地說,運行級別定義了系統的特定狀態,這種狀態可以看成一系列服務狀態的集合。

不同的發行版有不同的運行級別,但比較公認的如下:

  • 0,關機
  • 1,單用戶模式(修複模式),如果你的系統涼涼了,這將是你的救命稻草
  • 6,重啟

以我個人的deepin15.7為例,如圖

runlevel
default

其中runlevel2/3/4都屬於同一個運行等級(multi-user),而系統的預設的運行等級為5——graphical。我們平時所用的桌面環境就是這個等級了。其實,現代大部分採用systemd的發行版都和這個大同小異。

我們使用systemctl cat graphical.target打開graphical.target文件,可以看到下麵內容:

[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

其中的Requires=multi-user.target表示,如果想啟動graphical.target(即運行等級5)就必須先啟動multi-user.target(運行等級3).由此可見,在systemd中,運行等級5就是在等級3基礎上,同時啟動一個display-manager服務。display-manage顧名思義,肯定是和圖像顯示有關的咯。

如果你對.target文件,和他的定義語法很迷惑,沒有關係,後面還會詳細解釋。我舉這個例子,只是想讓你瞭解systemd是相容systemV的運行等級概念的。所以,你關於SystemV的認識也是可以繼續沿用的

1.3. Systemd

在Linux中以d結尾的,表示這是一個守護程式,systemd就是這個系統的守護程式

相比於之前的版本,systemd最關鍵的特性是:

  • 延遲啟動某些服務和系統功能,等到需要他們的時候才開啟
  • 完全並行啟動

systemd architecture

systemd 架構圖

1.3.1. systemd啟動步驟

systemd的特性複雜,下麵給出大致的啟動步驟,使我們有個總體觀:

  1. systemd載入配置信息
  2. 判定啟動目標,一般是default.target
  3. 判定啟動目標的依賴關係
  4. 激活依賴服務,啟動目標
  5. 響應系統消息,激活其他組件

1.3.2. 單元和單元類型

systemd不光負責處理進程和服務,同時還能掛載文件系統、監控網路套接字等等。在systemd中
所有服務和功能都被抽象成一個個單元(Unit),根據功能不同,單元類型也不同。systemd正是通過配置這些單元
來開關、管理服務的。

1.3.2.1. 單元類型

比較常用的幾種:

  • 服務單元,傳統的守護進程(XXX.service文件表示)
  • 掛載單元,控制文件系統掛載(XXX.mount文件表示)
  • 目標單元,將服務單元、掛載單元等單元組織在一起的單元,一般對應Sys-V的運行等級(XXX.target文件表示)

上面的尤其是服務單元我們會經常打交道,而且必要時也可以自定義服務單元等。比如我們的藍牙功能就抽象成
blueteeth.service,管理磁碟的udev系統對應systemd-udevd.service文件。如果你安裝了mysql,
還可以找到一個mysql.service文件。

使用deepin15.7的過程中,遇到過一個bug,就是在系統長期休眠之後再重啟,藍牙模塊莫名其妙的關閉了,進入[設置]面板也
無法找到藍牙配置選項了。這時執行systemctl restart blueteeth.service重啟藍牙模塊,大概率就會修複了

除了以上幾種,還有其他類型,比如
socket單元(.socket)、系統設備單元(.device)、交換單元(.swap)、路徑單元(.path)、定時單元(.time),
不一而足

1.3.3. systemd相關指令

1.3.3.1. 電源管理

主要涉及開關、系統重啟等,如果你是當前唯一用戶的話則不需要提權,否則需要root密碼

systemctl reboot #重啟
systemctl poweroff #關機
systemctl suspend #待機
systemctl hibernate #休眠
systemctl rescue #進入單用戶模式

1.3.3.2. 分析系統狀態

主要是查看系統中納入systemd管理的服務的狀態

systemctl status #系統狀態
systemctl list-units #所有激活單元列表
systemctl --failed #運行失敗單元列表

# 列出所有配置文件
$ systemctl list-unit-files

# 列出指定類型的配置文件
$ systemctl list-unit-files --type=service

1.3.3.3. 單元的管理

使用systemd操作單元的激活與關閉

systemctl start <unit> #立即激活單元
systemctl stop <unit> #立即關閉單元
sudo systemctl kill <unit> #前面的stop不好使了,就強行殺死這個單元
systemctl restart <unit> #重啟單元
systemctl status <unit> #單元狀態,這是和好用的指令,能夠看到服務單元的幾乎所有信息

systemctl is-enabled <unit> #單元是否配置自動啟動
systemctl enable <unit># 配置自動啟動單元
systemctl disable <unit>#關閉單元自動啟動

systemctl help <unit>#單元幫助手冊,一般是服務單元

systemctl daemon-reload <unit>#掃描單元配置文件變動,重新載入

systemctl mask <unit> #禁用單元
systemctl unmask <unit>#取消禁用

下麵是我本人電腦上mysql的狀態信息:

systemctl status mysql.service
● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
   Active: active (running)
  Process: 2666 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS)
  Process: 2602 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
 Main PID: 2668 (mysqld)
    Tasks: 27 (limit: 4915)
   Memory: 218.1M
   CGroup: /system.slice/mysql.service
           └─2668 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
  • loaded,單元配置文件地址
  • active:激活狀態
  • process:開啟服務時執行的指令
  • main Pid:主進程ID
  • memory:占用記憶體
  • CGroup:systemd通過CGroup控制進程,這裡展示該服務的所有子進程

1.3.3.4. 單元的依賴列表

systemctl list-depandencies <xxx.service> #列出xxx.service的依賴單元

在systemd中的單元的依賴關係

1.3.3.5. 其他

一些雜七雜八的指令

systemd-analyze #系統啟動時間統計
systemd-analyze blame #查看所有服務啟動時間列表,blame就能看出,這是要等一個背鍋位
localectl #本地化信息
timedatectl #時區信息
loginctl list-user #列出當前登錄用戶

systemd的指令非常豐富,可以通過查詢文檔獲取全部指令

1.4. systemd配置

systemd的配置文件主要分佈在兩個地方:
系統單元目錄(全局配置,我的是/lib/systemd/system)和系統配置目錄(局部配置,我的是/etc/systemd/system)

你可以通過下麵的指令查詢配置目錄:

pkg-config systemd --variable=systemdsystemunitdir #單元目錄
pkg-config systemd --variable=systemdsystemconfdir #配置目錄

其實配置目錄的很多文件都是指向單元目錄的軟鏈接。

單元配置文件就像一個藍圖,定義了一個單元的依賴關係、啟動順序、開啟關閉指令或者掛載點等,
systemd就是讀取這些信息來管理單元的。

1.4.1. Service文件

在systemd中一個.service就是一個服務類型的配置單元,同時也代表了一個服務功能。

我們使用sysctemctl cat ssh.service來查看ssh.service文件內容,該文件就在/lib/systemd/system下.

註:這個Service只有在你安裝openssh-server之後才會有.

[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service

可以看到service文件分為Unit/Service/Install三個區塊,我們分開解釋

1.4.1.1. [Unit]

主要描述啟動順序與依賴關係

[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

Description,一段描述Service的信息

After,表示ssh.servicenetwork.target auditd.service單元之後啟動。另外還有一個屬性Before
表示當前單元在列出的單元之前啟動。比如Before=bar.service,說明當前單元在bar.service之前啟動。
AfterBefore定義了單元之間啟動的順序

ConditionPathExists,表示在後面的路徑存在時返回true,這裡使用了!非運算符,應該是取反的意思。
同樣還有其他幾個路徑判斷條件——ConditionPathIsDirectoryConditionFileNotEmpty,顧名思義,他們的
意義應該不難猜吧。這些條件必須返回為true,否則該單元不會運行

1.4.1.2. [Service]

這個區塊定義如何啟動當前服務

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify

EnvironmentFile,指定當前服務環境參數文件,內部使用鍵值對定義,可以使用$key讀取值,比如後面的$SSHD_OPTS

ExecStartPre,定義啟動服務前執行的指令

ExecStart,定義啟動程式執行的指令

ExecReload,表示重啟服務時執行的命令。其他的諸如ExecStop等等,望文生義即可

KillMode,定義 Systemd 如何停止 sshd 服務,process表示當kill sshd服務的時候,僅殺死主進程,子進程還是留著的。
其他的kill模式還有:

  • control-group(預設值):當前控制組裡面的所有子進程,都會被殺掉
  • mixed:主進程將收到 SIGTERM 信號,子進程收到 SIGKILL 信號
  • none:沒有進程會被殺掉,只是執行服務的 stop 命令

Restart欄位,定義了 sshd 退出後,Systemd 的重啟方式。on-failure,表示任何意外的失敗,就將重啟sshd。
另外還有其他重啟模式定義:

  • no(預設值):退出後不會重啟
  • on-success:只有正常退出時(退出狀態碼為0),才會重啟
  • on-abnormal:只有被信號終止和超時,才會重啟
  • on-abort:只有在收到沒有捕捉到的信號終止時,才會重啟
  • on-watchdog:超時退出,才會重啟
  • always:不管是什麼退出原因,總是重啟

最後一個比較重要的是Type欄位,定義啟動類型。notify,表示啟動結束後會發出通知信號,然後 Systemd 再啟動其他服務。
其他的類型如下:

  • simple(預設值):ExecStart欄位啟動的進程為主進程
  • forking:ExecStart欄位將以fork()方式啟動,此時父進程將會退出,子進程將成為主進程
  • oneshot:類似於simple,但只執行一次,Systemd 會等它執行完,才啟動其他服務
  • dbus:類似於simple,但會等待 D-Bus 信號後啟動

1.4.1.3. [Install]

定義如何安裝這個配置文件,即怎樣做到開機啟動

WantedBy欄位:表示該服務所在的Target。
Target的含義是服務組,表示一組服務。WantedBy=multi-user.target指的是,sshd 所在的 Target 是multi-user.target。

systemctl enable sshd.service其實就是將sshd服務的鏈接放在multi-user.target.wants目錄下。
同時multi-user.target是系統的預設target,在啟動該target的時候,他下麵的服務都會開機啟動。
這也就是只要掛上multi-user.target就能開機啟動的原因

1.4.2. target文件

執行systemctl cat multi-user.target,可得:

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

target文件只是組織一批服務,因此他沒有[service]、[mount]等定義啟動或者掛載的區塊

Requires,表示強依賴關係,即必須要求basic.target啟動,否則multi-user啟動失敗。
其他的依賴關係如下:

  • Wants,只用於激活依賴,沒有強依賴關係,該服務沒起來也不影響當前服務
  • Conflicts,衝突關係,有我沒他,否則不能運行
  • Requisite,前置依賴,當前單元激活前,必須激活它,否則失敗,屬於強依賴

Wants是比較重要的依賴關係,他不會將啟動錯誤擴散給其他單元。systemd文檔鼓勵我們多用Wants關係

AllowIsolate,表示允許使用systemctl isolate命令切換到multi-user.target

1.5. systemd日誌服務

systemd 自帶日誌服務 journald,該日誌服務的設計初衷是剋服現有的 syslog 服務的缺點。

  • syslog 不安全,消息的內容無法驗證
  • 數據沒有嚴格的格式,非常隨意

Systemd Journal 用二進位格式保存所有日誌信息,用戶使用 journalctl 命令來查看日誌信息。無需自己編寫複雜脆弱的字元串分析處理程式。

常見的指令如下:

# 查看所有日誌(預設情況下 ,只保存本次啟動的日誌)
$ sudo journalctl

# 查看內核日誌(不顯示應用日誌)
$ sudo journalctl -k

# 查看系統本次啟動的日誌
$ sudo journalctl -b
$ sudo journalctl -b -0

# 查看上一次啟動的日誌(需更改設置)
$ sudo journalctl -b -1

# 查看指定時間的日誌
$ sudo journalctl --since="2012-10-30 18:17:16"
$ sudo journalctl --since "20 min ago"
$ sudo journalctl --since yesterday
$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$ sudo journalctl --since 09:00 --until "1 hour ago"

# 顯示尾部的最新10行日誌
$ sudo journalctl -n

# 顯示尾部指定行數的日誌
$ sudo journalctl -n 20

# 實時滾動顯示最新日誌
$ sudo journalctl -f

# 查看指定服務的日誌
$ sudo journalctl /usr/lib/systemd/systemd

# 查看指定進程的日誌
$ sudo journalctl _PID=1

# 查看某個路徑的腳本的日誌
$ sudo journalctl /usr/bin/bash

# 查看指定用戶的日誌
$ sudo journalctl _UID=33 --since today

# 查看某個 Unit 的日誌
$ sudo journalctl -u nginx.service
$ sudo journalctl -u nginx.service --since today

# 實時滾動顯示某個 Unit 的最新日誌
$ sudo journalctl -u nginx.service -f

# 合併顯示多個 Unit 的日誌
$ journalctl -u nginx.service -u php-fpm.service --since today

# 查看指定優先順序(及其以上級別)的日誌,共有8級
# 0: emerg
# 1: alert
# 2: crit
# 3: err
# 4: warning
# 5: notice
# 6: info
# 7: debug
$ sudo journalctl -p err -b

# 日誌預設分頁輸出,--no-pager 改為正常的標準輸出
$ sudo journalctl --no-pager

# 以 JSON 格式(單行)輸出
$ sudo journalctl -b -u nginx.service -o json

# 以 JSON 格式(多行)輸出,可讀性更好
$ sudo journalctl -b -u nginx.serviceqq
 -o json-pretty

# 顯示日誌占據的硬碟空間
$ sudo journalctl --disk-usage

# 指定日誌文件占據的最大空間
$ sudo journalctl --vacuum-size=1G

# 指定日誌文件保存多久
$ sudo journalctl --vacuum-time=1years

1.6. 在systemd中添加單元

關於自定義單元的首要一點建議:不要更改/lib/systemd/system(系統單元目錄),他由系統維護。
我們一般在/etc/systemd/system下自定義啟動單元。

1.6.1. 寫一個小慄子

  • 創建一個名為test1.target的單元
[Unit]
Description=test 1
  • 創建test2.target,依賴與test1
[Unit]
Description=test 2
Wants=test1.target
  • 激活test2.target,test1作為依賴也會被激活

systemctl start test2.target

  • 驗證兩個是否都被激活

systemctl status test1.target test2.target

註:如果單元內包含[Install]模塊,需要在start前enable他.
systemctl enable <unit>

  • 刪除單元
systemctl stop <unit> #首先停止單元
systemctl disable <unit> #如果有[Install]模塊,則刪除連接符號
#最後刪除單元文件即可

1.7. systemd 的按需和資源並行啟動

這是一個很複雜的概念,最好單獨討論

1.8. 參考


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

-Advertisement-
Play Games
更多相關文章
  • " 【.NET Core項目實戰 統一認證平臺】開篇及目錄索引 " 上篇文章我介紹瞭如何在網關上增加自定義客戶端授權功能,從設計到編碼實現,一步一步詳細講解,相信大家也掌握了自定義中間件的開發技巧了,本篇我們將介紹如何實現自定義客戶端的限流功能,來進一步完善網關的基礎功能。 .netcore項目實戰 ...
  • ASP.NET -- WebForm -- Cookie的使用 Cookie是存在瀏覽器記憶體或磁碟上。 1. Test3.aspx文件 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test3.aspx.cs" Inherits="T ...
  • Linux文件類型和Linux文件的文件名所代表的意義是兩個不同的概念。我們通過一般應用程式而創建的比如file.txt、file.tar.gz ,這些文件雖然要用不同的程式來打開,但放在Linux文件類型中衡量的話,大多是常規文件(也被稱為普通文件)。 一. 文件類型 Linux文件類型常見的有: ...
  • master資料庫已投入生產一段時間後,做主從複製的操作記錄 環境: master庫:172.18.237.13slave庫:172.18.237.14 mysql版本說明: master:mysql 5.6.33 slave:mysql 5.6.35 我到公司的時候已經裝了5.6.33版本,找了很 ...
  • 1.Linux修改管理員密碼:打開終端:1. 重啟 2.進入內核登陸系統點擊e3.進入系統救援界面,定位Linux16所在行,找到ro 後刪除,在此位置添加一條命令: 4.點擊Ctrl + x進入內核編輯界面5.輸入: 6.輸入: 來設置語言格式7.輸入: 後輸入2次密碼8.輸入: 讓密碼生效9.點 ...
  • 這是一篇介紹如何用樹莓派使用PN532的隨筆,介紹了具體的使用步驟。 首先介紹一下: ①、IC卡是非接觸式的智能卡,裡面一般是一個方形線圈和一個小晶元(用強光照著可以看到)。M1卡是IC卡的一種,一般水卡、公交卡都是這種。UID卡是M1的複製子卡,與M1完全相容。M1卡0扇區的內容可讀不可寫,UID ...
  • 恢復內容開始 1.使用yum安裝 2.創建倉庫 1.創建成功後在svn下麵多了幾個文件夾。 2.特別關註一下conf文件夾,這個是存放配置文件的 3.配置passwd 賬號密碼 4.配置authz 許可權 5.配置svnserve.conf 5.啟動與停止 6.連接測試 這裡使用TortoiseSVN ...
  • 老夫生於上世紀五十年代,作為八零後的大叔,九零後的老伯,同時也是你們動輒就要重裝的操作系統,我的學名是“電腦管理控製程序”,英譯“operating system”,小老弟們常喊我“OS”。雖說是老弟,目的卻都不怎麼單純,大部分人只想玩我,剩下一小撮人卻鐘愛探索我的身體,他們沉迷於當下,但真正願意... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...