JRT和springboot比较测试

news2024/12/27 0:34:17

想要战胜他,必先理解他。这两天系统的学习Maven和跑springboot工程,从以前只是看着复杂到亲手体验一下,亲自实践的才是更可靠的了解。

第一就是首先Maven侵入代码结构,代码一般要按约定搞src/main/java。如果是能严格执行测试的项目用着还行,需求性的项目测试根本跟不上,多增加层级就是增加负担。

第二就是Maven所带来的好处和所需要的环境配置和学习成本不匹配,增加学习成本,好处并没有绝对优势,当然如果架构没解决业务脚本化的问题,那么不同模块之间肯定相互引用很多,这时候是有优势的。所以根源不是Maven有多好、而是没解决业务编码便捷性问题,为了解决这个问题而引入的新问题,还要鼓吹有多好。然后就是Maven编译打包Spring太慢了,每个操作都要一分钟起,给和咖啡带来了充分的时间。

同时经过测试发现Spring启动后太费内存了,什么都不做内存就占用1700兆了,同等启动的JRTWeb占用137兆,相差10倍以上。用多余内存给DolerGet做缓存用不香吗,多用的内存都能内存缓存千万级别的数据了。

然后就是环境太复杂,又要配Maven,又要运行ridis,又要运行nginx配置代理,还没进入开发过程就能浪费两天时间,发布还得再额外学。针对单体机构的软件真的有必要像互联网那样用ridis那些么?杀鸡焉用牛刀,部署的时候也得额外安装ridis(麻烦的要死)。

实现原理上Spring和JRT基本一致,只是面向发布和开发理念不同。两者都是内嵌Web服务器,然后按请求的url执行对应的业务类。不同的是Spring按注解反射初始化容器,按url通过注解从容器取对象执行。JRT按业务脚本目录给每个业务编译jar包,按请求url执行对应jar,理论上应该是JRT执行效率更高,因为不需要解析注解那些,直接按路径得到类全面执行就行了。注解用的好确实是简化程序,但是什么都注解也不一定好,感觉Spring用点过渡注解的意思。综合就是Spring流程定义更全面和规范、用着更复杂更加重量级,一个开发要全面掌控不容易。JRT更注重简化业务和环境,要哪些就做哪些,不引入多余的东西,可以达到一个开发全面掌控的效果。

Springboot编译用了55秒
在这里插入图片描述

用cmd启动要1分钟开外
在这里插入图片描述
idea启动用了52秒
在这里插入图片描述

JRT网站在5秒编译和启动完成,并用谷歌打开指定的页面
在这里插入图片描述

springboot网站启动后占用的内存
在这里插入图片描述

JRT网站启动后占用的内存
在这里插入图片描述

Spring启动定制测试程序。由于这个springboot的前后台分离没做到分而不离,所以需要nginx代码前端后后台来避免跨域,因此启动网站之前需要启动nginx,同时又依赖了ridis,这里一起给启动了。

package xxxxxx;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Properties;

@ServletComponentScan(basePackages = "com.xxxxxx")
@MapperScan(basePackages = {"xxxxx.**.mapper"})
@SpringBootApplication
@EnableAsync
public class LimpApplication {

    public static void main(String[] args) {
        //尝试启动相关软件
        try {
            if (IsOSLinux() == false) {
                System.out.println("检查D:\\nginx-1.23.2是否存在,尝试启动nginx");
                File niginx = new File("D:\\nginx-1.23.2\\nginx.exe");
                if (niginx.exists()) {
                    System.out.println("存在nginx,尝试启动");
                    StartExe(niginx.toString(), "D:\\nginx-1.23.2");
                }
                System.out.println("检查D:\\Redis-x64-3.2.100是否存在,尝试启动ridis");
                File ridis = new File("D:\\Redis-x64-3.2.100\\start.bat");
                if (ridis.exists()) {
                    System.out.println("存在ridis,尝试启动");
                    StartExe(ridis.toString(), "D:\\Redis-x64-3.2.100");
                }
            }
        }
        catch (Exception ex)
        {

        }
        //启动前先启动ridis和nginx
        SpringApplication.run(LimpApplication.class, args);
    }

