亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

消息中間件及ActiveMQ介紹

jaysun / 2620人閱讀

摘要:中間件的分類基于遠(yuǎn)程過程調(diào)用的中間件?;趯ο笳埱蟠淼闹虚g件。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進(jìn)行通信,而不是通過直接調(diào)用彼此來通信,直接調(diào)用通常是用于諸如遠(yuǎn)程過程調(diào)用的技術(shù)。

一.中間件

1.1 什么是中間件?

由于業(yè)務(wù)、機(jī)構(gòu)和技術(shù)是不斷變化的,因此為其服務(wù)的軟件系統(tǒng)必須適應(yīng)這樣的變化。在合并、添加服務(wù)或擴(kuò)展可用服務(wù)之后,公司可能無力負(fù)擔(dān)重新創(chuàng)建信息系統(tǒng)所需的成本。正是在這個關(guān)鍵時刻,才需要集成新組件或者盡可能高效地擴(kuò)展現(xiàn)有組件。要集成異類組件,最方便的方法不是將它們重新創(chuàng)建為同類元素,而是提供一個允許它們進(jìn)行通信(不考慮它們之間的差異)的層。該層被稱作中間件。

1.2 中間件的分類

基于遠(yuǎn)程過程調(diào)用 (Remote Procedure Call, RPC)的中間件。

基于對象請求代理 (Object Request Broker, ORB) 的中間件。

面向消息的中間件或基于 MOM 的中間件。

二.面向消息的中間件 (Message-Oriented Middleware, MOM) 2.1 消息中間件介紹
消息隊列中間件是分布式系統(tǒng)中重要的組件,主要解決應(yīng)用耦合、異步消息、流量削鋒等問題。實現(xiàn)高性能、高可用、可伸縮和最終一致性架構(gòu)。是大型分布式系統(tǒng)不可缺少的中間件。
2.2 消息中間件的結(jié)構(gòu)

三.JMS(Java Message Service)

3.1 什么是jms?

JMS即Java消息服務(wù)(Java Message Service)應(yīng)用程序接口,是一個Java平臺中關(guān)于面向消息中間件(MOM)的API,用于在兩個應(yīng)用程序之間,或分布式系統(tǒng)中發(fā)送消息,進(jìn)行異步通信。Java消息服務(wù)是一個與具體平臺無關(guān)的API,絕大多數(shù)MOM提供商都對JMS提供支持。

3.2 JMS 消息傳送模式

客戶端 A、C 和 D之間的消息傳送說明了點對點模式(P2P)??蛻舳耸褂么四J较蜿犃心康牡匕l(fā)送一條消息,只有一個接收者能夠從該目的地獲得該消息。訪問該目的地的其他任何接收者都不能獲得該消息。

客戶端 B、E 和 F之間的消息傳送說明了發(fā)布/訂閱模式(publish-subscribe)??蛻舳耸褂么藦V播模式向主題目的地發(fā)送一條消息,任意數(shù)量的使用方訂戶都可以從該目的地檢索此消息。每個訂戶都獲得此消息的一個副本。

3.3 JMS 消息傳送對象

JMS 消息傳送的對象在編程域中基本保持不變:連接工廠、連接、會話、生成方、使用方、消息和目的地。

四、MQ (Message Queue)
MQ全稱為Message Queue,消息隊列(MQ)是正確而又完整的 JMS 實現(xiàn),消息隊列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。應(yīng)用程序通過寫和檢索出入列隊的針對應(yīng)用程序的數(shù)據(jù)(消息)來通信,而無需專用連接來鏈接它們。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進(jìn)行通信,而不是通過直接調(diào)用彼此來通信,直接調(diào)用通常是用于諸如遠(yuǎn)程過程調(diào)用的技術(shù)。
4.1 應(yīng)用場景 1. 異步處理
   場景說明:新用戶注冊發(fā)放100積分,180元新手大禮包,激活會員卡,傳統(tǒng)的做法有兩種:串行方式,并行方式。    

串行方式

使用消息隊列

    以上兩種方式,很容易發(fā)現(xiàn)同步處理的情況下都會涉及到非主業(yè)務(wù)的其他操作,其實注冊的的主流程不應(yīng)該受其他事件影響,通過消息隊列的方式,可以把后續(xù)的處理流程進(jìn)行異步處理可以大大提高響應(yīng)速度。
2. 應(yīng)用解耦
場景說明:企業(yè)中經(jīng)常出現(xiàn)企業(yè)合作如:本公司的驢粉卡與電信合作,新開卡的用戶從電信端推送到我方,除了相對應(yīng)的福利外,首先判斷是否注冊本公司賬戶,
沒有給予注冊,但是新用戶的相對應(yīng)權(quán)益需要對等的發(fā)放。

