搭建MongoDB副本集

来源:https://www.cnblogs.com/misakivv/p/18166888
-Advertisement-
Play Games

目錄一、什麼是MongoDB的副本集二、副本集的架構三、副本集的成員四、部署副本集1、節點劃分2、安裝MongoDB2.1、下載解壓安裝包3、創建主節點3.1、創建存儲數據和日誌的目錄3.2、新建配置文件3.3、啟動節點服務4、創建副本節點4.1、創建存儲數據和日誌的目錄4.2、新建配置文件4.3、 ...


目錄

一、什麼是MongoDB的副本集

MongoDB的副本集(Replica Set)是一種提供數據冗餘和高可用性的架構。它是由多個維護相同數據集的mongod進程(即資料庫實例)組成的一個集合,這些實例分佈在不同的伺服器上。

副本集的設計目標是為了確保在單個伺服器發生故障時,資料庫服務依然可以繼續運作,從而提高了系統的可靠性和容錯能力。

二、副本集的架構

  • 一個副本集最多有50個節點。一個副本集最多有7個投票節點,其餘節點必須是沒有投票權的節點。

  • 副本集的最小推薦配置是三個節點:

    • 一個主節點和兩個從節點。
    • 一個主節點、一個從節點和仲裁節點。

2270526-20220923193134773-2055031891

2270526-20220923185546781-845092680

三、副本集的成員

副本集有兩種類型三種角色

  • 兩種類型

    • 主節點(Primary)類型:數據操作的主要連接點,可讀寫

    • 次要(輔助、從)節點(Secondaries)類型:數據冗餘備份節點,可以讀或選舉

  • 三種角色

    • 主要成員(Primary):主要接收所有寫操作。就是主節點。

    • 副本成員(Replicate):從主節點通過複製操作以維護相同的數據集,即備份數據,不可寫操作,但可以讀操作(但需要配置)。是預設的一種從節點類型

    • 仲裁者(Arbiter):不保留任何數據的副本,只具有投票選舉作用,當然也可以將仲裁伺服器維護為副本集的一部分,即副本成員同時也可以是仲裁者。也是一種從節點類型。

  • 建議

    • 如果你的副本+主節點的個數是偶數,建議加一個仲裁者,形成奇數,容易滿足大多數的投票。

    • 如果你的副本+主節點的個數是奇數,可以不加仲裁者。

四、部署副本集

u=3763007939,3474838561&fm=253&fmt=auto&app=138&f=PNG

1、節點劃分

一臺機器上部署三個mongodb節點

角色
27017 主節點
27018 副本節點
27019 仲裁節點

2、安裝MongoDB

2.1、下載解壓安裝包

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.6.tgz
tar xzvf mongodb-linux-x86_64-rhel70-4.4.6.tgz -C /usr/local
cd /usr/local/
ln -s /usr/local/mongodb-linux-x86_64-rhel70-4.4.6 /usr/local/mongodb

3、創建主節點

3.1、創建存儲數據和日誌的目錄

mkdir -p /usr/local/mongodb/replica_sets/myrs_27017/log
mkdir -p /usr/local/mongodb/replica_sets/myrs_27017/data/db

3.2、新建配置文件

vim /usr/local/mongodb/replica_sets/myrs_27017/mongod.conf

systemLog:
    destination: file
    path: "/usr/local/mongodb/replica_sets/myrs_27017/log/mongod.log"
    logAppend: true
storage:
    dbPath: "/usr/local/mongodb/replica_sets/myrs_27017/data/db"
    journal:
    # 啟用持久性日誌
        enabled: true
processManagement:
    fork: true
    pidFilePath: "/usr/local/mongodb/replica_sets/myrs_27017/log/mongod.pid"
net:
    bindIp: localhost,192.168.112.40
    port: 27017
replication:
    replSetName: myrs

3.3、啟動節點服務

