詳解Python如何與?java高效的交互
問題背景
項目過程中可能會遇到,java 從數(shù)據(jù)庫取了很多數(shù)據(jù),但 java 本身不方便處理,所以傳遞給 python 去處理,如何傳?
解決方法
調(diào)研了一些方法,譬如可以直接在 java 中調(diào)研 python,傳入?yún)?shù)的方式,或者數(shù)據(jù)先存儲到 excel 中,然后 python 去 excel 中讀取,但是這些方法還是存在不便利和性能會有限制。之后,我嘗試了增加個 rabbitmq 消息中間件進行不同語言之間的通信交互。
MQ 是消費 - 生產(chǎn)者模型的一個典型的代表,一端往消息隊列中不斷寫入消息,而另一端則可以讀取或者訂閱隊列中的消息。MQ 和 JMS 類似,但不同的是 JMS 是 SUN JAVA 消息中間件服務(wù)的一個標(biāo)準(zhǔn)和 API 定義,而 MQ 則是遵循了 AMQP 協(xié)議的具體實現(xiàn)和產(chǎn)品。RabbitMQ 是一個在 AMQP 基礎(chǔ)上完成的,可復(fù)用的企業(yè)消息系統(tǒng)。
上圖是簡單抽象的描述,具體到 rabbitmq 有很多詳細(xì)的概念,這里不一一詳述。當(dāng)然,我們上面也說過 ,rabbitmq 是 AMQP 協(xié)議的一個開源實現(xiàn),所以其內(nèi)部實際上也是 AMQP 中的基本概念,包括:Message(消息)、Publisher(消息生產(chǎn)者),Exchange(交換器),Binding(綁定),Queue(消息隊列),Connection(網(wǎng)絡(luò)連接),Channel(信道),Consumer(消息消費者),Virtual Host(虛擬主機),Broker(消息隊列服務(wù)器)。
實際例子
生產(chǎn)者使用 java,往隊列中寫入待處理的消息。
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(); //聲明一個隊列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); List<testObj> list1 = new ArrayList<testObj>(); list1 = new MockData().mockData(); //發(fā)送消息到隊列中 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("程序運行時間: "+(endTime-startTime)/1000.0+"s"); } }
消費者使用 python 代碼,從消息隊列中獲取 java 生成者發(fā)送的消息進行處理。
python 代碼(即消費者)
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)建隊列 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ù)量大,且從時間效率上來說也快,而且很方便的進行系統(tǒng)的解耦。
以上就是詳解Python如何與 java高效的交互的詳細(xì)內(nèi)容,更多關(guān)于Python與java 高效的交互的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Tkinter組件實現(xiàn)Radiobutton的示例
Radiobutton組件用于實現(xiàn)多選一的問題,本文主要介紹了Tkinter組件實現(xiàn)Radiobutton的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01Python編程中對super函數(shù)的正確理解和用法解析
可能有人會想到,Python中既然可以直接通過父類名調(diào)用父類方法為什么還會存在super函數(shù)?其實,很多人對Python中的super函數(shù)的認(rèn)識存在誤區(qū),本文我們就帶來在Python編程中對super函數(shù)的正確理解和用法解析2016-07-07