Tomcat 原理、调优和错误汇总

本地环境:Tomcat 6、Windows 10、Java 1.7、myeclipse 10

一、使用方法

1.1 Tomcat 部署静态页面

参考链接:https://blog.youkuaiyun.com/qq_32786873/article/details/79609314

二、使用错误

2.1 503 Service Unavailable

原因:在这里插入图片描述

2.2 The web application [/project-name] registered the JDBC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

或者The web application [/project-name] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
可能存在的问题

  • 数据库账号密码错误
  • 有多个数据库配置源
  • jar包问题,把连接jdbc的jar包,拷贝到tomcate的lib目录下就可以了,如:ojdbc14.jar
  • 服务器内存冲突,重启系统
  • Tomcat内存不够
    Window->Preferences->tomcat 点击右侧的按钮,
    Creat Launch Configuration,在你对应的tomcat属性Aarguments下面添加一句话:
    -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=256m
  • 误报:https://github.com/alibaba/druid/issues/1699

实现ServletContextListener,然后再contextDestroyed()方法中添加如下代码:

Enumeration drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
logger.info(String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
e.printStackTrace();
logger.error(String.format("deregistering jdbc driver: %s", driver));
}
}

最后在web.xml中注册自己的监听器,问题解决。

2.3 lib1.so: lib2.so: 无法打开共享对象文件: 没有那个文件或目录