[root@localhost local]# /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27017/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 8177
child process started successfully, parent exiting

4、創建副本節點

4.1、創建存儲數據和日誌的目錄

mkdir -p /usr/local/mongodb/replica_sets/myrs_27018/log
mkdir -p /usr/local/mongodb/replica_sets/myrs_27018/data/db

4.2、新建配置文件

vim /usr/local/mongodb/replica_sets/myrs_27018/mongod.conf

systemLog:
    destination: file
    path: "/usr/local/mongodb/replica_sets/myrs_27018/log/mongod.log"
    logAppend: true
storage:
    dbPath: "/usr/local/mongodb/replica_sets/myrs_27018/data/db"
    journal:
        enabled: true
processManagement:
    fork: true
    pidFilePath: "/usr/local/mongodb/replica_sets/myrs_27018/log/mongod.pid"
net:
    bindIp:  localhost,192.168.112.40
    port: 27018
replication:
    replSetName: myrs

4.3、啟動節點服務

[root@localhost ~]# /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27018/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 18263
child process started successfully, parent exiting

5、創建仲裁節點

5.1、創建存儲數據和日誌的目錄

mkdir -p /usr/local/mongodb/replica_sets/myrs_27019/log
mkdir -p /usr/local/mongodb/replica_sets/myrs_27019/data/db

5.2、創建配置文件

vim /usr/local/mongodb/replica_sets/myrs_27019/mongod.conf

systemLog:
    destination: file
    path: "/usr/local/mongodb/replica_sets/myrs_27019/log/mongod.log"
    logAppend: true
storage:
    dbPath: "/usr/local/mongodb/replica_sets/myrs_27019/data/db"
    journal:
    # 啟用持久性日誌
        enabled: true
processManagement:
    fork: true
    pidFilePath: "/usr/local/mongodb/replica_sets/myrs_27019/log/mongod.pid"
net:
    bindIp:  localhost,192.168.112.40
    port: 27019
replication:
    replSetName: myrs

5.3、啟動節點服務

[root@localhost ~]# /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27019/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 18314
child process started successfully, parent exiting

6、添加環境變數

vim /etc/profile

export PATH=/usr/local/mongodb/bin/:$PATH

source /etc/profile
[root@localhost ~]# which mongo
/usr/local/mongodb/bin/mongo

7、初始化副本集

7.1、客戶端連接主節點

mongo --host 192.168.112.40 --port=27017

7.2、初始化副本集

當前並未選舉主節點(primary),並且操作沒有設置為允許從輔助節點(secondary)上讀取。

所以很多命令無法使用,必須初始化副本集

> show dbs
uncaught exception: Error: listDatabases failed:{
        "topologyVersion" : {
                "processId" : ObjectId("662f9e53d74e84faba8865bc"),
                "counter" : NumberLong(0)
        },
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotPrimaryNoSecondaryOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1

初始化副本集

> rs.initiate()
{
        "info2" : "no configuration specified. Using a default configuration for the set",
        "me" : "192.168.112.40:27017",
        "ok" : 1
}
myrs:SECONDARY>

image-20240429215626296

  • "ok"的值為1,說明創建成功。

  • 命令行提示符發生變化,變成了一個從節點角色,此時預設不能讀寫。

  • 稍等片刻,發現副本集只有自己一個,變成主節點。

8、查看副本集配置信息

myrs:PRIMARY> rs.conf()
{
        "_id" : "myrs",
        "version" : 1,
        "term" : 1,
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.112.40:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatIntervalMillis" : 2000,
                "heartbeatTimeoutSecs" : 10,
                "electionTimeoutMillis" : 10000,
                "catchUpTimeoutMillis" : -1,
                "catchUpTakeoverDelayMillis" : 30000,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("662fa69cd74e84faba8865e0")
        }
}
  • "_id" : "myrs" :副本集的配置數據存儲的主鍵值,預設就是副本集的名字

  • "members" :副本集成員數組,此時只有一個:"host" : "192.168.112.40:27017"

  • 該成員不是仲裁節點: "arbiterOnly" : false

  • 優先順序(權重值): "priority" : 1

  • "settings" :副本集的參數配置。

