Jython(WLST)/Python通信
我想建立一个Jython和Python之间的通信链接。我有一个Django应用和一些Python脚本,用于前端和系统管理/自动化任务。我使用Jython来处理Weblogic 9/10。我希望能给Jython系统发送一个请求,比如执行任务A,并传入参数a、b、c,然后在任务完成后返回一条消息。
我想这样做是因为WLST或Jython启动得很慢,每次需要部署或者检查服务器状态(现在最多有100台服务器)时,这都很麻烦。那么,怎样才能最简单地将信息传回主脚本或Python类,同时保持Jython/(WLST)系统处于活动状态,并能轻松地共享或发出请求呢?
我现在的做法是使用pickle对象。具体来说,就是把所有数据获取到后,输出到一个文件中,然后再把这个文件加载回Python应用/脚本中。
3 个回答
把数据进行“腌制”(也就是序列化)是可以的,使用cPickle会更高效。不过,不建议把它直接写入文件。你可以使用其他的进程间通信(IPC)方式,比如套接字或管道,这样可以避免写入磁盘带来的额外开销。具体可以参考一下这个链接:https://stackoverflow.com/search?q=python+named+pipes。
对于这种消息传递,我喜欢使用一种不依赖于特定编程语言的消息队列系统,这样在未来的项目中也能反复使用。如果你能接受在中间有一个消息队列代理来管理所有队列,可以看看AMQP。如果你不想使用第三方的代理,可以考虑ZeroMQ。
在这两种情况下,你可以使用一个发布-订阅的队列来发送消息,这样每个队列可以处理多个工作进程。消息可以是简单的文本字符串,或者是JSON对象,甚至在小心的情况下,你可能还可以发送经过处理的Python对象和执行代码。我个人比较喜欢使用JSON对象(JSON的一种子集),然后将它们解包成Python字典来使用。
我在大约20个相互通信的Python进程的系统中使用过AMQP和ZeroMQ。这两者都很好用,如果你需要连接一些非Python的东西,你会发现已经有AMQP模块和ZeroMQ库可用。
一个有趣的扩展是,可以有三种不同的工作进程,分别用Jython、CPython和IronPython编写。这样你就可以利用第三方的Java和.NET模块,以及像lxml这样的二进制CPython模块。再结合Redis,这样进程就完全解耦了,如果需要的话可以在多个服务器上运行。工作进程会把结果放入Redis,而不是让消息队列系统被大消息和小消息混在一起搞得很乱。如果需要,某个工作进程可以发布一个包含Redis键的消息,这样其他进程就可以取出对应的值。
你有没有考虑过使用Celery或者其他标准的队列/消息中介系统?django-celery已经相当成熟,功能也很强大,专门为这种任务设计的。
Django -> Celery --> Worker Process (always running)
^ |-> Worker Process
| `-> Worker Process -,
\______ Job Complete _____/
基本的想法是,你有一些一直在运行的工作进程(可以在一台或多台服务器上),它们在等待消息的到来。(这些消息可以是被序列化的对象、json格式的内容,或者你想要的任何东西)。这些进程会闲着,等待Celery(以及它的RabbitMQ后端)给它们分配消息或任务。一旦消息或任务处理完毕,通知会通过中介返回,并在django中调用一个回调函数来更新状态。
Celery是一个基于分布式消息传递的任务队列/作业队列。它专注于实时操作,但也支持调度功能。
执行单元被称为任务,这些任务可以在一个或多个工作服务器上并发执行。任务可以异步执行(在后台运行)或同步执行(等待直到准备好)。