消息中間件--ActiveMQ&JMS消息服務

来源:https://www.cnblogs.com/soul-wonder/archive/2018/04/22/8910220.html
-Advertisement-
Play Games

### 消息中間件 ### **消息中間件** 1. 消息中間件的概述 2. 消息中間件的應用場景(查看大綱文檔,瞭解消息隊列的應用場景) * 非同步處理 * 應用解耦 * 流量削峰 * 消息通信 ### JMS消息服務 ### **JMS的概述** 1. JMS消息服務的概述 2. JMS消息模型 ...


### 消息中間件 ###

----------

**消息中間件**

1. 消息中間件的概述 2. 消息中間件的應用場景   * 非同步處理   * 應用解耦   * 流量削峰   * 消息通信   ----------

### JMS消息服務 ###

----------

**JMS的概述**

1. JMS消息服務的概述 2. JMS消息模型   * P2P模式   * Pub/Sub模式   3. 消息消費的方式   * 同步的方式---手動   * 非同步的方式---listener監聽   4. JMS編程模型 ----------

### 消息中間件:ActiveMQ ###

----------

**ActiveMQ的下載與安裝**

1. ActiveMQ的下載與安裝   * 下載ActiveMQ的壓縮文件,解壓apache-activemq-5.14.5-bin.zip文件   * 雙擊運行:activemq.bat文件,啟動服務   2. 測試ActiveMQ是否安裝成功   * 打開瀏覽器,輸入:http://localhost:8161   3. 點擊Manage ActiveMQ broker連接,可以查看ActiveMQ中已經發佈的消息等   * 用戶名密碼都是:admin ----------

**ActiveMQ的消息隊列方式入門**(P2P模式)

1. 在父工程的pom.xml文件中引入ActiveMQ和Spring整合JMS的坐標依賴
<!-- activemq start -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.2.0</version>
</dependency>
<!-- activemq end -->
<!-- spring 與 mq整合 start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>3.7</version>
</dependency>
<!-- spring 與 mq整合 end -->
  2. ActiveMQ的向消息隊列中發送消息的入門程式(沒有使用Spring整合JMS的方式)
@Test
public void sendQueueMessage() throws JMSException {
// 1 創建連接工廠
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
 
// 2 使用工廠,創建連接
Connection connection = factory.createConnection();
 
// 3 啟動連接
connection.start();
 
// 4 使用連接,創建會話,true表示開始事務,代碼執行後需要提供事務
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
 
// 5 創建隊列隊形(myQueue--隊列的名字)/topic-----------session創建
Queue queue = session.createQueue("myQueue");
// 6 創建生產者-----------session創建
MessageProducer producer = session.createProducer(queue);
// 7 創建消息----文本消息-------session創建
TextMessage message = session.createTextMessage();
message.setText("helloworld!!!");
 
// 8 發送消息
producer.send(message);
 
// 9 提交事務
session.commit();
session.close();
connection.close();
}
3. ActiveMQ從消息隊列中獲取消息
@Test
public void receiverQueueMessage() throws JMSException {
// 1 創建連接工廠
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
// 2 使用工廠,創建連接
Connection connection = factory.createConnection();
// 3 啟動連接
connection.start();
// 4 使用連接,創建會話,true表示開始事務,代碼執行後需要提供事務
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
// 5 創建隊列隊形(hello--隊列的名字)/topic-----------session創建
Queue queue = session.createQueue("myQueue");
// 6 創建消費者-----------session創建
MessageConsumer consumer = session.createConsumer(queue);
 
// 7 接收消息----text格式
TextMessage receive = (TextMessage) consumer.receive();
String text = receive.getText();
System.out.println("接收到的消息====" + text);
 
// 8 提交事務
session.commit();
session.close();
connection.close();
 
}
4. 使用監聽器的方式,從隊列中消費消息
/**
*非同步方式
Queue接受用Listener方式接受,多用
如果有多個監聽listener,則交替執行
* @throws Exception
*/
@Test
public void receiverQueueListener() throws Exception{
// 1 創建連接工廠
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
// 2 使用工廠,創建連接
Connection connection = factory.createConnection();
// 3 啟動連接
connection.start();
// 4 使用連接,創建會話,true表示開始事務,代碼執行後需要提供事務//死迴圈的不能用事物
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 5 創建隊列隊形(hello--隊列的名字)/topic-----------session創建
Queue queue = session.createQueue("myQueue");
// 6 創建消費者-----------session創建
MessageConsumer consumer = session.createConsumer(queue);
 
//7 // 給消費者添加監聽器
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message msg) {
TextMessage message = (TextMessage) msg;
try {
System.out.println("Listener1111111111接收到的消息是=="+message.getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
 
while(true){}
// 使用監聽器的方式不能關閉,需要監聽器一直工作
// session.commit();
// session.close();
// connection.close();
}

 

**ActiveMQ的消息訂閱方式入門**(Pub/Sub模式

/**
* Topic發送
* @throws JMSException
*/
@Test
public void sendTopicMessage() throws JMSException {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
 
// 創建消息訂閱
Topic topic = session.createTopic("myTopic");
// 創建生產者
MessageProducer producer = session.createProducer(topic);
// 創建消息,一組可以存儲key value的消息
MapMessage message = session.createMapMessage();
message.setString("username", "cgx");
message.setString("password", "123456");
// 發送消息
producer.send(message);
// 提交事務
session.commit();
session.close();
connection.close();
}
/**
* Topic接受
*
* @throws JMSException
*/
@Test
public void testReceiverMessage() throws JMSException {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
 
// 創建消息訂閱
Topic topic = session.createTopic("myTopic");
// 創建消費者
MessageConsumer consumer = session.createConsumer(topic);
// 接收消息
MapMessage message = (MapMessage) consumer.receive();
System.out.println(message.getString("username"));
System.out.println(message.getString("password"));
 
session.commit();
session.close();
connection.close();
}
/**
* Topic接受Listener監聽方式
*
* @throws Exception
*/
@Test
public void receiverQueueListener() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建消息訂閱
Topic topic = session.createTopic("myTopic");
// 創建消費者
MessageConsumer consumer = session.createConsumer(topic);
 
// 給消費者添加監聽器consumer添加監聽
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message msg) {
MapMessage message = (MapMessage) msg;
try {
System.out.println(message.getString("username"));
System.out.println(message.getString("password"));
} catch (JMSException e) {
e.printStackTrace();
}
}
});
 
