2021年12月12日 星期日

rocketMQ 4.x

下載點

文件

控制台:就是有畫面可以操作


※啟動注意事項

此文章使用的是 Windows 的 rocketMQ,使用 java8 可以跑得起來,但不能安裝在有空格的路徑,如 Program Files,網上有說用字串包起來可以解決,但我試不成功,但可以用 PROGRA~1 解決

9 10 不是 LTS 版,我沒試過,而 11 會出現 JVM 參數已經沒有的問題,會跑不起來,雖然網路上也有將沒有的 JVM 參數註解掉,但我試還是不成功

windows 要執行副檔名是 cmd 的;linux 要執行 sh 的

mqnamesrv.cmd 啟動 name server,內部會執行 runserver.cmd

mqbroker.cmd 啟動 broker,內部會執行 runbroker.cmd

以上這兩個用文件編輯器可打開查看,其中需要 ROCKETMQ_HOME 變數,所以要設環境變數

-Xms2g -Xmx2g 可以設小一點,設 256m 就夠測試了

我設的是 ROCKETMQ_HOME=C:\Users\bruce\Downloads\rocketmq-4.9.2,要在 bin 的上一層,最後在放到 path 裡,然後後面加上 bin

然後先啟動 name server,後啟動 broker,啟動成功畫面如下:


以上的命令可在官網的文件複製


※測試生產消費

啟好了之後,試試能不能生產和消費,官網說要設定 NAMESRV_ADDR="localhost:9876"

所以再開啟命令提示字元,set NAMESRV_ADDR=localhost:9876,官網前後有字串,但我試的結果不行,注意 set 設定的變數只有在這個視窗有效,要永久就要在環境變數裡設定

設定好之後,tools.cmd  org.apache.rocketmq.example.quickstart.Producer 就會看到畫面一直跑,

接著是消費者,再開一個命令提示字元,如果變數是暫時的,還要在設定 NAMESRV_ADDR,打上 tools.cmd  org.apache.rocketmq.example.quickstart.Consumer,就會看到開始消費了



※啟動主控台

就是這文章最上面的控制台,使用 ide 打開後,可改兩個地方,如下:


rocketmq.config.namesrvAddr 要設定 name server 的地址; server.port 可以改成這個主控台想要的 port

server.port 預設是 8080;rocketmq.config.namesrvAddr 預設是 localhost:9876

然後下 mvn clean package -Dmaven.test.skip=true,成功後會在 target 裡生成一個 jar

執行這個 jar,java -jar xxx.jar 即可啟動,在瀏覽器打上 localhost:8080


看到這畫面表示成功了啟動了,再生產一次資料後,可在 Message 活頁標籤裡搜尋 Topic 是   TopicTest 的,可以看到生產的資料


※關閉 name server 和 broker

和啟動相反,先關閉 broker,再關閉 name server

mqshutdown.cmd broker

mqshutdown.cmd namesrv 



※broker 的雙主雙從等

在 rocketMQ 目錄有個 conf,裡面有三個資料夾

2m-2s-async:雙主雙從加異步

2m-2s-sync:雙主雙從加同步

2m-noslave:雙主

在啟動 broker 時可以加上 -c 的參數,後面加檔案路徑,就可以抓到裡面的設定,但裡面的設定還不是很多,可到官網查看


※Message

這個是傳訊息要用到的 class

tag 可以再 topic 裡在過濾一層,如生產時 topic 是 animal,tag 有 cat、dog…等,消費者可以針對某一個 tag 進行過濾,如 tag 給 dog,就只抓 dog,給 * 會全抓

key 是用戶端自己生成的,可以把它寫成唯一 id



※持久化資料

windows 在 %userProfile%\store

commitlog:真正存資料的地方,預設一個檔案 1G

consumequeue:用 topic 區分,連到 commitlog 的索引,消費者群組來這裡找資料的

index:如果在生產時有給 key 就可以利用這個 key 和時間區間來找資料



※Queue 數量

預設的數量是 4,可以使用 producer.setDefaultTopicQueueNums 修改,但如果已經有 topic 改不了,所以是 setDefault,因為資料在讀或寫的時候,更改這個值會有影響,要用下面要說的 writeQueueNums 和 readQueueNums 

已經有 topic,可以刪除或修改,但要在控制台操作,如下:

每個橫條都是一個 topic,最右的按鈕可以刪除 topic

status 按鈕可以看有幾個 queue

topic config 按鈕可以修改幾個 queue,如下:


perm 有三種值 2 4 6,分別是可寫可讀可讀寫

writeQueueNums 是 Queue 的數量,改好可到 status 查看

通常 writeQueueNums 和 readQueueNums 都是設成一樣的,只有在擴容或縮容時才會不一樣

假設 writeQueueNums 4; readQueueNums 8 會有 4 個消費者消費不到,想擴容時可暫時這樣設定

假設 writeQueueNums 8; readQueueNums 4 會有 4 個 queue 沒有消費,想縮容時可暫時這樣設定


※消費者組、主題、tag

