日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JMS分布式应用程序异步消息解决方案EhCache高速缓存同步问题

發布時間:2025/7/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JMS分布式应用程序异步消息解决方案EhCache高速缓存同步问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

部分博客中描述的使用攔截器怎么用EJB公布的WebService加入緩存,這樣能夠提高WebService的響應效率。但是即使是這樣做,還是要經歷網絡的傳輸的。于是決定在調用WebService的程序本地也加入EJB方法緩存。假設WebService調用的結果已經存在于本地緩存中,就直接從內存中拿數據,不用再訪問WebService了。

?

架構圖例如以下所看到的



可是還有一個問題又出現了,那就是WebService中的緩存和客戶程序本地緩存的同步問題。這個問題能夠詳細描寫敘述例如以下:


當提供WebService的程序的數據庫中的數據發生改變后(程序運行了增刪改方法后),就須要將WebService的緩存清空,由于那些是臟數據。但是調用WebService的客戶程序本地的緩存卻沒有清空。

?

如何解決問題呢?如何才干清空WebService緩存的同一時候也清空調用client本地的緩存呢?利用JMS的消息機制就能夠解決這一問題

?

詳細思路

WebService服務端創建一個JMS Topic,起名CacheTopic

當服務端運行增刪改方法后,向CacheTopic中發一條消息

客戶程序在自己的server中部署Message Driven Bean,監聽CacheTopic中的消息,收到消息后清空本地緩存

?

?

架構圖例如以下所看到的



項目中使用的AS都是JBoss,在JBoss中加入JMS Topic的方法是在deploy文件夾下部署一個Destination描寫敘述文件,文件名稱符合*-service.xml。

?

本項目中使用的CacheTopic的部署文件內容例如以下

<?xml version="1.0" encoding="UTF-8"?

> <server> <!--使用jboss messaging定義topic--> <mbean code="org.jboss.jms.server.destination.TopicService" name="jboss.messaging.destination:service=Topic,name=CacheTopic" xmbean-dd="xmdesc/Topic-xmbean.xml"> <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends> <depends>jboss.messaging:service=PostOffice</depends> <attribute name="JNDIName" >topic/CacheTopic</attribute> </mbean> </server>


服務端程序在運行增刪改方法后,不僅要清除WebService中的緩存。還要向CacheTopic中發送消息

上篇博客中的攔截器改動例如以下(主要是加入了發送消息的功能):


