背景

近期系统需求上来迟缓,也腾出了一些时间来梳理沉淀。对系统的代码进行审视,sonar静态检测,消除检测问题。也是还债的过程。回顾过往的坑,有些东西还是要沉淀下来。接下来节听听故事的来龙去脉。

一个故事

先说说之前印象比较深刻都一个需求,一个踩了很多坑的故事。

需求

实现一个web端的python代码执行器,能够完成简单的数据分析功能。

需求很简单;编程语言使用java,实现一个python的执行器功能。简单的,先从网上搜一把有没有现成的轮子。

技术选型

方案1:使用Jython包实现。

优点:封装良好

缺点:对python的第三方包的支持不好。

方案2:使用Runtime.getRuntime()执行脚本文件。

优点:调用简单(同在命令行中执行python)

缺点:无封装调用。第三方包必须安装在运行环境中。

综合:采用方案2实现python执行器。

设计

组件图

说明: 1、通信方式采用http和websocket进行。其中:websocke负责python的执行和停止事件处理(需要持续推送执行状态)。其他操作统一采用http方式。 2、manager模块负责核心业务分发。 3、执行器抽离,面向接口编程,方便后续扩展其他执行器类型。

类图

说明 1、PythonController: http接口层,提供给前端调用,返回json格式数据。 2、PythonSocket: WebSocket服务,和客户端建立socket通信。 3、IExector: 执行器接口,提供(execute和stop接口);PythonExector Python执行器实现。 4、PythonThread :线程,采用线程池进行异步处理。 5、PythonManager :python业务实现类,提供核心业务处理。

代码实现

java 中执行python代码片段:

Process process = null;

logger.info("python version={}",pythonVersion);

String cmd = String.format("python"+pythonVersion+" %s", pythonFile);

logger.info("执行python, 命令:{}", cmd);

// 执行命令

process = Runtime.getRuntime().exec(cmd);

遇到的问题

如何实现执行超时处理

process.waitFor();

是一个阻塞调用,一直等待,直到有响应为止。所以,为了避免系统资源占用。需要设置一个超时,超过指定时间,线程终止。

这里增加一个超时线程进行处理。

/**

* 超时线程

*/

private static class TimeoutWorker extends Thread {

private final Process process;

private Integer exit;

private TimeoutWorker(Process process) {

this.process = process;

}

@Override

public void run() {

try {

exit = process.waitFor();

} catch (InterruptedException e) {

return;

}

}

}

......(略去上文)