    /**
     * 判断OS
     *
     * @return 得到是否是Linux
     */
    public static boolean IsOSLinux() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("os.name");
        if (os != null && os.toLowerCase().indexOf("linux") > -1) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 启动Exe
     * @param cmdStr 命令串
     * @param runDir 运行路径
     */
    private static void StartExe(String cmdStr,String runDir)
    {
        File directory = new File(runDir);
        try
        {
            System.out.println("启动:"+cmdStr);
            // 创建进程并执行命令
            Process process = Runtime.getRuntime().exec(cmdStr,null,directory);
        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }
    }

}

由于很多开发不知道启动后该打开那个url使用,所以需要在Spring启动后执行一个逻辑,用谷歌打开特定页面

package xxxxxxx;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

/**
 * 启动后执行,打开登录页面等
 */
@Component
public class SpringBootApplicationRunner implements ApplicationRunner {
    /**
     * 启动后执行的逻辑
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        //打开页面辅助器
        OpenUrl("http://localhost:8527/imedicallis-hos/imedicallis/webui/test/form/demoHtml.html");
    }

    /**
     * 打印页面
     *
     * @param url 路径
     * @throws Exception
     */
    public static void OpenUrl(String url) throws Exception {
        //获取操作系统类型
        String os = System.getProperty("os.name").toLowerCase();
        //根据操作系统类型调用不同的命令
        if (os.contains("win")) {
            String path = GetChromePath();
            if (!path.isEmpty()) {
                File file = new File(path);
                if (file.exists()) {
                    //使用Runtime.exec执行命令
                    Runtime.getRuntime().exec(path + " "+ url);
                    return;
                }
            }
            //使用Runtime.exec执行命令
            Runtime.getRuntime().exec("cmd /c start " + url);

        } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
            //Linux or Mac
            //使用ProcessBuilder创建一个进程
            ProcessBuilder pb = new ProcessBuilder("google-chrome", url);
            Process p = pb.start();
        } else {
            System.out.println("Unsupported OS");
        }
    }

    /**
     * 得到谷歌程序地址
     *
     * @return
     * @throws Exception
     */
    private static String GetChromePath() throws Exception {
        String path = GetExeRegedit("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
        if (path.isEmpty()) {
            path = GetExeRegedit("HKEY_LOCAL_MACHINE\\HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
        }
        if (!path.isEmpty()) {
            path += "\\chrome.exe";
        }
        return path;
    }

    /**
     * 得到注册表值
     *
     * @param path 执行路径
     * @return
     * @throws Exception
     */
    private static String GetExeRegedit(String path) throws Exception {
        Process ps = null;
        //当路径中有空格时,要把路径打上引号。
        ps = Runtime.getRuntime().exec("reg query \"" + path + "\"");
        ps.getOutputStream().close();
        InputStreamReader i = new InputStreamReader(ps.getInputStream());
        String line;
        BufferedReader ir = new BufferedReader(i);
        String ret = "";
        while ((line = ir.readLine()) != null) {
            if (line.contains("Path")) {
                String[] arr = line.split("    ");
                ret = arr[arr.length - 1];
            }
        }
        return ret;
    }
}

逻辑都是参照JRT启动来的,JRT的启动引导

package WebLoader;

import JRT.Core.Util.LogUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.*;
import java.net.Socket;
import java.nio.file.Paths;
import java.util.Scanner;

/**
 * 网站加载器,参照操作系统引导概念,引导加载网站
 */
public class Main {

    /**
     * 加载入口
     * @param args
     */
    public static void main(String[] args) {

        //站点名称
        String WebName="JRTWeb";
        //自动打开的页面
        String OpenUrlStr="https://localhost:8081/JRTWeb/sys/form/frmCodeTableManager.aspx";

        boolean isWin=true;
        System.out.println("本控制台将负责引导启动网站");
        try
        {
            String osName = System.getProperty("os.name");
            String StartCmd="startup.bat";
            String ShutdownCmd="shutdown.bat";
            //判断Windows
            if(osName != null && !osName.startsWith("Windows")) {
                isWin=false;
                StartCmd="startup.sh";
                ShutdownCmd="shutdown.sh";
            }

            File directory = new File("");// 参数为空
            String courseFile = directory.getCanonicalPath();
            System.out.println(courseFile);
            String binPath= Paths.get(courseFile,"WebSrc","bin").toString();
            String stopBatPath= Paths.get(courseFile,"WebSrc","bin",ShutdownCmd).toString();
            String startBatPath= Paths.get(courseFile,"WebSrc","bin",StartCmd).toString();
            if(isWin==true) {
                //结束打开页面工具
                KillProcess("DevOpenPage.exe");
            }
            System.out.println("尝试停止站点");
            System.out.println("执行脚本:"+stopBatPath);
            TryExecCmd(stopBatPath,binPath);

            //存在就删除
            File jrtOkFile=new File(Paths.get(courseFile,"WebSrc","webapps","JRTWeb","jrt.ok").toString());
            //不存在就创建,网站启动成功会删除
            if(!jrtOkFile.exists())
            {
                jrtOkFile.createNewFile();
            }
            //用线程打开页面
            ThreadOpenUrl(jrtOkFile,OpenUrlStr);
            System.out.println("尝试启动站点");
            System.out.println("执行脚本:"+startBatPath);
            TryExecCmd(startBatPath,binPath);

        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }

    }

    /**
     * 打开页面
     * @param jrtOkFile 成功文件
     * @param OpenUrlStr 打开地址
     * @throws Exception
     */
    private static void ThreadOpenUrl(File jrtOkFile,String OpenUrlStr) throws Exception
    {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int tryNum = 0;
                    //等待网站启动
                    while (true) {
                        tryNum++;
                        //标志文件没了就是网站启动了
                        if (!jrtOkFile.exists()) {
                            break;
                        }
                        if (tryNum > 200) {
                            break;
                        }
                        Thread.sleep(100);
                    }
                    //打开页面辅助器
                    OpenUrl("https://localhost:8081/JRTWeb/sys/form/frmDevOpenPage.aspx");
                    //打开起始页面
                    OpenUrl(OpenUrlStr);
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        });
        thread.start();
    }

    //结束指定名称进程
    //processName:进程名
    public static void KillProcess(String processName) {
        try {
            String line;
            Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe");
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
                if (line.contains(processName)) {
                    String processId = line.split("\\s+")[1];
                    Runtime.getRuntime().exec("taskkill /F /PID " + processId);
                    System.out.println("Process " + processName + " has been killed.");
                }
            }
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 启动Exe
     * @param cmdStr 命令串
     * @param runDir 运行路径
     */
    private static void StartExe(String cmdStr,String runDir)
    {
        File directory = new File(runDir);
        try
        {
            System.out.println("启动:"+cmdStr);
            // 创建进程并执行命令
            Process process = Runtime.getRuntime().exec(cmdStr,null,directory);
        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }
    }


    /**
     * 执行cmd
     * @param cmdStr 命令串
     * @param runDir 运行路径
     */
    private static void TryExecCmd(String cmdStr,String runDir)
    {
        File directory = new File(runDir);
        try
        {
            System.out.println("执行:"+cmdStr);
            // 创建进程并执行命令
            Process process = Runtime.getRuntime().exec(cmdStr,null,directory);
            // 获取命令行程序的输出结果
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待命令行程序执行完毕
            int exitCode=process.waitFor();
            // 关闭资源
            reader.close();
            System.out.println("返回:"+exitCode);
        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }
    }


    /**
     * 打印页面
     *
     * @param url 路径
     * @throws Exception
     */
    public static void OpenUrl(String url) throws Exception {
        //获取操作系统类型
        String os = System.getProperty("os.name").toLowerCase();
        //根据操作系统类型调用不同的命令
        if (os.contains("win")) {
            String path = GetChromePath();
            if (!path.isEmpty()) {
                File file = new File(path);
                if (file.exists()) {
                    //使用Runtime.exec执行命令
                    Runtime.getRuntime().exec(path + " "+ url);
                    return;
                }
            }
            //使用Runtime.exec执行命令
            Runtime.getRuntime().exec("cmd /c start " + url);

        } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
            //Linux or Mac
            //使用ProcessBuilder创建一个进程
            ProcessBuilder pb = new ProcessBuilder("google-chrome", url);
            Process p = pb.start();
        } else {
            System.out.println("Unsupported OS");
        }
    }

    /**
     * 得到谷歌程序地址
     *
     * @return
     * @throws Exception
     */
    private static String GetChromePath() throws Exception {
        String path = GetExeRegedit("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
        if (path.isEmpty()) {
            path = GetExeRegedit("HKEY_LOCAL_MACHINE\\HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
        }
        if (!path.isEmpty()) {
            path += "\\chrome.exe";
        }
        return path;
    }

    /**
     * 得到注册表值
     *
     * @param path 执行路径
     * @return
     * @throws Exception
     */
    private static String GetExeRegedit(String path) throws Exception {
        Process ps = null;
        //当路径中有空格时,要把路径打上引号。
        ps = Runtime.getRuntime().exec("reg query \"" + path + "\"");
        ps.getOutputStream().close();
        InputStreamReader i = new InputStreamReader(ps.getInputStream());
        String line;
        BufferedReader ir = new BufferedReader(i);
        String ret = "";
        while ((line = ir.readLine()) != null) {
            if (line.contains("Path")) {
                String[] arr = line.split("    ");
                ret = arr[arr.length - 1];
            }
        }
        return ret;
    }
}





我以前理解的和spring.net差不多的,配置一堆容器XML,搞多层。因为亲自经历过那种工程的失败,以及后面我推广的简化版Spring.net也因为维护麻烦被架空。实践springboot之后只能说比以前的有过之而无不及,工程和结构起码复杂了几倍的难度,没办法,谁让互联网大、分工详细的呢。传统软件生搬硬套只能说是在找死,哈哈哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1394118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

竞赛保研 大数据房价预测分析与可视

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 大数据房价预测分析与可视 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 该项目较为新颖,适合…

如何保证HUAWEI交换机成功使用ssh登录?

1)telnet 部分配置4行 telnet server enable telnet server-source all-interface local-user admin service-type telnet ssh stelnet server enable 2)ssh local-user admin service-type telnet ssh ssh server-source all-interface ssh server c…