傳統(tǒng)方式

缺點:

1.與其他系統(tǒng)過度耦合
2.短信發(fā)放或優(yōu)惠券發(fā)放失敗,影響主業(yè)務(wù)

使用消息隊列

優(yōu)點:

1.注冊完成然后將消息寫入隊列返回成功。
2.發(fā)放權(quán)益業(yè)務(wù)不影響主業(yè)務(wù),實現(xiàn)解耦。

3. 秒殺方案
場景說明:秒殺活動對稀缺或者特價的商品進(jìn)行定時定量售賣,吸引成大量的消費(fèi)者進(jìn)行搶購,但又只有少部分消費(fèi)者可以下單成功。
因此,秒殺活動將在較短時間內(nèi)產(chǎn)生比平時大數(shù)十倍,上百倍的頁面訪問流量和下單請求流量。

秒殺前:用戶不斷刷新商品詳情頁,頁面請求達(dá)到瞬時峰值。

秒殺開始:用戶點擊秒殺按鈕,下單請求達(dá)到瞬時峰值。

秒殺后:一部分成功下單的用戶不斷刷新訂單或者產(chǎn)生退單操作,大部分用戶繼續(xù)刷新商品詳情頁等待退單機(jī)會。

秒殺前,用戶不斷刷新商品詳情頁,造成大量的頁面請求。所以,我們需要把秒殺商品詳情頁與普通的商品詳情頁分開。對于秒殺商品詳情頁盡量將能靜態(tài)化的元素靜態(tài)化處理,除了秒殺按鈕需要服務(wù)端進(jìn)行動態(tài)判斷,其他的靜態(tài)數(shù)據(jù)可以緩存在瀏覽器和CDN 上。這樣,秒殺前刷新頁面導(dǎo)致的流量進(jìn)入服務(wù)端的流量只有很小的一部分。

利用讀寫分離 Redis 緩存攔截流量(活動未開始時攔截大部分動態(tài)數(shù)據(jù)請求)

成功參與下單后,進(jìn)入下層服務(wù),開始進(jìn)行訂單信息校驗,庫存扣量。為了避免直接訪問數(shù)據(jù)庫,我們使用主從版 Redis 來進(jìn)行庫存扣量

如果還有大量并發(fā)的請求則利用消息隊列組件,當(dāng)秒殺服務(wù)將訂單信息寫入消息隊列后,即可認(rèn)為下單完成,避免直接操作數(shù)據(jù)庫。

五.JMS實現(xiàn)--ActiveMQ
ActiveMQ是Apache軟件基金下的一個開源軟件,它遵循JMS1.1規(guī)范(Java Message Service),是消息驅(qū)動中間件軟件(MOM)。它為企業(yè)消息傳遞提供高可用,出色性能,可擴(kuò)展,穩(wěn)定和安全保障。
5.1 中間件、JMS、MQ、ActiveMQ之間的關(guān)系

5.2 ActiveMQ的消息傳遞模式

P2P (點對點)消息域使用 queue 作為 Destination,消息可以被同步或異步的發(fā)送和接收,每個消息只會給一個 Consumer 傳送一次。
Pub/Sub(發(fā)布/訂閱,Publish/Subscribe)消息域使用 topic 作為 Destination,發(fā)布者向 topic 發(fā)送消息,訂閱者注冊接收來自 topic 的消息。發(fā)送到 topic 的任何消息都將自動傳遞給所有訂閱者。接收方式(同步和異步)與 P2P 域相同。
5.3 ActiveMQ簡單案例

消息生產(chǎn)者

       //創(chuàng)建session會話
        ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.187.13:61616");
        Connection connection = factory.createConnection();
        connection.start();
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

        //創(chuàng)建一個消息隊列 session.createQueue("jms.test.topic")--P2P模式
        Destination destination = session.createTopic("jms.test.topic");

        //創(chuàng)建消息生產(chǎn)者
        MessageProducer producer = session.createProducer(destination);

        //消息持久化
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);

        for (int i = 0; i < messageNum; i++) {
            producer.send(session.createTextMessage("Message Producer:" + i));
        }

        //提交會話
        session.commit();

