天天看點

消息隊列Java的簡單實作

此文章是剛畢業的時候比較懵懂寫的,實際上不可稱之為消息隊列,等我有空了會更新一篇關于主流mq的文章,謝謝包容(20171123)

消息隊列Java的簡單實作

今天看到我們的招聘資訊有對消息隊列有要求,然後就思索了一翻,網上一搜一大堆。

我可以舉個小例子先說明應用場景

假設你的伺服器每分鐘的處理量為200個,但用戶端再峰值的時候可能一分鐘會發1000個消息給你,這時候你就可以把他做成隊列,然後按正常有序的處理,先進後出(LIFO),先進先出(FIFO)可根據自己的情況進行定奪

stack  先進後出(LIFO)--------java 對應的類 Stack

隊列 先進先出(FIFO)--------java對應的類Queue

這兩種都可用Linkedlist進行封裝和實作,下面是我自己寫的一個棧的例子

/**
 * @author 劉伊凡
 * --------->>>>>>隊列的實作--------------
 */
public class MyStack<T> {
	private LinkedList<T> storage = new LinkedList<T>();

	public synchronized void push(T e) {//需要加上同步
		storage.addFirst(e);
	}

	public T peek() {
		return storage.getFirst();
	}

	public void pop() {
		storage.removeFirst();
	}

	public boolean empty() {
		return storage.isEmpty();
	}

	@Override
	public String toString() {
		return storage.toString();
	}

}
           

下面是一個測試類

/**
 * @author 劉伊凡
 *
 */
public class StackTest {
	public static void main(String[] args) {
		MyStack<String> stack = new MyStack<String>();
		for(String s : "the prefect code".split(" ")){//LIFO
			stack.push(s);
		}
		while(!stack.empty()){
			System.out.print(stack.peek()+" ");
			stack.pop();
		}
		
		System.out.println();
		for(char s : "寫了個一句話倒起來說的程式".toCharArray()){//用例:正話反說
			stack.push(String.valueOf(s));
		}
		while(!stack.empty()){
			System.out.print(stack.peek());
			stack.pop();
		}
	}
}
           

挺有意思的,讓我想了,以前在學校的晚會上,主持人互動的時候會讓人上台去答題拿獎品,其中有一個題目就是主持人說一句話,然後要求選手倒起來說,我們的這個程式很符合需求嘛,哈哈,我們可以用java來作弊,學以緻用

消息隊列的應用場景,補充(來自網際網路)

個人認為消息隊列的主要特點是異步處理,主要目的是減少請求響應時間和解耦。是以主要的使用場景就是将比較耗時而且不需要即時(同步)傳回結果的操作作為消息放入消息隊列。同時由于使用了消息隊列,隻要保證消息格式不變,消息的發送方和接收方并不需要彼此聯系,也不需要受對方的影響,即解耦和。

使用場景的話,舉個例子:

假設使用者在你的軟體中注冊,服務端收到使用者的注冊請求後,它會做這些操作:

  1. 校驗使用者名等資訊,如果沒問題會在資料庫中添加一個使用者記錄
  2. 如果是用郵箱注冊會給你發送一封注冊成功的郵件,手機注冊則會發送一條短信
  3. 分析使用者的個人資訊,以便将來向他推薦一些志同道合的人,或向那些人推薦他
  4. 發送給使用者一個包含操作指南的系統通知
  5. 等等……

但是對于使用者來說,注冊功能實際隻需要第一步,隻要服務端将他的賬戶資訊存到資料庫中他便可以登入上去做他想做的事情了。至于其他的事情,非要在這一次請求中全部完成麼?值得使用者浪費時間等你處理這些對他來說無關緊要的事情麼?是以實際當第一步做完後,服務端就可以把其他的操作放入對應的消息隊列中然後馬上傳回使用者結果,由消息隊列異步的進行這些操作。

或者還有一種情況,同時有大量使用者注冊你的軟體,再高并發情況下注冊請求開始出現一些問題,例如郵件接口承受不住,或是分析資訊時的大量計算使cpu滿載,這将會出現雖然使用者資料記錄很快的添加到資料庫中了,但是卻卡在發郵件或分析資訊時的情況,導緻請求的響應時間大幅增長,甚至出現逾時,這就有點不劃算了。面對這種情況一般也是将這些操作放入消息隊列(生産者消費者模型),消息隊列慢慢的進行處理,同時可以很快的完成注冊請求,不會影響使用者使用其他功能。

是以在軟體的正常功能開發中,并不需要去刻意的尋找消息隊列的使用場景,而是當出現性能瓶頸時,去檢視業務邏輯是否存在可以異步處理的耗時操作,如果存在的話便可以引入消息隊列來解決。否則盲目的使用消息隊列可能會增加維護和開發的成本卻無法得到可觀的性能提升,那就得不償失了。