Jetty启动项目失败?两个命令解决address already in use问题

Jetty启动项目失败?两个命令解决address already in use问题,第1张

在使用Idea开发Java项目时常常选中Jetty作为我们本地运行项目的Web容器。当我们执行了jetty run后,若Idea被非正常地关闭了,可能出现Idea关闭了但Jetty仍在运行的情况。这时候如果我们重新打开Idea,再次执行jetty run时就会报错:

以下为在Windows系统下的解决方法。只需要执行两个命令即可。

假如我是在80端口启动了jetty,那么打开windwos“命令提示符”窗口,输入以下命令:

解释一下,netstat -ano是列出系统当前所有端口的占用情况。但这个列表往往较长,我们想要找到自己要的并不容易。所以才有了命令的后边部分——findstr "80"。findstr命令搜索符合条件的结果,为我们过滤掉大部分的内容,这样就容易找到我们需要的80端口占用情况。

netstat和findstr命令之间有个“|”,这个竖杠表示将netstat命令的结果作为findstr命令的输入。这种写法在Linux系统中也比较常见。

执行此命令的输出结果示例如下:

我们看到输出结果一共有5列,分别是:协议、本地地址、外部地址、状态、PID。其中本地地址为“127.0.0.1:80”的为我们要找的,其对应的PID是10468。

使用命令一我们拿到了占用端口的进程的PID,10468。再执行以下命令杀死进程即可。

其中PID用于指定进程ID,F选项意思是强制结束进程

拿到进程的PID后,如果想进一步了解其对应的程序名称,可以使用以下命令:如PID是4832

其输出结果为:

在 Servers 视图中右击 New Server 项目找 ”Download Additional Server“看看有没有 Jetty 插件,如果没有的话,需要手工处理,这需要你很了解如何手工从命令行启动一个 Java 程序同时指定各种各样的参数给它。如果你知道这个步骤的话,你只需要去 Microsoft 网站上下载一个 Process Explorer NT 的工具,先从你的 Jetty 目录下双击一个 bat 文件启动 jetty 服务器,然后用 Process Explorer NT 观察它的完整命令行参数,复制下来之后去 Eclipse 中添加一个 Java Application 类型的 Launching 配置,手工把它的 main class 和各种参数加上去,让它运行起来跟你双击 bat 文件时得到的命令行是一样就可以了。

理论上讲 jetty 是一个 Java 程序,因此只要我们从 Eclipse 启动 Jetty 的命令行参数和双击 bat 文件启动时是一样的话,结果就是一样的,你也一样地可以在 Eclipse 中 debug 它。 只不过没有插件的话,可能部署过程需要手工复制 war 包。

概括一下 Tomcat 和 Jetty 两者最大的区别。大体来说,Tomcat 的核心竞争力是 成熟稳定 ,因为它经过了多年的市场考验,应用也相当广泛,对于比较复杂的企业级应用支持得更加全面。也因为如此,Tomcat 在整体结构上比 Jetty 更加复杂,功能扩展方面可能不如 Jetty 那么方便。

而 Jetty 比较年轻,设计上更加 简洁小巧 ,配置也比较简单,功能也支持方便地扩展和裁剪,比如我们可以把 Jetty 的 SessionHandler 去掉,以节省内存资源,因此 Jetty 还可以运行在小型的嵌入式设备中,比如手机和机顶盒。当然,我们也可以自己开发一个 Handler,加入 Handler 链中用来扩展 Jetty 的功能。值得一提的是,Hadoop 和 Solr 都嵌入了 Jetty 作为 Web 服务器。

从设计的角度来看,Tomcat 的架构基于一种多级容器的模式,这些容器组件具有父子关系,所有组件依附于这个骨架,而且这个骨架是不变的,我们在扩展 Tomcat 的功能时也需要基于这个骨架,因此 Tomcat 在设计上相对来说比较复杂。当然 Tomcat 也提供了较好的扩展机制,比如我们可以自定义一个 Valve,但相对来说学习成本还是比较大的。而 Jetty 采用 Handler 责任链模式。由于 Handler 之间的关系比较松散,Jetty 提供 HandlerCollection 可以帮助开发者方便地构建一个 Handler 链,同时也提供了 ScopeHandler 帮助开发者控制 Handler 链的访问顺序。

说了一堆理论,你可能觉得还是有点抽象,接下来我们通过一个实例,来压测一下 Tomcat 和 Jetty,看看在同等流量压力下,Tomcat 和 Jetty 分别表现如何。需要说明的是,通常我们从吞吐量、延迟和错误率这三个方面来比较结果。

首先用 Spring Boot 默认的 Tomcat 作为内嵌式 Web 容器,经过一轮压测后,将内嵌式的 Web 容器换成 Jetty,再做一轮测试,然后比较结果。为了方便观察各种指标,在本地开发机器上做这个实验。

我们会在每个请求的处理过程中休眠 1 秒,适当地模拟 Web 应用的 I/O 等待时间。JMeter 客户端的线程数为 100,压测持续 10 分钟。在 JMeter 中创建一个 Summary Report,在这个页面上,可以看到各种统计指标。

第一步,压测 Tomcat。启动 Spring Boot 程序和 JMeter,持续 10 分钟,以下是测试结果,结果分为两部分:

第二步,我们将 Spring Boot 的 Web 容器替换成 Jetty,具体步骤是在 pom.xml 文件中的 spring-boot-starter-web 依赖修改下面这样:

编译打包,启动 Spring Boot,再启动 JMeter 压测,以下是测试结果:

下面我们通过一个表格来对比 Tomcat 和 Jetty:

从表格中的数据我们可以看到:

当然由于测试场景的限制,以上数据并不能完全反映 Tomcat 和 Jetty 的真实能力。但是它可以在我们做选型的时候提供一些参考:如果系统的目标是资源消耗尽量少,并且对稳定性要求没有那么高,可以选择轻量级的 Jetty;如果你的系统是比较关键的企业级应用,建议还是选择 Tomcat 比较稳妥。

最后用一句话总结 Tomcat 和 Jetty 的区别:Tomcat 好比是一位工作多年比较成熟的工程师,轻易不会出错、不会掉链子,但是他有自己的想法,不会轻易做出改变。而 Jetty 更像是一位年轻的后起之秀,脑子转得很快,可塑性也很强,但有时候也会犯一点小错误。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11441834.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-16
下一篇2023-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存