消息消費(fèi)者

       //創(chuàng)建session會話
        ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.187.13:61616");
        Connection connection = factory.createConnection();
        connection.start();
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

        //創(chuàng)建一個消息隊列 session.createQueue("jms.test.topic")--P2P模式
        Destination destination = session.createTopic("jms.test.topic");

        //創(chuàng)建消息消費(fèi)者
        MessageConsumer consumer = session.createConsumer(destination);

        while (true) {
            TextMessage message = (TextMessage) consumer.receive();
            if (message != null){
                System.out.println("Message Consumer:"+message.getText());
            }else {
                break;
            }
        }
        session.commit();
5.4 ActiveMQ的消息存儲機(jī)制

KahaDB

ActiveMQ 5.3 版本起的默認(rèn)存儲方式。KahaDB存儲是一個基于文件的快速存儲消息,設(shè)計目標(biāo)是易于使用且盡可能快。它使用基于文件的消息數(shù)據(jù)庫意味著沒有第三方數(shù)據(jù)庫的先決條件。

        
                
        

AMQ

MQ存儲使用戶能夠快速啟動和運(yùn)行,因為它不依賴于第三方數(shù)據(jù)庫。AMQ 消息存儲庫是可靠持久性和高性能索引的事務(wù)日志組合,當(dāng)消息吞吐量是應(yīng)用程序的主要需求時,該存儲是最佳選擇。但因為它為每個索引使用兩個分開的文件,并且每個 Destination 都有一個索引,所以當(dāng)你打算在代理中使用數(shù)千個隊列的時候,不應(yīng)該使用它。

        

JDBC

選擇關(guān)系型數(shù)據(jù)庫,通常的原因是企業(yè)已經(jīng)具備了管理關(guān)系型數(shù)據(jù)的專長,但是它在性能上絕對不優(yōu)于上述消息存儲實現(xiàn)。事實是,許多企業(yè)使用關(guān)系數(shù)據(jù)庫作為存儲,是因為他們更愿意充分利用這些數(shù)據(jù)庫資源。

        
                
                        
                
        
        
                
                
                
                
                
                
        

內(nèi)存存儲

內(nèi)存消息存儲器將所有持久消息保存在內(nèi)存中。在僅存儲有限數(shù)量 Message 的情況下,內(nèi)存消息存儲會很有用,因為 Message 通常會被快速消耗。在 activema.xml 中將 broker 元素上的 persistent 屬性設(shè)置為 false 即可。

        
                
        

1.KahaDB存儲的目錄結(jié)構(gòu)及簡單說明
    -rw-rw-r--. 1 lvmama01 lvmama01 32M 5月  18 09:47 db-1.log
    -rw-rw-r--. 1 lvmama01 lvmama01 32K 5月  18 09:47 db.data
    -rw-rw-r--. 1 lvmama01 lvmama01 33K 5月  18 09:47 db.redo
    -rw-rw-r--. 1 lvmama01 lvmama01 0   5月  16 19:31 lock

可以看出,上面directory一共有四個文件:

①db.data

它是消息的索引文件。本質(zhì)上是B-Tree的實現(xiàn),使用B-Tree作為索引指向db-*.log里面存儲的消息。

②db.redo

主要用來進(jìn)行消息恢復(fù)。

③db-*.log 存儲消息的內(nèi)容。對于一個消息而言,不僅僅有消息本身的數(shù)據(jù)(message data),而且還有(Destinations、訂閱關(guān)系、事務(wù)...),data log以日志形式存儲消息,而且新的數(shù)據(jù)總是以APPEND的方式追加到日志文件末尾。因此,消息的存儲是很快的。比如,對于持久化消息,Producer把消息發(fā)送給Broker,Broker先把消息存儲到磁盤中(enableJournalDiskSyncs配置選項),然后再向Producer返回Acknowledge。Append方式在一定程度上減少了Broker向Producer返回Acknowledge的時間。

④lock文件

2.KahaDB存儲底層原理簡單分析

KahaDB內(nèi)部分為:data logs, 按照Message ID高度優(yōu)化的索引,memory message cache。

①在內(nèi)存(cache)中的那部分B-Tree是Metadata Cache

通過將索引緩存到內(nèi)存中,可以加快查詢的速度(quick retrival of message data)。但是需要定時將 Metadata Cache 與 Metadata Store同步。這個同步過程就稱為:check point。由checkpointInterval選項 決定每隔多久時間進(jìn)行一次checkpoint操作。

②BTree Indexes則是保存在磁盤上的,稱為Metadata Store,它對應(yīng)于文件db.data,它就是對Data Logs以B樹的形式索引。

有了它,Broker(消息服務(wù)器)可以快速地重啟恢復(fù),因為它是消息的索引,根據(jù)它就能恢復(fù)出每條消息的location。如果Metadata Store被損壞,則只能掃描整個Data Logs來重建B樹了。