public class CacheClearSyncInterceptor {@AroundInvokepublic Object clearCache(InvocationContext context) throws Exception{//運行目標方法Object returnObj =context.proceed();/**************************清空本地緩存 begin**************************************/System.out.println("清空前的緩存數:"+CacheHandler.getInstance().getCache().getSize());//清空本地緩存CacheHandler.getInstance().clearCache();System.out.println("清空后的緩存數:"+CacheHandler.getInstance().getCache().getSize());/**************************清空本地緩存 end**************************************///發送消息到CacheTopic,實現緩存同步StringBuilder txtMsgBuilder = new StringBuilder();txtMsgBuilder.append("【gxpt-jc】系統運行了【").append(context.getTarget().getClass().getName()).append(".").append(context.getMethod().getName()).append("】").append("方法,須要同步緩存");MessageSender.send(txtMsgBuilder.toString(), DestinationType.TOPIC,"topic/CacheTopic","192.168.24.48:1199");return returnObj;}}

上面用到的消息發送者類MessageSender的代碼例如以下

public class MessageSender {/*** @MethodName : send* @Description : 發送消息* @param msg 消息* @param type 目的地類型:TOPIC或QUEUE* @param destinationJndi 目的地的jndi名稱* @param url 目的地url*/public static void send(String msg,DestinationType type,String destinationJndi,String url) throws Exception{//定義連接對象和sessionTopicConnection topicConnection=null;TopicSession topicSession = null;QueueConnection queueConnection=null;QueueSession queueSession = null;try {//創建contextProperties props = new Properties();props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");props.setProperty("java.naming.provider.url", url);Context ctx = new InitialContext(props);/************************************發消息給TOPIC begin******************************************************/if(type==DestinationType.TOPIC){TopicConnectionFactory topicFactory=(TopicConnectionFactory)ctx.lookup("ConnectionFactory");//獲取ConnectiontopicConnection=topicFactory.createTopicConnection();//獲取SessiontopicSession=topicConnection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);//獲取destinationTopic topic=(Topic)ctx.lookup(destinationJndi);//創建消息發送者TopicPublisher publisher=topicSession.createPublisher(topic);//創建消息TextMessage txtMsg = topicSession.createTextMessage(msg);//發送消息publisher.publish(txtMsg);}/************************************發消息給TOPIC end******************************************************//************************************發消息給QUEUE begin******************************************************/if(type==DestinationType.QUEUE){QueueConnectionFactory queueFactory=(QueueConnectionFactory)ctx.lookup("ConnectionFactory");//獲取ConnectionqueueConnection=queueFactory.createQueueConnection();//獲取SessionqueueSession=queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);//獲取destinationQueue queue=(Queue)ctx.lookup(destinationJndi);//創建消息發送者QueueSender sender=queueSession.createSender(queue);//創建消息TextMessage txtMsg = queueSession.createTextMessage(msg);//發送消息sender.send(txtMsg);}/************************************發消息給QUEUE end******************************************************/} finally{//關閉對象if(topicConnection!=null && topicSession!=null){topicSession.close();topicConnection.close();}if(queueConnection!=null && queueSession!=null){queueSession.close();queueConnection.close();}}}}

client接收消息的MDB的代碼例如以下

@MessageDriven(activationConfig={@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Topic"),@ActivationConfigProperty(propertyName="destination",propertyValue="topic/CacheTopic"),@ActivationConfigProperty(propertyName="providerAdapterJNDI", propertyValue="java:/RemoteJMSProvider")} ) public class KSCacheSyncMdb implements MessageListener{public void onMessage(Message msg){try {//獲取消息文本TextMessage txtMsg = (TextMessage)msg;//顯示文本消息System.out.println("因為"+txtMsg.getText());/**************************清空本地緩存 begin**************************************/System.out.println("清空前的緩存數:"+CacheHandler.getInstance().getCache().getSize());//清空本地緩存CacheHandler.getInstance().clearCache();System.out.println("清空后的緩存數:"+CacheHandler.getInstance().getCache().getSize());/**************************清空本地緩存 end**************************************/} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}}}

由于在JBoss5.1.0中部署的MDB默認僅僅能監聽本地Destination中的消息。為了讓MDB能夠監聽遠程Destination中的消息。client仍需再部署一個RemoteJMSProvider描寫敘述文件,文件名稱相同需符合*-service.xml。文件內容例如以下


<?

xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.messaging:service=JMSProviderLoader,name=RemoteJMSProvider"> <attribute name="ProviderName">RemoteJMSProvider</attribute> <attribute name="ProviderAdapterClass"> org.jboss.jms.jndi.JNDIProviderAdapter </attribute> <!-- The combined connection factory --> <attribute name="FactoryRef">XAConnectionFactory</attribute> <!-- The queue connection factory --> <attribute name="QueueFactoryRef">XAConnectionFactory</attribute> <!-- The topic factory --> <attribute name="TopicFactoryRef">XAConnectionFactory</attribute> <!-- Uncomment to use HAJNDI to access JMS--> <attribute name="Properties"> java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=192.168.24.48:1199 </attribute> </mbean> </server>


這樣就實現了分布式應用程序緩存同步的


版權聲明:本文博主原創文章,博客,未經同意不得轉載。

總結

以上是生活随笔為你收集整理的JMS分布式应用程序异步消息解决方案EhCache高速缓存同步问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。