(1)如果共享库文件安装到了/lib或/usr/lib目录下, 那么需执行一下ldconfig命令
(2)

   # cat /etc/ld.so.conf
    include ld.so.conf.d/*.conf
    # echo "/usr/local/lib" >> /etc/ld.so.conf
    # ldconfig

(3) export LD_LIBRARY_PATH=…/webapps/项目名称/WEB-INF/classes

参考链接:https://www.cnblogs.com/Anker/p/3209876.html

2.4 严重: Failed to initialize connector [Connector[AJP/1.3-8008]]

解决方法: 修改两个Tomcat的Connector port,保持不同。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8081" />

2.5 严重: StandardServer.await: create[localhost:8080]: java.net.BindException: Address already in use: JVM_Bind

场景:启动两个Tomcat时报错。
原因分析:暂时未明。
解决方法: 修改Connector port为不同值,无用。

 <Connector port="8008" protocol="AJP/1.3" redirectPort="8081" />

修改server port即可,保持两个Tomcat不同,但是会报 2.4 错误。

<Server port="8080" shutdown="SHUTDOWN">

myeclipse修改代码后无法实时加载到tomcat

暂未解决

三、原理

概述

HTTP server主要用来给浏览器等客户端提供静态资源的访问功能,还有代理服务器、负载均衡等功能。当然,通过CGI/Servlet技术,也可以将处理过的动态内容通过HTTP Server分发,但是一个HTTP Server始终只是把服务器上的文件如实的通过HTTP协议传输给客户端。

而tomcat属于application server,也是绑定服务器IP并监听TCP端口。它实现了部分HTTP server的功能,没有nginx和Apache的功能丰富。主要用于处理动态内容。没有提供java EE规范,如下图:
在这里插入图片描述

架构

两大核心部分connector(连接器)和container(容器)。

tomcat的work目录是工作目录,在浏览器访问jsp =》java=》.class。tomcat定时扫描work目录,不是实时的,因此修改jsp文件后不会立马生效,可以立即删除work目录。

针对由jsp转换成的java文件,比如my-jsp.java,tomcat编译支持的文件大小最大为64k。改进:1.把jsp中的业务逻辑写入单独的类,在jsp中通过调用这个类的静态方法来执行;2.将jsp页面中的js提取出来放到单独的js文件内。

AJP协议:二进制协议
客户端< - http / s->代理< - http / s - >应用

VS

客户端< - http / s->代理< - AJP - >应用

xshell 关闭后 linux的tomcat断掉解决

方法一:
输入命令

nohup ./catalina.sh run &
显示为:

[1]8579

如何关掉?

输入命令查看进程号

ps -ef |grep tomcat

显示处root 456 33345 99。。。省略

其中33345为端口号

输入命令结束进程 kill -9 进程号

kill -9 33345

方法二:
启动方式
(1)Catania
(2)startup
使用startup方式启动tomcat,tomcat运行不受shell影响。

Several ports (8005, 8080, 8009) required by Tomcat Server at localhost are already in use
方法一:进入tomcat bin目录执行shutdown.sh或者shutdown.bat。
方法二:进一步排查——任务管理器或者命令行kill杀掉Java、tomcat相关进程,重启eclipse。

tomcat 调优

动静分离
nginx+tomcat,使用nginx实现静态资源的访问,tomcat处理jsp。

tomcat线程池
打开tomcat的server.xml
配置Executor
​​<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4" maxIdLeTime="60000"/>

参数解释
name
给执行器(线程池)起一个名字
namePrefix
指定线程池中的每一个线程的name前缀
maxThreads
线程池中最大的线程数量
假设:请求的数量超过了“750”,这将不是意味着将maxThreads属性值设置为“750”,它的最好解决方案是使用“Tomcat集群”。
也就是说,如果有“1000”请求,两个Tomcat实例设置“maxThreads= 500”,而不在单Tomcat实例的情况下设置maxThreads=1000。
minSpareThreads
线程池中允许空闲的线程数量(多余的线程都杀死)
maxIdLeTime
一个线程空闲多久算是一个空闲线程
其他的配置其实阅读官方文档是最好的。

    <Connector port="8081" protocol="HTTP/1.1" executor = "tomcatThreadPool"
               connectionTimeout="20000"
               redirectPort="8443" enableLookups="false"/>

enableLookups="false"
关闭dns解析,减少性能损耗
minProcessors
服务器启动时创建的最少线程数
maxProcessors
最大可以创建的线程数
acceptCount=“1000”
线程池中的线程都被占用,允许放到队列中的请求数
maxThreads=“3000”
最大线程数
minSpareThreads=“20”
最小空闲线程数,这里是一直会运行的线程
和压缩有关系的配置

通过修改tomcat的运行模式

BIO
Tomcat8以下版本,默认使用的就是BIO(阻塞式IO)模式。
对于每一个请求都要创建一个线程来进行处理,不适合高并发。
修改:protocol='org.apache.coyote.http11.Http11NioProtocol'

APR(Apache Portable Runtime)
是Tomcat生产环境运行的首选方式
如果操作系统未安装apr或者apr路径未指到Tomcat默认可识别的路径,
则apr模式无法启动,自动切换启动nio模式。
所以必须要安装apr和native,直接启动就支持apr
apr是从操作系统级别解决异步IO问题,apr的本质就是使用jni(java native interface)
技术调用操作系统底层的IO接口,所以需要提前安装所需要的依赖
提升Tomcat对静态文件的处理性能,当然也可以采用动静分离。

禁用AJP连接器 Apache JServer Protocol
使用Nginx+tomcat的架构,所以用不着AJP协议,所以把AJP连接器禁用

Linux 下修改 TOMCAT_HOME/bin/catalina.sh,在其中加入,可以放在 CLASSPATH = 下面:

JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m"
windows 下修改 TOMCAT_HOME/bin/catalina.bat,在其中加入,可以放在 set CLASSPATH = 下面:

set JAVA_OPTS=-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m
这些参数在我们学习 JVM 部分文章时已经都认识过了,不过这里还是简单介绍下:

-server:启用 JDK的 server 版本;
-Xms:Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;
-Xmx:Java虚拟机可使用堆的最大内存;
-XX:PermSize:Java虚拟机永久代大小;
-XX:MaxPermSize:Java虚拟机永久代大小最大值;

线程池配置

<Executor name="tomcatThreadPool"   
       namePrefix="catalina-exec-"   
      maxThreads="1000"   
        minSpareThreads="100"  
        maxIdleTime="60000"  
       maxQueueSize="Integer.MAX_VALUE"  
       prestartminSpareThreads="false"  
        threadPriority="5"  
        className="org.apache.catalina.core.StandardThreadExecutor"/> 

name:线程池名称,用于 Connector中指定。 namePrefix:所创建的每个线程的名称前缀,一个单独的线程名称为
namePrefix+threadNumber。 maxThreads:池中最大线程数。
minSpareThreads:活跃线程数,也就是核心池线程数,这些线程不会被销毁,会一直存在。
maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒。
maxQueueSize:在被执行前最大线程排队数目,默认为Int的最大值,也就是广义的无限。除非特殊情况,这个值不需要更改,否则会有请求不会被处理的情况发生。
prestartminSpareThreads:启动线程池时是否启动 minSpareThreads部分线程。默认值为false,即不启动。
threadPriority:线程池中线程优先级,默认值为5,值从1到10。
className:线程池实现类,未指定情况下,默认实现类为org.apache.catalina.core.StandardThreadExecutor。如果想使用自定义线程池首先需要实现
org.apache.catalina.Executor接口。

线程池配置完成后需要在 Connector 中指定:

<Connector executor="tomcatThreadPool"  
...  

<Connector port="9027"
      ...........
      compression="on"
      compressionMinSize="2048"
    connectionTimeout="20000"
    compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
    ................
      />

compression 打开压缩功能
  compressionMinSize 启用压缩的输出内容大小,这里面默认为2KB
  compressableMimeType 压缩类型
  connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间

参考链接:1.Tomcat 性能优化——
https://gitbook.cn/books/5ad3405a1b0f9f64ea5f7758/index.html#writeCommentDiv

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值