③Data Logs則對應(yīng)于文件 db-*.log,默認(rèn)是32MB

Data Logs以日志形式存儲消息,它是生產(chǎn)者生產(chǎn)的數(shù)據(jù)的真正載體。

④Redo Log則對應(yīng)于文件 db.redo,redo log的原理用到了“Double Write”。

簡要記錄下自己的理解:因為磁盤的頁大小與操作系統(tǒng)的頁大小不一樣,磁盤的頁大小一般是16KB,而OS的頁大小是4KB。而數(shù)據(jù)寫入磁盤是以磁盤頁大小為單位進(jìn)行的,即一次寫一個磁盤頁大小,這就需要4個OS的頁大?。?*4=16)。如果在寫入過程中出現(xiàn)故障(突然斷電)就會導(dǎo)致只寫入了一部分?jǐn)?shù)據(jù)(partial page write)
而采用了“Double Write”之后,將數(shù)據(jù)寫入磁盤時,先寫到一個Recovery Buffer中,然后再寫到真正的目的文件中。在ActiveMQ的源碼PageFile.java中有相應(yīng)的實現(xiàn)。
public void unload() throws IOException {
     //load時創(chuàng)建writeFile(db.data)和 recoveryFile(db.redo)
    writeFile = new RecoverableRandomAccessFile(file, "rw", false);

    ........

    if (enableRecoveryFile) {
         recoveryFile = new RecoverableRandomAccessFile(getRecoveryFile(), "rw");
    }
}
private void writeBatch() throws IOException {
    .......
    //將數(shù)據(jù)寫入磁盤時,先寫到一個Recovery Buffer中(db.data)
    for (PageWrite w : batch) {
        try {
            checksum.update(w.getDiskBound(), 0, pageSize);
        } catch (Throwable t) {
            throw IOExceptionSupport.create("Cannot create recovery file. Reason: " + t, t);
        }
        recoveryFile.writeLong(w.page.getPageId());
        recoveryFile.write(w.getDiskBound(), 0, pageSize);
    }
    .......
    //寫入真正的目的文件中(db.redo)
    for (PageWrite w : batch) {
        writeFile.seek(toOffset(w.page.getPageId()));
        writeFile.write(w.getDiskBound(), 0, pageSize);
        w.done();
    }
}
5.4 ActiveMQ的部署模式

1.默認(rèn)的單機(jī)部署(kahadb)

略......

2.共享存儲主從模式(基于數(shù)據(jù)庫)

3.共享存儲主從模式(基于文件系統(tǒng))

4.基于zookeeper的主從(levelDB Master/Slave詳細(xì)說明

第一步:zookeeper集群搭建

server.1=lvmama01:2888:3888
server.2=lvmama02:2888:3888
server.3=lvmama03:3888:3888

第二步:activemq集群搭建修改activemq.xml文件:

 
         
   

第三步:分別啟動三臺activemq(仔細(xì)查看日志):

1.啟動第一臺機(jī)器(lvmama01:192.168.187.11)

2.啟動第二臺機(jī)器(lvmama02:192.168.187.12)

3.第三臺啟動同第二臺

第三步:查看是否啟動成功(沒成功可以查看activemq.log日志)

啟動成功后通過zkCli.sh可以看到已創(chuàng)建leveldb-stores如下:

第四步:通過流量器訪問web管理頁面(注意只有master機(jī)器可以訪問)

第五步:測試

        String userName = ActiveMQConnectionFactory.DEFAULT_USER;
        String password = ActiveMQConnectionFactory.DEFAULT_PASSWORD;
        String brokerURL = "failover:(tcp://192.168.187.11:61616,tcp://192.168.187.12:61616,tcp://192.168.187.13:61616)?Randomize=false";

        //2. 通過ConnectionFactory建立一個Connection連接,并且調(diào)用start方法開啟
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(userName, password, brokerURL);
        Connection connection = connectionFactory.createConnection();
        connection.start();

        //3. 通過Connection創(chuàng)建Session,用于接收消息[第一個參數(shù):是否啟用事務(wù);第二個參數(shù):設(shè)置簽收模式]
        Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

        //4. 通過Session創(chuàng)建Destination對象
        Destination destination = session.createQueue("cluster-queue");

        //5. 通過Session創(chuàng)建發(fā)送或接受對象
        MessageProducer messageProducer = session.createProducer(null);
        

運(yùn)行結(jié)果(此時發(fā)送的目標(biāo)為192.168.187.11):

Connected to the target VM, address: "127.0.0.1:12266", transport: "socket"
 INFO | Successfully connected to tcp://192.168.187.11:61616
生產(chǎn)者:Hello MQ:1
生產(chǎn)者:Hello MQ:2
生產(chǎn)者:Hello MQ:3
生產(chǎn)者:Hello MQ:4
生產(chǎn)者:Hello MQ:5
生產(chǎn)者:Hello MQ:6
生產(chǎn)者:Hello MQ:7
生產(chǎn)者:Hello MQ:8
生產(chǎn)者:Hello MQ:9

此時將activemq master服務(wù)停止,集群自動重新選舉 lvmama02(192.168.187.12)成為Master

我們再試運(yùn)行測試用例發(fā)現(xiàn)消息任然可以發(fā)送,只不過發(fā)送的目標(biāo)變?yōu)?92.168.187.12

