今日主題: RabbitMQ
-
RabbitMQ 的使用場景有哪些?
- 搶購活動,削峰填谷,防止系統(tǒng)崩塌。
- 延遲信息處理,比如 10 分鐘之后給下單未付款的用戶發(fā)送郵件提醒。
- 解耦系統(tǒng),對于新增的功能可以單獨寫模塊擴展,比如用戶確認(rèn)評價之后,新增了給用戶返積分的功能,這個時候不用在業(yè)務(wù)代碼里添加新增積分的功能,只需要把新增積分的接口訂閱確認(rèn)評價的消息隊列即可,后面再添加任何功能只需要訂閱對應(yīng)的消息隊列即可。
-
RabbitMQ 有哪些重要的角色?
RabbitMQ 中重要的角色有:生產(chǎn)者、消費者和代理:
- 生產(chǎn)者:消息的創(chuàng)建者,負責(zé)創(chuàng)建和推送數(shù)據(jù)到消息服務(wù)器;
- 消費者:消息的接收方,用于處理數(shù)據(jù)和確認(rèn)消息;
- 代理:就是 RabbitMQ 本身,用于扮演“快遞”的角色,本身不生產(chǎn)消息,只是扮演“快遞”的角色。
-
RabbitMQ 有哪些重要的組件?
- ConnectionFactory(連接管理器):應(yīng)用程序與Rabbit之間建立連接的管理器,程序代碼中使用。
- Channel(信道):消息推送使用的通道。
- Exchange(交換器):用于接受、分配消息。
- Queue(隊列):用于存儲生產(chǎn)者的消息。
- RoutingKey(路由鍵):用于把生成者的數(shù)據(jù)分配到交換器上。
- BindingKey(綁定鍵):用于把交換器的消息綁定到隊列上。
-
RabbitMQ 中 vhost 的作用是什么?
vhost:每個 RabbitMQ 都能創(chuàng)建很多 vhost,我們稱之為虛擬主機,每個虛擬主機其實都是 mini 版的RabbitMQ,它擁有自己的隊列,交換器和綁定,擁有自己的權(quán)限機制。
-
RabbitMQ 的消息是怎么發(fā)送的?
首先客戶端必須連接到 RabbitMQ 服務(wù)器才能發(fā)布和消費消息,客戶端和 rabbit server 之間會創(chuàng)建一個 tcp 連接,一旦 tcp 打開并通過了認(rèn)證(認(rèn)證就是你發(fā)送給 rabbit 服務(wù)器的用戶名和密碼),你的客戶端和 RabbitMQ 就創(chuàng)建了一條 amqp 信道(channel),信道是創(chuàng)建在“真實” tcp 上的虛擬連接,amqp 命令都是通過信道發(fā)送出去的,每個信道都會有一個唯一的 id,不論是發(fā)布消息,訂閱隊列都是通過這個信道完成的
-
RabbitMQ 怎么保證消息的穩(wěn)定性?
- 提供了事務(wù)的功能。
- 通過將 channel 設(shè)置為 confirm(確認(rèn))模式。
-
RabbitMQ 怎么避免消息丟失?
- 把消息持久化磁盤,保證服務(wù)器重啟消息不丟失。
- 每個集群中至少有一個物理磁盤,保證消息落入磁盤。
-
要保證消息持久化成功的條件有哪些?
- 聲明隊列必須設(shè)置持久化 durable 設(shè)置為 true.
- 消息推送投遞模式必須設(shè)置持久化,deliveryMode 設(shè)置為 2(持久)。
- 消息已經(jīng)到達持久化交換器。
- 消息已經(jīng)到達持久化隊列。
以上四個條件都滿足才能保證消息持久化成功。
-
RabbitMQ 持久化有什么缺點?
持久化的缺地就是降低了服務(wù)器的吞吐量,因為使用的是磁盤而非內(nèi)存存儲,從而降低了吞吐量??杀M量使用 ssd 硬盤來緩解吞吐量的問題。
-
RabbitMQ 有幾種廣播類型?
- direct(默認(rèn)方式):最基礎(chǔ)最簡單的模式,發(fā)送方把消息發(fā)送給訂閱方,如果有多個訂閱者,默認(rèn)采取輪詢的方式進行消息發(fā)送。
- headers:與 direct 類似,只是性能很差,此類型幾乎用不到。
- fanout:分發(fā)模式,把消費分發(fā)給所有訂閱者。
- topic:匹配訂閱模式,使用正則匹配到消息隊列,能匹配到的都能接收到。
11. RabbitMQ 怎么實現(xiàn)延遲消息隊列?
延遲隊列的實現(xiàn)有兩種方式:
- 通過消息過期后進入死信交換器,再由交換器轉(zhuǎn)發(fā)到延遲消費隊列,實現(xiàn)延遲功能;
- 使用 RabbitMQ-delayed-message-exchange 插件實現(xiàn)延遲功能。
-
RabbitMQ 集群有什么用?
群主要有以下兩個用途:
- 高可用:某個服務(wù)器出現(xiàn)問題,整個 RabbitMQ 還可以繼續(xù)使用;
- 高容量:集群可以承載更多的消息量。
-
RabbitMQ 節(jié)點的類型有哪些?
- 磁盤節(jié)點:消息會存儲到磁盤。
- 內(nèi)存節(jié)點:消息都存儲在內(nèi)存中,重啟服務(wù)器消息丟失,性能高于磁盤類型。
-
RabbitMQ 集群搭建需要注意哪些問題?
- 各節(jié)點之間使用“--link”連接,此屬性不能忽略。
- 各節(jié)點使用的 erlang cookie 值必須相同,此值相當(dāng)于“秘鑰”的功能,用于各節(jié)點的認(rèn)證。
- 整個集群中必須包含一個磁盤節(jié)點。
-
RabbitMQ 每個節(jié) 點是其他節(jié)點的完整拷貝嗎?為什么?
不是,原因有以下兩個:
- 存儲空間的考慮:如果每個節(jié)點都擁有所有隊列的完全拷貝,這樣新增節(jié)點不但沒有新增存儲空間,反而增加了更多的冗余數(shù)據(jù);
- 性能的考慮:如果每條消息都需要完整拷貝到每一個集群節(jié)點,那新增節(jié)點并沒有提升處理消息的能力,最多是保持和單節(jié)點相同的性能甚至是更糟。
今日主題: MySQL
-
數(shù)據(jù)庫的三范式是什么?
- 第一范式:強調(diào)的是列的原子性,即數(shù)據(jù)庫表的每一列都是不可分割的原子數(shù)據(jù)項。
- 第二范式:要求實體的屬性完全依賴于主關(guān)鍵字。所謂完全依賴是指不能存在僅依賴主關(guān)鍵字一部分的屬性。
- 第三范式:任何非主屬性不依賴于其它非主屬性。
-
一張自增表里面總共有 7 條數(shù)據(jù),刪除了最后 2 條數(shù)據(jù),重啟 MySQL 數(shù)據(jù)庫,又插入了一條數(shù)據(jù),此時 id 是幾?
- 表類型如果是 MyISAM ,那 id 就是 8。
- 表類型如果是 InnoDB,那 id 就是 6。
InnoDB 表只會把自增主鍵的最大 id 記錄在內(nèi)存中,所以重啟之后會導(dǎo)致最大 id 丟失。
-
如何獲取當(dāng)前數(shù)據(jù)庫版本?
使用 select version() 獲取當(dāng)前 MySQL 數(shù)據(jù)庫版本。
-
說一下 ACID 是什么?
- Atomicity(原子性):一個事務(wù)(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結(jié)束在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被恢復(fù)(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣。即,事務(wù)不可分割、不可約簡。
- Consistency(一致性):在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預(yù)設(shè)約束、觸發(fā)器、級聯(lián)回滾等。
- Isolation(隔離性):數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進行讀寫和修改的能力,隔離性可以防止多個事務(wù)并發(fā)執(zhí)行時由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。事務(wù)隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復(fù)讀(repeatable read)和串行化(Serializable)。
- Durability(持久性):事務(wù)處理結(jié)束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。
5. char 和 varchar 的區(qū)別是什么?
char(n) :固定長度類型,比如訂閱 char(10),當(dāng)你輸入"abc"三個字符的時候,它們占的空間還是 10 個字節(jié),其他 7 個是空字節(jié)。
chat 優(yōu)點:效率高;缺點:占用空間;適用場景:存儲密碼的 md5 值,固定長度的,使用 char 非常合適。
varchar(n) :可變長度,存儲的值是每個值占用的字節(jié)再加上一個用來記錄其長度的字節(jié)的長度。
所以,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適,二者使用需要權(quán)衡。
-
float 和 double 的區(qū)別是什么?
- float 最多可以存儲 8 位的十進制數(shù),并在內(nèi)存中占 4 字節(jié)。
- double 最可可以存儲 16 位的十進制數(shù),并在內(nèi)存中占 8 字節(jié)。
-
MySQL 的內(nèi)連接、左連接、右連接有什么區(qū)別?
內(nèi)連接關(guān)鍵字:inner join;左連接:left join;右連接:right join。
內(nèi)連接是把匹配的關(guān)聯(lián)數(shù)據(jù)顯示出來;左連接是左邊的表全部顯示出來,右邊的表顯示出符合條件的數(shù)據(jù);右連接正好相反。
-
MySQL 索引是怎么實現(xiàn)的?
索引是滿足某種特定查找算法的數(shù)據(jù)結(jié)構(gòu),而這些數(shù)據(jù)結(jié)構(gòu)會以某種方式指向數(shù)據(jù),從而實現(xiàn)高效查找數(shù)據(jù)。
具體來說 MySQL 中的索引,不同的數(shù)據(jù)引擎實現(xiàn)有所不同,但目前主流的數(shù)據(jù)庫引擎的索引都是 B+ 樹實現(xiàn)的,B+ 樹的搜索效率,可以到達二分法的性能,找到數(shù)據(jù)區(qū)域之后就找到了完整的數(shù)據(jù)結(jié)構(gòu)了,所有索引的性能也是更好的。
-
怎么驗證 MySQL 的索引是否滿足需求?
使用 explain 查看 SQL 是如何執(zhí)行查詢語句的,從而分析你的索引是否滿足需求。
explain 語法:explain select * from table where type=1。
-
說一下數(shù)據(jù)庫的事務(wù)隔離?
MySQL 的事務(wù)隔離是在 MySQL. ini 配置文件里添加的,在文件的最后添加:
transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
READ-UNCOMMITTED:未提交讀,最低隔離級別、事務(wù)未提交前,就可被其他事務(wù)讀?。〞霈F(xiàn)幻讀、臟讀、不可重復(fù)讀)。
READ-COMMITTED:提交讀,一個事務(wù)提交后才能被其他事務(wù)讀取到(會造成幻讀、不可重復(fù)讀)。
REPEATABLE-READ:可重復(fù)讀,默認(rèn)級別,保證多次讀取同一個數(shù)據(jù)時,其值都和事務(wù)開始時候的內(nèi)容是一致,禁止讀取到別的事務(wù)未提交的數(shù)據(jù)(會造成幻讀)。
SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止臟讀、不可重復(fù)讀、幻讀。
臟讀 :表示一個事務(wù)能夠讀取另一個事務(wù)中還未提交的數(shù)據(jù)。比如,某個事務(wù)嘗試插入記錄 A,此時該事務(wù)還未提交,然后另一個事務(wù)嘗試讀取到了記錄 A。
不可重復(fù)讀 :是指在一個事務(wù)內(nèi),多次讀同一數(shù)據(jù)。
幻讀 :指同一個事務(wù)內(nèi)多次查詢返回的結(jié)果集不一樣。比如同一個事務(wù) A 第一次查詢時候有 n 條記錄,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產(chǎn)生了幻覺。發(fā)生幻讀的原因也是另外一個事務(wù)新增或者刪除或者修改了第一個事務(wù)結(jié)果集里面的數(shù)據(jù),同一個記錄的數(shù)據(jù)內(nèi)容被修改了,所有數(shù)據(jù)行的記錄就變多或者變少了。