while (true) {
 
}
 
}

 

### Spring整合ActiveMQ ###★★★★★

----------   **Spring整合ActiveMQ**★★★★★   1. 創建applicationContext-mq.xml的配置文件,導入約束★★★★★
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
 
</beans>

 

2. 具體的配置如下★★★★★ applicationContext-mq.xml===================mq的消息發送(消息生產者)
<!-- 配置連接工廠 -->
<!-- ActiveMQ 連接工廠 -->
<!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供-->
<!-- 如果連接網路:tcp://ip:61616;未連接網路:tcp://localhost:61616 以及用戶名,密碼-->
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://localhost:61616" userName="admin" password="admin" />
 
<!-- Spring Caching連接工廠 -->
<!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
<!-- Session緩存數量和鏈接數有關 -->
<property name="sessionCacheSize" value="100" />
</bean>
 
<!-- 定義JmsTemplate的Queue類型★★★★★ -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 -->
<constructor-arg ref="connectionFactory" />
<!-- 非pub/sub模型(發佈/訂閱),即隊列模式 -->
<property name="pubSubDomain" value="false" />
</bean>
 
<!-- 定義JmsTemplate的Topic類型★★★★★ -->
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate" >
<!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 -->
<constructor-arg ref="connectionFactory" />
<!-- pub/sub模型(發佈/訂閱) -->
<property name="pubSubDomain" value="true" />
</bean>

 

  3. 發送消息的代碼如下★★★★★   3.1.Queue方式:★★★★★
@Autowired
@Qualifier(value="jmsQueueTemplate")
private JmsTemplate queueTemplate;//Queue
 
 
/**
* Queue發送消息---spring框架
*/
@Test
public void sendQueueMessage() {
// 發送消息 構造參數指定目標,因為配置文件中的隊列和訂閱模式是通過id與false和true進行區分
queueTemplate.send("myQueue", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
// 使用session創建消息,發送
TextMessage textMessage = session.createTextMessage("測試結合spring框架發送queue消息");
return textMessage;
}
});
}
  3.2.Topic方式:★★★★★
@Autowired
@Qualifier(value = "jmsTopicTemplate")
private JmsTemplate topicTemplate;//Topic
 