if (process != null) {

TimeoutWorker worker = new TimeoutWorker(process);//将执行进程放进超时线程中执行。

worker.start();

try {

logger.info("timeout={}(ms)", timeout);

worker.join(timeout);//加入当前线程,timeout后,退出。

if (worker.exit != null){

int insRet = worker.exit;

......(略去下文)

补充线程知识:

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

如何实现安装包安装

python的安装使用

python setup.py install

进行安装第三方包。在linux环境下,需要切到安装包的解压根目录,然后执行以上指令。于是,简单编写shell脚本python_install.sh。同时,实现动态注射shell指令参数。

#!/bin/bash

filepath=$1

pythonVersion=$2

echo "the file path is : ${filepath}"

echo "the python version is : ${pythonVersion}"

cd ${filepath} && python${pythonVersion} setup.py install

遇到个坑:.sh脚本在windows系统下编辑后,放在Linux环境,发现.sh脚本文件运行失败。单独执行语句,没问题。后来发现原来文件编码导致linux不识别。参见:执行shell脚本时提示bad interpreter:No such file or directory的解决办法

如何获取process的错误信息

程序最初通过标准输出流获取process执行输出,本以为可以回去到所有的结果输出(正确输出和错误信息)。发现,并没有。而且,有时候程序一只卡死,waitFor()方法阻塞无法返回,直到超时为止。

......(略去上文)

InputStreamReader ir = new InputStreamReader(process.getInputStream());

BufferedReader bufferedReader = new BufferedReader(ir);

String data = null;

while ((data = bufferedReader.readLine()) != null) {

......(略去下文)

后来,网上搜了搜,发现:

Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。

process.getErrorStream();

process.getInputStream();

process.getOutputStream();

waitFor()方法阻塞无法返回的问题。原因是getErrorStream()所对应的那个缓冲区没有被清空。所以,程序中增加对getErrorStream()错误输出流处理。同时,也解决了无法获取到process错误信息的问题。

所以,类似像上面那样。读取标准错误流,就可以接收到process的错误信息。

......(略去上文)

InputStreamReader ir = new InputStreamReader(process.getErrorStream());

BufferedReader bufferedReader = new BufferedReader(ir);

String data = null;

while ((data = bufferedReader.readLine()) != null) {

......(略去下文)

故事结尾

这个故事让我学习了python,成了py新手。踩了不少的坑,就要挤出时间去填上。

个人公众号:

您的关注是对我最大的支持!

python发明小故事_一个与python有关的故事相关推荐

  1. python日历小程序_一个查看网络设备信息Python小程序

    原标题:一个查看网络设备信息Python小程序 网络编程中,最常见的一个问题就是,获取设备信息. 首先我们,要学习如何获取本机的网络信息.我们将用到标准库中的socket库.假如说,我们要查看本机的 ...

  2. python整人小程序_一个可以套路别人的python小程序实例代码

    先简要介绍一下程序. 程序是使用pycharm工具,python语言所写.程序包括客户端 client.py 和服务器端 server.py 两部分,利用了python中的socket包. 咳咳,使用 ...

  3. python连连看小游戏_请用PYTHON编一个小游戏,如五子棋,连连看,贪吃蛇,扫雷,计算器等等...

    展开全部 #!/usr/bin/python from Tkinter import * import random class snake(Frame): def __init__(self, ma ...

  4. 如何制作python检查小软件_如何用Python制作整蛊小程序

    原标题:如何用Python制作整蛊小程序 下面的整蛊程序,千万不要发代码,否则就实现不了你整蛊的目的了.完成后一定要打包成一个exe程序,再发给朋友使用 . 1. 使用 pip install pyi ...

  5. python制作网页挂机_一个用Python写的简易挂机锁

    基本功能实现了,但是不够漂亮屏蔽了Alt+F4,但是Ctrl+Alt+Del没能屏蔽# -*- coding: utf-8 -*- u""" 一个挂机锁软件. autho ...

  6. 怎么用python画小狗_怎么用python画小猪佩奇

    最近社会猪可是火遍了大江南北,不蹭下热度可对不起它.见过手画的佩奇,见过用代码画的吗? 没有?那就来看我大显身手. 用python的turtle库来画小猪佩奇. 有人问:turtle难不难? 答曰:不 ...

  7. python编写股票公式_一个用Python编写的股票数据(沪深)爬虫和选股策略测试框架...

    一个户外论坛的特点: 列出一些活动,有翻页功能,点向一个活动显示当前活动信息,在二楼一般显示报名名单! 需要的数据: 就是活动的信息, 报名的名单,价钱,主 一个股票数据(沪深)爬虫和选股策略测试框架 ...

  8. python 语句执行顺序_一个针对 Python 语句执行顺序的练习

    摘自 Fluent Python evalsupport.py print(' evalsupport module start') def deco_alpha(cls): print(' deco ...

  9. python画图小动物_如何用python画简单的动物

    首先来看一下实现效果,如下图: 具体实现代码请看: (推荐学习:python视频教程)# -*- coding:utf-8 -*- # __author__ :kusy # __content__:文 ...

最新文章

  1. MySQL数据导入oracle
  2. 安卓版kindle电子书位置_安卓手机APP如何打开三种格式的电子书文件
  3. mit景观生成技术_永远不会再为工作感到不知所措:如何使用MIT技术
  4. VS2010与QT的集成开发环境
  5. 矩池云上使用nohup和让任务后台运行
  6. 面试中软性问题的套路与反套路
  7. git远程仓库中master及其余分支间代码的合并
  8. 指针函数 (C语言)
  9. python解释器安装过程
  10. Word转html实现在线预览
  11. 魔板游戏java_Java魔板游戏完整代码及注释
  12. URP教务系统自动登录
  13. android n换行格式,Android 写文件生成器的时候换行请用\r\n
  14. 推荐免费下载华软源码430套大型企业管理源码,下载地址:http://www.hur.cn/tg/linkin.asp?linkid=205389 源码语言:PB/Delphi/VB/Java/.Ne
  15. 《盟威软件快速开发平台》开发
  16. 游戏场景offset坐标系关联正六边形cube坐标系
  17. 通信原理学习笔记6-2:数字解调——抽样和符号同步
  18. 在华为工作的优点和缺点
  19. 设计模式六大原则(SOLID)
  20. java中的常用名词,Java编程基础常见英语词汇

热门文章

  1. 计算机术语网站,背单词网站
  2. 设计模式 结构型模式 -- 装饰者模式(概述 快餐店案例 模式优点 使用场景 源码解析 BufferedWriter 和代理模式的区别)
  3. java验证各种文件内容合法性
  4. Linux命令--查看内存--free--使用/教程/实例
  5. python操作excel几种方式
  6. Glossary - 术语对照表 2
  7. 华为gt3和华为gt3pro手表区别 华为gt3和gt3pro哪个值得入手
  8. 买android手机,买大屏 Android 手机真的有必要吗?
  9. 2020劳务员-岗位技能(劳务员)考试题库及劳务员-岗位技能(劳务员)模拟考试题
  10. 如何获得微信公众号二维码