詳解Python如何與?java高效的交互
問題背景
項(xiàng)目過程中可能會遇到,java 從數(shù)據(jù)庫取了很多數(shù)據(jù),但 java 本身不方便處理,所以傳遞給 python 去處理,如何傳?
解決方法
調(diào)研了一些方法,譬如可以直接在 java 中調(diào)研 python,傳入?yún)?shù)的方式,或者數(shù)據(jù)先存儲到 excel 中,然后 python 去 excel 中讀取,但是這些方法還是存在不便利和性能會有限制。之后,我嘗試了增加個 rabbitmq 消息中間件進(jìn)行不同語言之間的通信交互。
MQ 是消費(fèi) - 生產(chǎn)者模型的一個典型的代表,一端往消息隊(duì)列中不斷寫入消息,而另一端則可以讀取或者訂閱隊(duì)列中的消息。MQ 和 JMS 類似,但不同的是 JMS 是 SUN JAVA 消息中間件服務(wù)的一個標(biāo)準(zhǔn)和 API 定義,而 MQ 則是遵循了 AMQP 協(xié)議的具體實(shí)現(xiàn)和產(chǎn)品。RabbitMQ 是一個在 AMQP 基礎(chǔ)上完成的,可復(fù)用的企業(yè)消息系統(tǒng)。

上圖是簡單抽象的描述,具體到 rabbitmq 有很多詳細(xì)的概念,這里不一一詳述。當(dāng)然,我們上面也說過 ,rabbitmq 是 AMQP 協(xié)議的一個開源實(shí)現(xiàn),所以其內(nèi)部實(shí)際上也是 AMQP 中的基本概念,包括:Message(消息)、Publisher(消息生產(chǎn)者),Exchange(交換器),Binding(綁定),Queue(消息隊(duì)列),Connection(網(wǎng)絡(luò)連接),Channel(信道),Consumer(消息消費(fèi)者),Virtual Host(虛擬主機(jī)),Broker(消息隊(duì)列服務(wù)器)。
實(shí)際例子
生產(chǎn)者使用 java,往隊(duì)列中寫入待處理的消息。
java 代碼(即生產(chǎn)者)
public class Producer1 {
public final static String QUEUE_NAME="data";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException{
long startTime=System.currentTimeMillis(); //獲取開始時間
//數(shù)據(jù)準(zhǔn)備
List<testObj> list = MockData.mockData();
//創(chuàng)建連接工廠
ConnectionFactory factory = new ConnectionFactory();
//設(shè)置RabbitMQ相關(guān)信息
factory.setHost("192.168.43.211");
factory.setUsername("test");
factory.setPassword("123456");
//factory.setPort(5672);
//創(chuàng)建一個新的連接
Connection connection = factory.newConnection();
//創(chuàng)建一個通道
Channel channel = connection.createChannel();
//聲明一個隊(duì)列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
List<testObj> list1 = new ArrayList<testObj>();
list1 = new MockData().mockData();
//發(fā)送消息到隊(duì)列中
ObjectMapper mapper=new ObjectMapper();
String message = mapper.writeValueAsString(list1);
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
//關(guān)閉通道和連接
channel.close();
connection.close();
long endTime=System.currentTimeMillis(); //獲取結(jié)束時間
System.out.println("程序運(yùn)行時間: "+(endTime-startTime)/1000.0+"s");
}
}消費(fèi)者使用 python 代碼,從消息隊(duì)列中獲取 java 生成者發(fā)送的消息進(jìn)行處理。
python 代碼(即消費(fèi)者)
if __name__ == '__main__':
starttime = datetime.datetime.now()
# 創(chuàng)建socket鏈接
credentials = pika.PlainCredentials('test', '123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
'192.168.43.211', 5672, '/', credentials))
# 創(chuàng)建管道
channel = connection.channel()
# 創(chuàng)建隊(duì)列
queue_name = 'data'
channel.queue_declare(queue_name)
# 如果接受到消息就調(diào)用回調(diào)函數(shù),準(zhǔn)備接受消息
# 聲明回調(diào)函數(shù)
def callback(ch, method, properties, body):
message = json.loads(body.decode())
endtime = datetime.datetime.now()
print("拿數(shù)據(jù)時間:{}".format(endtime - starttime))
list = message
for i in list:
print(i)
channel.basic_consume(callback, queue=queue_name, no_ack=False)
channel.start_consuming()
我們可以看到 python 順利拿到 java 傳輸?shù)臄?shù)據(jù),至于你拿到數(shù)據(jù)后,后面要做什么復(fù)雜的操作、分析,那就是看你自己的需要了。
另外,你不妨嘗試把模擬數(shù)據(jù)條數(shù)提高到 10 萬條甚至更多, rabbitmq 基本能保持穩(wěn)定有效。
小結(jié)
在解決不同語言程序之間數(shù)據(jù)傳輸問題上,方法各異,rabbitmq 是一個很好的選擇,處理數(shù)據(jù)量大,且從時間效率上來說也快,而且很方便的進(jìn)行系統(tǒng)的解耦。
以上就是詳解Python如何與 java高效的交互的詳細(xì)內(nèi)容,更多關(guān)于Python與java 高效的交互的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Tkinter組件實(shí)現(xiàn)Radiobutton的示例
Radiobutton組件用于實(shí)現(xiàn)多選一的問題,本文主要介紹了Tkinter組件實(shí)現(xiàn)Radiobutton的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
django實(shí)現(xiàn)前后臺交互實(shí)例
本篇文章主要介紹了django實(shí)現(xiàn)前后臺交互實(shí)例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
Python編程中對super函數(shù)的正確理解和用法解析
可能有人會想到,Python中既然可以直接通過父類名調(diào)用父類方法為什么還會存在super函數(shù)?其實(shí),很多人對Python中的super函數(shù)的認(rèn)識存在誤區(qū),本文我們就帶來在Python編程中對super函數(shù)的正確理解和用法解析2016-07-07
python pydoc生成API文檔的實(shí)現(xiàn)
pydoc?模塊會根據(jù) Python 模塊來自動生成文檔,本文主要介紹了python pydoc生成API文檔的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-12-12
python實(shí)現(xiàn)不同電腦之間視頻傳輸功能
這篇文章主要介紹了python實(shí)現(xiàn)不同電腦之間視頻傳輸,本文視頻傳輸實(shí)現(xiàn)的前提是確保發(fā)送端和接收端接在同一個局域網(wǎng)下,分為發(fā)送端和接收端,通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-06-06