9、添加副本節點和仲裁節點

添加副本節點

myrs:PRIMARY> rs.add("192.168.112.40:27018")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1714399646, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1714399646, 1)
}

添加仲裁節點

myrs:PRIMARY> rs.addArb("192.168.112.40:27019")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1714399738, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1714399738, 1)
}

10、再次查看副本集配置信息

myrs:PRIMARY> rs.conf()
{
        "_id" : "myrs",
        "version" : 3,
        "term" : 1,
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.112.40:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "192.168.112.40:27018",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "192.168.112.40:27019",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatIntervalMillis" : 2000,
                "heartbeatTimeoutSecs" : 10,
                "electionTimeoutMillis" : 10000,
                "catchUpTimeoutMillis" : -1,
                "catchUpTakeoverDelayMillis" : 30000,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("662fa69cd74e84faba8865e0")
        }
}
  • 成員信息:
    • 成員1(_id: 0)和成員2(_id: 1)都是數據承載節點,它們位於同一臺機器的不同埠(27017 和 27018)。兩者都有相同的優先順序("priority" : 1),意味著它們都可以成為主節點。它們都沒有延遲複製("slaveDelay" : NumberLong(0)),並且都參與選舉投票("votes" : 1)。
    • 成員3(_id: 2)是一個仲裁者(arbiterOnly: true),位於埠27019。仲裁者的角色是在選舉新主節點時起到決定性的一票作用,但它不存儲實際數據,也沒有優先順序,不參與數據複製。

11、設置副本節點可讀

rs.slaveOk()

五、測試副本集的數據讀寫操作

1、主節點測試

[root@localhost ~]# mongo --port 27017

myrs:PRIMARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
myrs:PRIMARY> use test1
switched to db test1
myrs:PRIMARY> db.q1.insert({"id":"1000","content":"學習部署副本集","userid":"001","name":"zhangsan","createdatatime":new Date(),"state":null})
WriteResult({ "nInserted" : 1 })
myrs:PRIMARY> db.q1.find().pretty()
{
        "_id" : ObjectId("662fb0d727a6cea3c847b26e"),
        "id" : "1000",
        "content" : "學習部署副本集",
        "userid" : "001",
        "name" : "zhangsan",
        "createdatatime" : ISODate("2024-04-29T14:38:15.243Z"),
        "state" : null
}

2、副本節點測試

[root@localhost ~]# mongo --port 27018

myrs:SECONDARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test1   0.000GB
myrs:SECONDARY> use test1
switched to db test1
myrs:SECONDARY> show tables;
q1
myrs:SECONDARY> db.q1.find().pretty()
{
        "_id" : ObjectId("662fb0d727a6cea3c847b26e"),
        "id" : "1000",
        "content" : "學習部署副本集",
        "userid" : "001",
        "name" : "zhangsan",
        "createdatatime" : ISODate("2024-04-29T14:38:15.243Z"),
        "state" : null
}
myrs:SECONDARY> db.q1.insert({"id":"1001","content":"學習部署副本集","userid":"002","name":"lisi","createdatatime":new Date(),"state":null})
WriteCommandError({
        "topologyVersion" : {
                "processId" : ObjectId("662fa148dfb1efa1f75795c3"),
                "counter" : NumberLong(4)
        },
        "operationTime" : Timestamp(1714402027, 1),
        "ok" : 0,
        "errmsg" : "not master",
        "code" : 10107,
        "codeName" : "NotWritablePrimary",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1714402027, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
})
  • 無法寫入數據

    • "errmsg" : "not master"

    • "codeName" : "NotWritablePrimary"

2.1、設置副本節點只能作為備份不能讀取