Connected to the target VM, address: "127.0.0.1:12400", transport: "socket"
 INFO | Successfully connected to tcp://192.168.187.12:61616
生產(chǎn)者:Hello MQ:1
生產(chǎn)者:Hello MQ:2
生產(chǎn)者:Hello MQ:3
生產(chǎn)者:Hello MQ:4
生產(chǎn)者:Hello MQ:5
生產(chǎn)者:Hello MQ:6
生產(chǎn)者:Hello MQ:7
生產(chǎn)者:Hello MQ:8
生產(chǎn)者:Hello MQ:9

六.ActiveMQ性能測試

1.安裝Jmeter測試工具,參考

2.新建jndi.properties到j(luò)meter/bin目錄下

//ActiveMQ jar包中init所需的類名
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory

//ActiveMQ的地址
java.naming.provider.url = tcp://127.0.0.1:61616

//連接工廠名稱
connectionFactoryNames = connectionFactory

//p2p 隊列名稱
queue.MyQueue = example.MyQueue
topic.MyTopic = example.MyTopic

3.把配置文件打到ApacheJMeter.jar 中 在jmeter/bin目錄下運(yùn)行

  jar uf ApacheJMeter.jar jndi.properties

4.下載Activemq,并加activemq-all-5.15.3.jar添加到Jmeter/lib下

5.配置Jmeter測試p2p模式

新建線程組

新建JMS Point-to-Point采樣并配置(參考jndi.properties)

6.進(jìn)行測試(單線程+60s+10000條消息)

測試結(jié)果:

Jmeter官網(wǎng)測試結(jié)果:

可能由于機(jī)器原因,測試結(jié)果差距蠻大 ^_^

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/69457.html

相關(guān)文章

  • 消息間件——RabbitMQ(二)各大主流消息間件綜合對比介紹!

    摘要:主流消息中間件介紹是由出品,是一個完全支持和規(guī)范的實現(xiàn)。主流消息中間件介紹是阿里開源的消息中間件,目前也已經(jīng)孵化為頂級項目。 showImg(https://img-blog.csdnimg.cn/20190509221741422.gif);showImg(https://img-blog.csdnimg.cn/20190718204938932.png?x-oss-process=...

    hiyang 評論0 收藏0
  • 基于JMS(Java Message Service)的消息間件----ActiveMQ

    摘要:而中的消息中間件則是在常見的消息中間件類型無疑是不錯的選擇。是在之間傳遞的消息的對象?;竟δ苁怯糜诤兔嫦蛳⒌闹虚g件相互通信的應(yīng)用程序接口。支持兩種消息發(fā)送和接收模型。一種稱為模型,即采用點對點的方式發(fā)送消息。 消息中間件利用高效可靠的消息傳遞機(jī)制進(jìn)行平臺無關(guān)的數(shù)據(jù)交流,并基于數(shù)據(jù)通信來進(jìn)行分布式系統(tǒng)的集成。通過提供消息傳遞和消息排隊模型,它可以在分布式環(huán)境下擴(kuò)展進(jìn)程間的通信。而Ja...

    JessYanCoding 評論0 收藏0
  • 限時訂單實現(xiàn)方案(DelayQueue、ActiveMq

    摘要:一在各種電商網(wǎng)站下訂單后會保留一個時間段,時間段內(nèi)未支付則自動將訂單狀態(tài)設(shè)置為已過期。并修改這些數(shù)據(jù)的狀態(tài)為已過期。因此以上方式實際開發(fā)中基本不予采用。時間到期了才會發(fā)送這條消息到消息隊列中。 一、在各種電商網(wǎng)站下訂單后會保留一個時間段,時間段內(nèi)未支付則自動將訂單狀態(tài)設(shè)置為已過期。(原文鏈接 ) showImg(https://segmentfault.com/img/bVbv9BX?...

    hosition 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<