Windows pip install -r requirements.txt 太慢

目录 解决方案一: 解决方案二: 下载单个包时切换源: 解决方案一: 1、在虚拟环境中切换下载的源: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 2、当出现有pip.txt文件写入时&…

解决springboot启动报Failed to start bean ‘subProtocolWebSocketHandler‘;

解决springboot启动报 Failed to start bean subProtocolWebSocketHandler; nested exception is java.lang.IllegalArgumentException: No handlers 问题发现问题解决 问题发现 使用springboot整合websocket,启动时报错,示例代码: EnableW…

XSS漏洞:xss.haozi.me靶场通关

xss系列往期文章: 初识XSS漏洞-CSDN博客 利用XSS漏洞打cookie-CSDN博客 XSS漏洞:xss-labs靶场通关-CSDN博客 XSS漏洞:prompt.mi靶场通关-CSDN博客 目录 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C…

QT第六天

要求&#xff1a;使用QT绘图&#xff0c;完成仪表盘绘制&#xff0c;如下图。 素材 运行效果&#xff1a; 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QPen>QT_BEGIN_NAMESPACE name…

克魔助手工具详解、数据包抓取分析、使用教程

目录 摘要 引言 克魔助手界面 克魔助手查看数据捕获列表 数据包解析窗口 数据包数据窗口 克魔助手过滤器表达式的规则 抓包过滤器实例 总结 参考资料 摘要 本文介绍了克魔助手工具的界面和功能&#xff0c;包括数据包的捕获和分析&#xff0c;以及抓包过滤器的使用方…