#設置從節點有讀取許可權
rs.slaveOk()
# 取消從節點的數據讀取許可權
rs.slaveOk(false)

3、仲裁節點不存放任何數據

[root@localhost ~]# mongo --port 27019

myrs:ARBITER> show dbs
uncaught exception: Error: listDatabases failed:{
        "topologyVersion" : {
                "processId" : ObjectId("662fa25360629ad0a0f05cc1"),
                "counter" : NumberLong(1)
        },
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotPrimaryNoSecondaryOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
myrs:ARBITER> rs.slaveOk()
WARNING: slaveOk() is deprecated and may be removed in the next major release. Please use secondaryOk() instead.
myrs:ARBITER> show dbs
uncaught exception: Error: listDatabases failed:{
        "topologyVersion" : {
                "processId" : ObjectId("662fa25360629ad0a0f05cc1"),
                "counter" : NumberLong(1)
        },
        "ok" : 0,
        "errmsg" : "node is not in primary or recovering state",
        "code" : 13436,
        "codeName" : "NotPrimaryOrSecondary"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1

"errmsg" : "node is not in primary or recovering state"

仲裁節點(Arbiter)在MongoDB副本集中僅用於選舉過程中的投票,並不存儲數據

六、主節點的選舉原則

1、主節點選舉觸發條件

  • MongoDB在副本集中,會自動進行主節點的選舉,主節點選舉的觸發條件

    • 主節點故障

    • 主節點網路不可達(預設心跳信息為10秒)

    • 人工干預(rs.stepDown(600))primary直接降級在600s內不會把自己選為primary

  • 一旦觸發選舉,就要根據一定規則來選擇主節點。

2、選舉規則

  • 選舉規則是根據票數來決定誰獲勝

    • 票數最高,且獲得了“大多數”成員的投票支持的節點獲勝。

    • "大多數"的定義為:假設複製集內投票成員時N,則大多數為N/2+1。例如:3個投票成員,則大多數的值是2。當複製集記憶體活成員數量不足大多數時,整個複製集將無法選舉primary,複製集將無法提供寫服務,處於只讀狀態。

    • 若票數相同,且都獲得了“大多數”成員的投票支持的,數據新的節點獲勝。

    • 數據的新舊是通過操作日誌oplog來對比的。

  • 在獲得票數的時候,優先順序(priority)參數影響重大。

  • 可以通過設置優先順序(priority)來設置額外票數。優先順序即權重,取值為0-1000,相當於增加0-1000的票數,優先順序的值越大,就越可能獲得多數成員的投票(votes)數。指定較高的值可使成員更有資格成員主要成員,更低的值可使成員更不符合條件。

  • 預設情況下,優先順序的值是1

七、集群故障分析

1、主節點故障

  • 從節點和仲裁節點對主節點的心跳失敗,當失敗超過10秒,此時因為沒有主節點了,會自動發起投票。
    • 而副本節點只有一臺,因此,候選人只有一個就是副本節點,開始投票。
    • 仲裁節點向副本節點投了一票,副本節點本身自帶一票,因此共兩票,超過了"大多數"。
    • 27019是仲裁節點,沒有選舉權,27018不向其投票,其票數是0。
    • 最終結果,27018成為主節點。具備讀寫功能。
  • 再啟動 27017主節點,發現27017變成了從節點,27018仍保持主節點。
  • 登錄27017節點,發現是從節點了,數據自動從27018同步。
  • 此時:不影響正常使用

2、副本節點故障

  • 主節點和仲裁節點對副本節點的心跳失敗。因為主節點還在,因此,沒有觸發投票選舉。
    如果此時,在主節點寫入數據。再啟動從節點,會發現,主節點寫入的數據,會自動同步給從節點。
  • 此時:不影響正常使用

3、仲裁節點故障

  • 主節點和副本節點對仲裁節點的心跳失敗。因為主節點還在,因此,沒有觸發投票選舉。
  • 此時:不影響正常使用

4、主節點和仲裁節點故障

副本集中沒有主節點了,導致此時,副本集是只讀狀態,無法寫入。

因為27017的票數,沒有獲得大多數,即沒有大於等於2,它只有預設的一票(優先順序是1)
如果要觸發選舉,隨便加入一個成員即可。

  • 如果只加入 27019仲裁節點成員,則主節點一定是27017,因為沒得選了,仲裁節點不參與選舉,但參與投票。
  • 如果只加入 27018節點,會發起選舉。因為27017和27018都是兩票,則按照誰數據新,誰當主節點。

此時:影響正常使用,需要處理

5、從節點和仲裁節點故障

10秒後,27017主節點自動降級為副本節點。(服務降級)
副本集不可寫數據了,已經故障了。

此時:影響正常使用,需要處理

6、主節點和從節點故障

集群將處於不完全狀態,無法執行寫操作,因為剩餘的副本節點不足以立即選出新的主節點(假設只剩一個副本節點和仲裁節點)。直到至少有一個額外的副本節點線上並同步,以便選舉出新的主節點

此時:影響正常使用,需要處理

7、所有節點故障

  • 整個集群不可用,既不能執行讀也不能執行寫操作。

  • 這種情況需要手動干預,逐一排查並恢復各個節點,確保至少一個主節點和多數節點(包括仲裁節點)線上,以恢復集群服務。

  • 此時:影響正常使用,需要處理


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

-Advertisement-
Play Games
更多相關文章
  • 目錄通用許可權的管理擴展許可權的管理特殊許可權的管理許可權掩碼 在Linux中,許可權管理是通過文件系統中的許可權位來實現的。 通用許可權的管理 每個文件或目錄都有一個所有者、一個用戶組和其他用戶的許可權設置。主要的許可權包括讀取、寫入和執行。 文件許可權包括讀、寫和執行許可權: 讀許可權(r):允許用戶讀取文件的內容或列 ...
  • 在開始主題之前,先介紹一個刷固件工具。這個工具在 idf 中是集成的,不過,樂鑫也單獨發佈了這個工具—— esptool。下載鏈接:Releases · espressif/esptool · GitHub。這貨是用 Python 寫的,只是封裝成了 exe,方便直接運行罷了。 在使用時,需要 -p ...
  • 哈嘍大家好,我是鹹魚。(博客網址: https://xxxsalted.github.io/) 在搭建了博客並換了主題之後,發現有許多細節方面的東西還需要完善和定製化一下,比如說行距和引用的樣式我不是很喜歡,以及沒有評論功能。 於是決定自己動手,說乾就乾。 PS:下文的修改操作僅限於博客主題(Kli ...
  • Everything is a file 是一個經典的概念。Linux系統將所有的東西都看作是文件,包括將硬體設備、進程、網路連接等均抽象為文件。 ...
  • 一:kvm工具棧 kvm主要的工具棧,從大的類別可以分為libvirt和qemu這2大類,其中libvirt中分為virtual machine manager和virsh ,virtual machine manager中的virt-manager是基於圖形化界面的管理,其他的都是可以在命令直接使 ...
  • 痞子衡嵌入式半月刊: 第 98 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
  • 目錄Linux學習大綱命令提示符命令的格式路徑的分類文件的分類目錄的結構一些快捷鍵 Linux學習大綱 命令提示符 通常情況下,我們使用Linux都是在命令行環境下, 所以學習 Linux 的第一步需要瞭解 Linux 的命令提示符。 Linux命令提示符通常由用戶名、主機名和當前工作目錄組成。 [ ...
  • 1、下載必備安裝包 make、gcc(debian中可用build-essential包)、bc、linux-headers-$(uname -r)、dkms sudo apt install build-essential bc sudo apt install linux-headers-$(u ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...