/**
* Topic發送消息---spring框架
*/
@Test
public void sendTopicMessage() {
topicTemplate.send("spring_topic", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
MapMessage mapMessage = session.createMapMessage();
mapMessage.setString("username", "mdzz");
return mapMessage;
}
});
}

 

4. 接收消息的代碼如下==========不提倡手動,要用監聽器非同步獲取
/**
* Queue接收消息---spring框架
* 同步手動:不提倡
* receive("myQueue")要寫目標,不寫目標的話會報找不到目標的錯誤NO defaultDestination
*/
@Test
public void receiverMessage() {
//接收消息textMessage類型
TextMessage textMessage = (TextMessage) queueTemplate.receive("myQueue");
 
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
  **Spring配置監聽器**★★★★★★★★★★★★★★★   1. 自定義監聽器代碼的編寫----接收消息---spring框架---實現MessageListener介面★★★★★   1.1.Queue:★★★★★
@Component(value="queueConsumer1")
public class QueueListener implements MessageListener {
 
@Override
public void onMessage(Message arg0) {
// 把arg0強轉
TextMessage textMessage = (TextMessage) arg0;
try {
// 輸出消息
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
 
}
    1.2.Topic:發送一個,兩個都會接受★★★★★topic特點:有幾個監聽幾個都會同時收到
@Component
public class TopicConsumer1 implements MessageListener {
 
@Override
public void onMessage(Message arg0) {
MapMessage mapMessage = (MapMessage) arg0;
try {
System.out.println("TopicConsumer1===="+mapMessage.getString("username"));
} catch (JMSException e) {
e.printStackTrace();
}
}
 
}
 
@Component
public class TopicConsumer2 implements MessageListener {
    //...
}
  2. 編寫配置文件 applicationContext-mq-consumer.xml=============mq的消息接受(負責監聽接受消息)
<!-- 掃描包 -->
<context:component-scan base-package="com.my.jms.consumer" />
 
<!-- ActiveMQ 連接工廠 -->
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://localhost:61616" userName="admin" password="admin" />
 
<!-- Spring Caching連接工廠 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
<property name="sessionCacheSize" value="100" />
</bean>
 
<!-- Spring JmsTemplate 的消息生產者 start-->
<jms:listener-container destination-type="queue" container-type="default" connection-factory="connectionFactory">
<jms:listener destination="myQueue" ref="queueConsumer1"/>
</jms:listener-container>
 
<jms:listener-container destination-type="topic" container-type="default" connection-factory="connectionFactory">
<jms:listener destination="spring_topic" ref="topicConsumer1"/>
<jms:listener destination="spring_topic" ref="topicConsumer2" />
</jms:listener-container>
  3.不用啟動項目,把spring配置文件applicationContext-mq-consumer.xml啟動起來,可以用採用下麵方法 新建一個test類,讓他一直啟動著,這樣就一直載入spring的配置文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-mq-consumer.xml")
public class SpringQueueListenerTest {
 
@Test
public void test(){
while(true);
}
}

 

4.只要發送端(發送消息---spring框架)一啟動,監聽器就會監聽到,就會輸出:測試結合spring框架發送queue消息★★★★★

spring整合總結:

消息發送
  1. 創建spring容器
  2. 從容器中獲取JMSTemplate對象,發送消息
  3. 定義Destination
  4. 使用JMSTemplate對象發送消息
消息接受
  1. 創建一個類實現MessageListener 介面。業務處理在此類中實現。
  2.在spring容器中配置DefaultMessageListenerContainer對象,引用MessageListener 實現類對象接收消息。

項目整合ActiveMQ:

1. 消息生產者整合ActiveMQ
  消息生產者只需要發送消息
  需要把JMSTemplate和Destination交給spring進行管理

 部分代碼:
/**===========================activeMQ消息發送========================================*/
// 發送消息!!!
this.send("save", item.getId());
}

@Autowired
private JmsTemplate jmsTemplate;

@Autowired
private Destination destination;

/**
* 此方法就是用來發送消息的
* 考慮:1、發送什麼數據?2、我需要什麼數據?
* 在消息中需要:1、消息的標識:save,delete,update;2、商品的ID
*/
private void send(final String type, final Long itemId) {
// TODO Auto-generated method stub
jmsTemplate.send(destination, new MessageCreator() {

@Override
public Message createMessage(Session session) throws JMSException {
//創建消息體
TextMessage textMessage = new ActiveMQTextMessage();
//設置消息內容
Map<String, Object> map = new HashMap<>();
map.put("type", type);
map.put("itemId", itemId);
try {
ObjectMapper mapper = new ObjectMapper();
textMessage.setText(mapper.writeValueAsString(map));
} catch (Exception e) {
e.printStackTrace();
}
return textMessage;
}
});
}

 


2. 消息消費改造
  在search-service添加
  ItemMessageListener:

/**===========================activeMQ消息發送========================================*/
@Autowired
private SearchService searchService;

@Override
public void onMessage(Message message) {
//先判斷此消息類型是否是TextMessage
if(message instanceof TextMessage){
//如果是,強轉
TextMessage textMessage = (TextMessage)message;
try {
//獲取消息:json
String json = textMessage.getText();
//傑克遜第三作用:直接解析json數據
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(json);
String type = jsonNode.get("type").asText();
Long itemId = jsonNode.get("itemId").asLong();
//根據解析出來的type,判斷此type=save的時候我應該調用indexSearch方法
if("save".equals(type)){
searchService.indexItem(itemId);
}

} catch (Exception e) {
e.printStackTrace();
}
}

}

索引庫增加商品會觸發mq:

SearchServiceImpl:

@Override
public void indexItem(Long itemId) throws Exception {
Item item = this.itemMapper.selectByPrimaryKey(itemId);

SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", item.getId());
doc.addField("item_title", item.getTitle());
doc.addField("item_image", item.getImage());
doc.addField("item_cid", item.getCid());
doc.addField("item_price", item.getPrice());
doc.addField("item_status", item.getStatus());

this.cloudSolrServer.add(doc);

this.cloudSolrServer.commit();

}

 

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Lesson Eight 2018-04-23 02:07:01 封裝與隱藏:問題:當創建了類的對像以後,如果直接通過“對象.屬性”的方式對相應的對像屬性賦值的話,可能會出來不滿足實際情況的意外。 引出:通過“對像 .方法”的形式,來控制對像對屬性的訪問。對屬性的要求術可以通過方法來體現。 解決:1 ...
  • 集合的操作 集合是一個無序的,不重覆的數據組合,它的主要作用如下: 去重,把一個列表變成集合,就自動去重了 關係測試,測試兩組數據之間的交集,差集,並集等關係 集合的寫法 list_1 = set([1, 3, 4, 6, 7, 12, 5]) 集合的關係 list_1 = set([1, 3, 5 ...
  • 問題:在使用連接池和線程綁定之後需要關閉其他的參數麽(stat? con?...) ...
  • 多線程併發與線程安全相關知識整理如下: 一、線程怎麼保證安全性。 什麼是線程安全性 當多個線程訪問某個類時,不管運行時環境採用何種調度方式或者這些進程將如何交替執行,並且在主調代碼中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那麼就稱這個類是線程安全的。 線程安全性的三大特征 原子性、有 ...
  • 1. 併發編程的3個概念 併發編程時,要想併發程式正確地執行,必須要保證原子性、可見性和有序性。只要有一個沒有被保證,就有可能會導致程式運行不正確。 1.1. 原子性 原子性:即一個或多個操作要麼全部執行並且執行過程中不會被打斷,要麼都不執行。 一個經典的例子就是銀行轉賬:從賬戶A向賬戶B轉賬100 ...
  • 再次整理了一下這個日誌收集系統的框,如下圖 這次要實現的代碼的整體邏輯為: 完整代碼地址為: https://github.com/pythonsite/logagent etcd介紹 高可用的分散式key-value存儲,可以用於配置共用和服務發現 類似的項目:zookeeper和consul 開 ...
  • Java中的IO流 分類 根據流的方向:輸入流和輸出流 根據讀取文字的大小:位元組流和字元流(位元組按照位元組讀取,讀取中文容易亂碼,字元流按照字元讀取,通常用於讀取中文) 根據讀取的方式:節點流和緩存流 分類 根據流的方向:輸入流和輸出流 根據讀取文字的大小:位元組流和字元流(位元組按照位元組讀取,讀取中文容 ...
  • 一、基礎概念 抽象事物,是若沒有具體的信息可以描述這個事物,這個事物可以稱為抽象事物。 抽象類,是不斷的向上抽取而來。抽取方法聲明而不確定具體的方法內容。由不同的子類來完成具體的方法內容。 (一)抽象類的特點: 1、抽象方法沒有方法體,必須由抽象關鍵字abstract來修飾。 1、抽象方法一定是存在 ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...