當設定完消費者組、主題、tag 後,消費者組就會開始監聽,但只要同一個消費者組,不管主題、tag 是什麼都會收到資料,所以有可能收錯資料,而另一個資料丟失

正確的做法是消費者組、主題、tag 都要一樣,要訂閱不同主題時,也要用新的消費者組



※刷盤和複製策略

在下載好的 rocketmq\conf\broker.conf 有如下的設定

brokerRole = ASYNC_MASTER,表示異步複製,改同步只要去掉 A 即可,而 SLAVE 是接受方

flushDiskType = ASYNC_FLUSH,表示異步刷盤,改同步只要去掉 A 即可

這兩個預設都是異步的


複製策略

brokerRole 表示 MASTER 複製給 SLAVE 用什麼方式

1. ASYNC_MASTER 消息在記憶體並寫到 master 的硬碟後就回應,然後再寫到 slave

所以在還沒寫到硬碟時,忽然網路延遲或斷電,但生產者會以為已經送到 broker 了,這時會造成 slave 資料丟失

2. SYNC_MASTER 收到消息並寫到 master 和 slave 的硬碟後才回應已完成

3. SLAVE 接收 MASTER 的資料


刷盤策略

flushDiskType 表示消息在記憶體,寫入硬碟的方式

1. ASYNC_FLUSH 消息在記憶體就回應,然後再寫到碟碟

所以忽然網路延遲或斷電,就會認為沒有刷盤成功,然後再送出資料給消費者,造成消息重覆

2. SYNC_FLUSH 記憶體寫到硬碟後再回應



※Queue 和消費者

1.同個消費者組下的消費者可以消費同個主題的不同 queue;但同個主題的同個 queue 不能被多個消費者消費


如果想一個 queue 對應一個消費者,在 spring boot 裡,可以用

@RocketMQMessageListener(

    consumerGroup = "myConsumerGroup",

    topic = "myTopic",

    selectorExpression = "myTag",

    consumeMode = ConsumeMode.ORDERLY,

    consumeThreadMax = 1)

ConsumeMode.ORDERLY 表示一個 queue 對應一個消費者,注意原碼的註解 one queue, one thread,並不是指一個 thread,要指定一個 thread 要用下面的 consumeThreadMax = 1

consumeThreadMax 的數量是指藍色的線



2.不同消費者組下的消費者可以同時消費同個主題的同個 queue




3.同個消費者組下的消費者不可以同時消費不同 topic 的 queue






2021年12月10日 星期五

Mongodb

 官網連結


enterprise 需要錢,community 不用錢

下載解壓安裝,安裝過程會問要不要再安裝 compass,這個是 gui 工具,看要不要安裝或者安裝自己熟悉的 gui 工具,mongodb://127.0.0.1:27017 可以連自己的,但下面的 mongod 要執行成功

完成後,看要不要設定環境變數

啟動用 mongod,但會出現錯誤,說路徑要有 c:\data\db,自行創建後,啟動成功

或者用參數  mongod --dbpath 資料夾路徑名,這樣就可以使用自己喜歡的資料夾

port 預設是 27017,想改可用 mongod --port 2222,這要就可以改 port

然後再開一個視窗,打上 mongo 或 mongo --port 27017 即可連線,出現「>」表示連現成功


database 資料庫

collection 集合

document 文件

資料庫和集合不用手動創建,直接 use 名稱即可,在新增文件時,會自動新增資料庫和文件

show dbs 或 shw databases 看有什麼資料庫

db 看目前在哪個資料庫

show collections 或 show tables看當前資料庫有什麼集合


官方開發文件

新增文件 db.<collection>.insertOne   insertMany

 db.zoo.insertOne(name:"monkey");  zoo 是這行才開始新增的 collection,如果資料庫沒新增也會一併新增,insertOne 裡的 bson 就是 document

其他 deleteOne、deleteMany、updateOne、updateMany、find 都看官方文件即可


※NoSQLBooster for MongoDB

這也是個 IDE


projection 是投影的意思,在這裡表示哪些欄位要顯示,1顯示,0不顯示

另一種方法是將 document 寫在 find 的第二個參數裡,這樣就不用寫 projection 了



※索引

預設 _id 是 PK,就已經是索引了

db.<collection>.createIndex(

  { field1: 1 } ,

  { field2: -1 }

);

對 field1 做正序,對 field2 做倒序

查看 index: db.<collection>.getIndexes();


如圖,表示有兩個索引,key 為索引的欄位名稱,第二個是我建的複合索引


查看執行計畫,官方文檔

db.<collection>.explain("queryPlanner");

裡面可以寫三種值 queryPlanner、executionStats、allPlansExecution

看結果的 winningPlan,有個 stage,如下


stage 包括五種

COLLSCAN:掃描 collection,全表掃描的意思

IXSCAN:掃描 index,表示吃到索引了

FETCH:用於檢索文件

SHARD_MERGE:用於合併分片的結果

SHARDING_FILTER:用於從分片中過濾掉孤立文件