Docker之安装Nginx

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Docker之Dockerfile构建镜像》。&#x1f3af;&…

软件测试|深入了解Python中的super()函数用法

简介 Python中的super()函数是一种强大的工具&#xff0c;用于在子类中调用父类的方法。它在面向对象编程中非常有用&#xff0c;可以让你轻松地扩展和重用现有的类。本文将详细介绍super()函数的用法&#xff0c;并提供一些示例来帮助你更好地理解它的功能。 什么是super()函…

C#中的文件操作

为什么要对文件进行操作&#xff1f; 在计算机当中&#xff0c;数据是二进制的形式存在的&#xff0c;文件则是用于存储这些数据的单位&#xff0c;因此在需要操作计算机中的数据时&#xff0c;需要对文件进行操作。 在程序开发过程中&#xff0c;操作变量和常量的时候&#…

Kotlin学习最快速的方式

引言: 前段时间在一个技术交流群看到一句话:"在我面试的过程中,遇到一位面试者,做ios开发的,Swift 语言出来4-5年了,30多岁的人,连这个都不会";今天再次回想了这句话,说的不正我这样的人吗?一个之前做Anroid应用开发的,现在连Kotlin都不会;做技术的,还是要紧跟时代…

基于YOLOv8深度学习的智能肺炎诊断系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

数组中第K个最大元素(算法村第十关白银挑战)

215. 数组中的第K个最大元素 - 力扣&#xff08;LeetCode&#xff09; 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 **k** 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现…

Leetcode刷题-(1~5)-Java+Python+JavaScript

算法题是程序员的基本功&#xff0c;也是各个大厂必考察的重点&#xff0c;让我们一起坚持写算法题吧 遇事不决&#xff0c;可问春风&#xff0c;春风不语&#xff0c;即是本心。 我们在我们能力范围内&#xff0c;做好我们该做的事&#xff0c;然后相信一切都事最好的安排就…

【AI接口】语音版、文心一言大模型和AI绘图、图片检测API

文章目录 一、语音版大模型AI1、接口2、请求参数3、请求参数示例4、接口返回示例 二、AI图片鉴黄合规检测API1、接口2、请求参数3、请求参数示例4、接口返回示例5、报错说明6、代码开源 三、人工智能AI绘画API1、接口2、请求参数3、请求参数示例4、接口返回示例5、AI绘画成果展…

rabbitmq-java基础详解

一、rabbitmq是什么&#xff1f; 1、MQ定义 MQ&#xff08;Message Queue&#xff09;消息队列 主要解决&#xff1a;异步处理、应用解耦、流量削峰等问题&#xff0c;是分布式系统的重要组件&#xff0c;从而实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性的架…

LabVIEW精确测量产品中按键力和行程

项目背景 传统的按键测试方法涉及手工操作&#xff0c;导致不一致和效率低下。在汽车行业中&#xff0c;带有实体按键的控制面板非常常见&#xff0c;确保一致的按键质量至关重要。制造商经常在这些组件的大规模、准确测试中遇到困难。显然&#xff0c;需要一个更自动化、精确…

Unity3D和three.js的比较

一、Unity3D和three.js简介 Unity3D是一款跨平台的游戏引擎,可以用于开发2D和3D游戏。它提供了一个可视化的开发环境,包含了强大的编辑器和工具,使开发者可以方便地创建游戏场景、添加物体、设置物理效果、编写脚本等。Unity3D支持多种平台,包括PC、移动设备、主机等,可以…

uniapp uni.chooseLocation调用走失败那里,错误码:112

问题&#xff1a;我配置了百度上所有能配置的&#xff0c;一直调用不成功&#xff0c;如下图配置的 1:第一个 配置 代码&#xff1a; "permission": {"scope.userLocation": {"desc": "你的位置信息将用于小程序位置接口的效果展示"}…

华为设备NAT的配置

实现内网外网地址转换 静态转换 AR1&#xff1a; sys int g0/0/0 ip add 192.168.10.254 24 int g0/0/1 ip add 22.33.44.55 24 //静态转换 nat static global 22.33.44.56 inside 192.168.10.1 动态转换 最多有两台主机同时访问外网 AR1&#xff1a; sys int g0/0/0 ip add…