【tomcat】5、调优

  • 系列文章目录:https://blog.csdn.net/hancoder/category_10106944.html
  • 0 sevlet的知识,从上面目录中找
  • 1 tomcat的安装与目录结构:https://blog.csdn.net/hancoder/article/details/106765035
  • 2 tomcat源码环境搭建: https://blog.csdn.net/hancoder/article/details/113064325
  • 3 tomcat架构与参数:https://blog.csdn.net/hancoder/article/details/113065917
  • 4 tomcat源码分析:https://blog.csdn.net/hancoder/article/details/113062146
  • 5 tomcat调优:https://blog.csdn.net/hancoder/article/details/113065948

5 Web 应用配置

web.xml 是web应用的描述文件, 它支持的元素及属性来自于Servlet 规范定义 。 在 Tomcat 中, Web 应用的描述信息包括

  • tomcat/conf/web.xml 中默认配置
  • 以及 Web 应用 WEB-INF/web.xml 下的定制配置。

5.1 ServletContext 初始化参数

我们可以通过<context‐param>添加ServletContext 初始化参数,它配置了一个键值对,这样我们可以在应用程序中使用

javax.servlet.ServletContext.getInitParameter()方法获取参数。 即req.getServletContext().getInitParameter("")

<context‐param>
    <param‐name>contextConfigLocation</param‐name>
    <param‐value>classpath:applicationContext‐*.xml</param‐value>
    <description>Spring Config File Location</description>
</context‐param>

5.2 会话配置

<session‐config>用于配置Web应用会话,包括 超时时间、Cookie配置以及会话追踪模式。它将覆盖 server.xml 和 context.xml 中的配置。

HTTP是无状态的,并不知道是否是同一用户

所以我们使用的是session+cookie的形式

cookie默认的名称是JSESSIONID

<session‐config>
    <session‐timeout>30</session‐timeout>
    <cookie‐config>
        <name>JESSIONID</name>
        <domain>www.itcast.cn</domain>
        <path>/</path>
        <comment>Session Cookie</comment>
        <http‐only>true</http‐only>
        <secure>false</secure>
        <max‐age>3600</max‐age>
        </cookie‐config>
    <tracking‐mode>COOKIE</tracking‐mode>
    </session‐config>

配置解析:

1) session‐timeout : 会话超时时间,单位 分钟

2) cookie‐config: 用于配置会话追踪Cookie

  • name:Cookie的名称

    扫描二维码关注公众号,回复: 12424060 查看本文章
  • domain:Cookie的域名

  • path:Cookie的路径

  • comment:注释

  • http‐only:cookie只能通过HTTP方式进行访问,JS无法读取或修改,此项可以增加网站访问的安全性。

  • secure:如果是true,此cookie只能通过HTTPS连接传递到服务器,而HTTP 连接则不会传递该信息。注意是从浏览器传递到服务器,服务器端的Cookie对象不受此项影响。

  • max‐age:以秒为单位表示cookie的生存期,默认为‐1表示是会话Cookie,浏览器关闭时就会消失。

    3) tracking‐mode :用于配置会话追踪模式,Servlet3.0版本中支持的追踪模式: COOKIE、URL、SSL

  • COOKIE : 通过HTTP Cookie 追踪会话是最常用的会话追踪机制, 而且Servlet规范也要求所有的Servlet规范都需要支持Cookie追踪。

  • URL : URL重写是最基本的会话追踪机制。当客户端不支持Cookie时,可以采用URL重写的方式。当采用URL追踪模式时,请求路径需要包含会话标识信息,Servlet容器会根据路径中的会话标识设置请求的会话信息。如: http://www.myserver.com/user/index.html;jessionid=1234567890。

  • SSL : 对于SSL请求, 通过SSL会话标识确定请求会话标识。

req.getSession().getId()

谷歌浏览器的F11 Application里能看到

5.3 Servlet配置

Servlet 的配置主要是两部分, serv let 和 servlet-mapping :

<servlet>
    <servlet‐name>myServlet</servlet‐name>
    <servlet‐class>cn.itcast.web.MyServlet</servlet‐class>
    <init‐param>
        <param‐name>fileName</param‐name>
        <param‐value>init.conf</param‐value>
        </init‐param>
    <load‐on‐startup>1</load‐on‐startup>
    <enabled>true</enabled>
</servlet>

<servlet‐mapping>
    <servlet‐name>myServlet</servlet‐name>
    <url‐pattern>*.do</url‐pattern>
    <url‐pattern>/myservet/*</url‐pattern>
    </servlet‐mapping>

配置说明:

  • servlet‐name : 指定servlet的名称, 该属性在web.xml中唯一。
  • servlet‐class : 用于指定servlet类名
  • init‐param: 用于指定servlet的初始化参数, 在应用中可以通过HttpServlet.getInitParameter 获取。
  • load‐on‐startup: 用于控制在Web应用启动时,Servlet的加载顺序。 值小于0,web应用启动时,不加载该servlet,第一次访问时加载。
  • enabled: true , false 。 若为false ,表示Servlet不处理任何请求。
  • url‐pattern: 用于指定URL表达式,一个 servlet‐mapping可以同时配置多个 url‐ pattern。
Servlet 中文件上传配置:
<servlet>
    <servlet‐name>uploadServlet</servlet‐name>
    <servlet‐class>cn.itcast.web.UploadServlet</servlet‐class>
    <multipart‐config>
        <location>C://path</location>
        <max‐file‐size>10485760</max‐file‐size>
        <max‐request‐size>10485760</max‐request‐size>
        <file‐size‐threshold>0</file‐size‐threshold>
        </multipart‐config>
</servlet>

配置说明:

1) location:存放生成的文件地址。

2) max‐file‐size:允许上传的文件最大值。 默认值为‐1, 表示没有限制。

3) max‐request‐size:针对该 multi/form‐data 请求的最大数量,默认值为‐1, 表示 无限制。

4) file‐size‐threshold:当数量量大于该值时, 内容会被写入文件。

5.4 Listener配置

Listener用于监听serv let 中的事件,例如context 、request 、session对象的创建、修 改、删除,并触发响应事件。Listener是观察者模式的实现,在servlet 中主要用于对 context 、request 、session对象的生命周期进行监控。在servlet2.5规范中共定义了8种 Listener。在启动时,ServletContextListener 的执行顺序与web.xml 中的配置顺序一致, 停止时执行顺序相反。

<listener>
    <listener‐class>org.springframework.web.context.ContextLoaderListener</listener‐class>
</listener>

5.5 Filter配置

filter 用于配置web应用过滤器, 用来过滤资源请求及响应。 经常用于认证、日志、加密、数据转换等操作,

  • 在 HttpServletRequest到达 Servlet之前,拦截客户的 HttpServletRequest:根据需要检查 HttpServletRequest,也可以修改 HttpServletRequest头和数据
  • 在 HttpServletResponse到达客户端之前,拦截 HttpServletResponse:根据需要检查 HttpServletResponse,也可以修改 HttpServletResponse头和数据

配置如下:

<filter>
    <filter‐name>myFilter</filter‐name>
    <filter‐class>cn.itcast.web.MyFilter</filter‐class>
    <async‐supported>true</async‐supported>
    <init‐param>
        <param‐name>language</param‐name>
        <param‐value>CN</param‐value>
        </init‐param>
</filter>
<filter‐mapping>
    <filter‐name>myFilter</filter‐name>
    <url‐pattern>/*</url‐pattern>
    </filter‐mapping>

配置说明:

1) filter‐name: 用于指定过滤器名称,在web.xml中,过滤器名称必须唯一。

2) filter‐class : 过滤器的全限定类名, 该类必须实现Filter接口。

3) async‐supported: 该过滤器是否支持异步

4) init‐param :用于配置Filter的初始化参数, 可以配置多个, 可以通过 FilterConfig.getInitParameter获取

5) url‐pattern: 指定该过滤器需要拦截的URL。

5.6 欢迎页面配置

welcome-file-list 用于指定web应用的欢迎文件列表。 尝试请求的顺序,从上到下。

<welcome‐file‐list>
    <welcome‐file>index.html</welcome‐file>
    <welcome‐file>index.htm</welcome‐file>
    <welcome‐file>index.jsp</welcome‐file>
 </welcome‐file‐list>

5.7 错误页面配置

error-page 用于配置Web应用访问异常时定向到的页面,支持HTT P响应码和异常类两种形式。

<error‐page>
    <error‐code>404</error‐code>
    <location>/404.html</location>
    </error‐page>
<error‐page>
    <error‐code>500</error‐code>
    <location>/500.html</location>
    </error‐page>

<error‐page>
    <exception‐type>java.lang.Exception异常类型</exception‐type>
    <location>/error.jsp</location>
    </error‐page>

6.Tomcat 管理配置

从早期的Tomcat版本开始,就提供了Web版的管理控制台,他们是两个独立的Web应用,位于webapps 目录下。Tomcat 提供的管理应用有用于管理的Host 的host-manager和用于管理Web应用的manager

6.1 host-manager

Tomcat启动之后,可以通过 http://localhost:8080/host-manager/html 访问该Web应用。

host-manager 默认添加了访问权限控制,当打开网址时,需要输入用户名和密码 (conf/tomcat-users.xml中配置) 。

所以要想访问该页面,需要在conf/tomcat-users.xml 中配置,并分配对应的角色:

1) admin-gui:用于控制页面访问权限

2 )admin-script :用于控制以简单文本的形式进行访问

配置如下:

<role rolename="admin‐gui"/>
<role rolename="admin‐script"/>
<user username="itcast" password="itcast" roles="admin‐script,admin‐gui"/>

登录后,就可以看到我们配置的host标签了。如果我们关掉一个后,他讲访问默认的host。也可以动态添加

6.2 manager

manager的访问地址为 http://localhost:8080/manager, 同样, manager也添加了页面访问控制,因此我们需要为登录用户分配角色为:

<role rolename="manager‐gui"/>
<role rolename="manager‐script"/>
<user username="itcast"
      password="itcast" 
      roles="admin‐script,admin‐gui,manager‐gui,manager‐script"/>

就可以看到web应用了

在可以在Server Status中看到

  • OS:内存信息
  • JVM:GC
  • 线程池

7.JVM 配置

最常见的JV M配置当属内存分配,因为在绝大多数情况下,JV M默认分配的内存可能不能够满足我们的需求,特别是在生产环境,此时需要手动修改Tomcat启动时的内存参数分配。

7.1 JVM内存模型图

7.2 JVM配置选项

编辑启动文件的内容:

  • windows 平台(catalina.bat) :
set JAVA_OPTS=‐server  ‐Xms2048m  ‐Xmx2048m  ‐XX :MetaspaceSize=256m ‐XX :MaxMetaspaceSize=256m ‐XX :SurvivorRatio=8 
  • linux 平台(catalina.sh) :
JAVA_OPTS="‐server ‐Xms1024m ‐Xmx2048m ‐XX :MetaspaceSize=256m -XX :MaxMetaspaceSize=512m  ‐XX :SurvivorRatio=8" 

参数说明 :

序号 参数 含义
1 -Xms 堆内存的初始大小
2 -Xmx 堆内存的最大大小。和上面一致就不会再运行中变化了,推荐
3 -Xmn 新生代的内存大小,官方建议是整个堆的 3/8。
4 -XX:MetaspaceSize 元空间内存初始大小, 在JDK1.8版本之前配置为 -XX:PermSize(永久代)
5 -XX:MaxMetaspaceSize 元空间内存最大大小, 在JDK1.8版本之前配置为 -XX:MaxPermSize(永久代)
6 -XX:InitialCodeCacheSize - XX:ReservedCodeCacheSize 代码缓存区大小
7 -XX:NewRatio 设置新生代和老年代的相对大小比例。这种方式的优点是新生代大小会随着整个堆大小动态扩展。如 -XX:NewRatio=3 指定老年代:新生代为 3:1。 老年代占堆大小的 3/4,新生代占 1/4 。
8 -XX:SurvivorRatio 指定伊甸园区 (Eden) 与幸存区大小比例。如 -XX:SurvivorRatio=10 表示伊甸园区 (Eden)是 幸存区 To 大小的 10 倍 (也是幸存区 From的 10 倍)。 所以, 伊甸园区 (Eden) 占新生代大小的 10/12, 幸存区 From 和幸存区 To 每个占新生代的 1/12 。 注意, 两个幸存区永远是一样大的。

Tomcat 集群

8.1 简介

由于单台Tomcat 的承载能力是有限的,当我们的业务系统用户量比较大,请求压力比较大时,单台Tomcat是扛不住的,这个时候,就需要搭建Tomcat 的集群,而目前比较流程的做法就是通过Nginx来实现Tomcat集群的负载均衡。

				tomcat1
客户端--->Nginx-->
				tomcat2

8.2 环境准备

8.2.2 准备Tomcat

在服务器上, 安装两台tomcat, 然后分别改Tomcat服务器的端口号 :

  8005 ‐‐‐‐‐‐‐‐‐>8015 ‐‐‐‐和‐‐‐>8025  

  8080 ‐‐‐‐‐‐‐‐‐>8888 ‐‐‐‐和‐‐‐>9999   

  8009 ‐‐‐‐‐‐‐‐‐>8019 ‐‐‐‐和‐‐‐>8029 

8.2.3 安装配置Nginx

在当前服务器上 , 安装Nginx , 然后再配置Nginx, 配置nginx.conf :

upstream serverpool{
    
    
    server localhost:8888; 
    server localhost:9999;
}
server {
    
    
    listen 99;
    server_name localhost;
    location / {
    
    
        proxy_pass http://serverpool/;
    }
}
proxy_pass指定了声明的upstream

1 负载均衡策略

1). 轮询

最基本的配置方法,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。

upstream serverpool{  
      server localhost:8888;  
      server localhost:9999;  
} 

参数说明:

参数 描述
fail_timeout 与max_fails结合使用
max_fails 设置在fail_timeout参数设置的时间内最大失败次数,如果在这个时间内,所有针对该服务器的请求都失败了,那么认为该服务器会被认为是停机了
fail_time 服务器会被认为停机的时间长度,默认为10s
backup 标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里
down 标记服务器永久停机了
2). weight权重

权重方式,在轮询策略的基础上指定轮询的几率。

upstream serverpool{
    
      
    server localhost:8888 weight=3;  
    server localhost:9999 weight=1;  
} 

weight参数用于指定轮询几率,weight 的默认值为1;weight 的数值与访问比率成正比,比如8888服务器上的服务被访问的几率为9999服务器的三倍。

此策略比较适合服务器的硬件配置差别比较大的情况。

3). ip_hash

指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。

upstream serverpool{
    
      
    ip_hash;  
    server 192.168.192.133:8080;
    server 192.168.192.137:8080;  
} 

2 Session共享方案

在Tomcat集群中,如果应用需要用户进行登录,那么这个时候,用于tomcat做了负载均衡,则用户登录并访问应用系统时,就会出现问题 。

解决上述问题, 有以下几种方案:

8.4.1 ip_hash 策略

利用上面负载均衡算法的哈希算法

一个用户发起的请求,只会请求到tomcat1上进行操作,另一个用户发起的请求只在 tomcat2上进行操作 。那么这个时候,同一个用户发起的请求,都会通过nginx 的 ip_hash策略,将请求转发到其中的一台Tomcat上。

8.4.2 Session复制

在serv let_demo01 工程中 , 制作session.j sp页面,分别将工程存放在两台 tomcat 的 webapps/ 目录下:

<%@ page contentType="text/html;charset=UTF‐8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        TOMCAT ‐ 9999 :  
        <br/>
        sessionID  : <%=session.getId()%>
        <br/>
        <% Object loginUser = session.getAttribute("loginUser"); 

        if(loginUser  != null && loginUser.toString().length()>0){ 
            out.println("session 有值, loginUser = " + loginUser); 
        }else{ 
            session.setAttribute("loginUser","ITCAST"); 
            out.println("session 没有值"); 
        } 
        %>
    </body>
</html>

通过nginx访问 , http://localhost:99/demo01/session.jsp ,访问到的两台Tomcat 出现的sessionID是不一样的:

上述现象,则说明两台Tomcat 的Session各是各的,并没有进行同步,这在集群环境下是存在问题的。

Session同步的配置如下:

1) 在Tomcat 的conf/server.xml 配置如下:

Engine标签下
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

2 ) 在Tomcat部署的应用程序 servlet_demo01 的web.xml 中加入如下配置 :

<distributable/>

3 ) 配置完毕之后, 再次重启两个 Tomcat服务。

上述方案,适用于较小的集群环境 (节点数不超过4个),如果集群的节点数比较多的话,通过这种广播的形式来完成Session的复制,会消耗大量的网络带宽,影响服务的性能。

8.4.3 SSO单点登录

单点登录 (Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,也是用来解决集群环境Session共享的方案之一 。

  • tomcat发给认证服务,认证服务区找redis

image-20210123034157907

img

配置长连接

1 为什么要配置长连接

一个普通的请求是从按照下图 1->2->3->4 的顺序。从浏览器到 Nginx,再从 Nginx 到 Tomcat。Tomcat 处理完后,再返回给 Nginx,最后再从 Nginx 返回给浏览器。

+------------+          +------------+         +-------------+
|            |    1     |            |   2     |             |
|  浏 览 器   +--------> |   Nginx    +-------> |   Tomcat   |
|            |    4     |            |   3     |             |
|            | <--------+            | <-------+             |
+------------+          +------------+         +-------------+

在这个请求过程中,一般从浏览器到 Nginx 是短连接(就是请求回去后就断开连接),而 Nginx 到 Tomcat 可以是短连接 或是 长连接(请求返回后,连接还保持一段时间)。为什么 Nginx 到 Tomcat 之间要设置成长连接呢?因为连接的创建(三次握手)是需要花费一些时间的,如果请求量非常大,不如像连接池一样保存一定的连接,当有请求进来时复用一些连接。而且还能减少 time wait,关于 time wait 请参看:关于 time wait

一般来说,请求方被请求方都可以主动断开连接。请求方断开连接时机比较好判断,如果要请求的内容都完成了,就可以断开连接了。但被请求方的断开连接的时机就不好判断了,因为被请求方不知道请求方会发多少次请求。所以一般被请求方设置的参数相对多一些,例如:长连接在处理多少次请求后断开、长连接在经过多少秒后断开等等。

下面说一下浏览器->Nginx->Tomcat设置长连接的方法。首先说一下 Nginx 的设置方法。

1,Nginx 设置

1. Nginx - 反向代理
nginx.conf:

http {
    ...
    ##
    # 与Client连接的长连接配置
    ##
    # http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests
    # 设置通过"一个存活长连接"送达的最大请求数(默认是100,建议根据客户端在"keepalive"存活时间内的总请求数来设置)
    # 当送达到单个长连接的请求数超过该值后,该连接就会被关闭。(通过设置为5,验证确实是这样)
    keepalive_requests 8192;

    # http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
    # 第一个参数设置"keep-alive客户端长连接"将在"服务器端"继续打开的超时时间(默认是75秒,
    # 建议根据具体业务要求来,但必须要求所有客户端连接的"Keep-Alive"头信息与该值设置的相同
    # (这里是5分钟),同时与上游服务器(Tomcat)的设置是一样的)
    # 可选的第二个参数设置“Keep-Alive: timeout=time”响应头字段的值。设置第二个参数后,这个时间会实传回给客户端(例如:浏览器)
    keepalive_timeout 300s 300s;

    ...
    include /etc/nginx/web_servers.conf;

}

web_servers.conf:
upstream web_server {
    server 127.0.0.1:8080;

    # http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
    # 连接到 upstream(也就是 Tomcat)的最大并发空闲keepalive长连接数,也就是最多只能创建
    # 这么多长连接,在这之上再创建连接的话,都是短连接。
    #(默认是未设置,建议与Tomcat Connector中的maxKeepAliveRequests值一样)。
    # 如果并发数大于这个数值的话,根据情况可能会创建一些`短连接`来处理请求。可以使用
    # `netstat -an|grep TIME|awk '{if($4~"10001") print}'|wc -l`命令来查看,
    # 其中`10001`是 Nginx 的端口号,改成自己 Nginx 的端口。
    #
    # 当这个数被超过时,使用"最近最少使用算法(LUR)"来淘汰并关闭连接。
    keepalive 8;
}
server {

    listen 80;
    server_name lihg.com www.lihg.com;
    location / {
        proxy_pass http://web_server;
        ##
        # 与上游服务器(Tomcat)建立keepalive长连接的配置,可参考上面的keepalive链接里的
        # "For HTTP"部分
        ##
        # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version
        # 设置代理的HTTP协议版本(默认是1.0版本)
        # 使用keepalive连接的话,建议使用1.1版本。
        proxy_http_version 1.1;

        # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
        # 允许重新定义或追加字段到传递给代理服务器的请求头信息,默认是close。如果把这个 header 设置成空的话,Nginx 会向 Tomcat 传递`close`,这样 Tomcat 就会在处理完请求后关闭连接(这个部分是推理的,没有实际验证是 Tomcat 关的,还是 Nginx 关的)
        proxy_set_header Connection "";
    }
}

上面每个参数的功能都在注释中介绍了,下面简单总结一下使用上注意的地方:

  • keepalive_timeout 和 keepalive_requests 是影响长连接如何关闭的参数。 如果监控长连接在运行中,一部分的连接被关闭了(也就是没有了),可能是 keepalive_requests 影响的(因为超过了单个长连接的请求最大次数);如果大批量被关闭了,可能是和 keepalive_timeout 有关。
  • upstream 中的 keepalive 是限制对 Tomcat 创建长连接个数的限制。不是不能创建超过这个数的连接,而是创建的长连接数,不能超过这个限制,在这之上可以再创建连接,只不过创建的都是短连接。
  • proxy_http_version 和 proxy_set_header 根据 http 版本(1.0/1.1)设置有所不同,请注意。

关于 Nginx 的设置,可以参考:Alphabetical index of directives

2,Tomcat 设置

conf/server.xml:
    <!-- 
        maxThreads:由此连接器创建的最大请求处理线程数,这决定可同时处理的最大并发请求数(默认为200)
        minSpareThreads:保持运行状态的最小线程数(默认为10)
        acceptCount:接收传入的连接请求的最大队列长度(默认队列长度为100)
        connectionTimeout:在接收一条连接之后,连接器将会等待请求URI行的毫秒数(默认为60000,60秒)
        maxConnections:在任何给定的时间,服务器能接收和处理的最大连接数(NIO的默认值为10000)
        keepAliveTimeout:在关闭这条连接之前,连接器将等待另一个HTTP请求的毫秒数(默认使用connectionTimeout属性值)
        maxKeepAliveRequests:和 Nginx 中的 keepalive_request 属性的功能是一样的(默认为100)
        enableLookups:启用DNS查询(默认是DNS查询被禁用)
        compression:连接器是否启用HTTP/1.1 GZIP压缩,为了节省服务器带宽
        compressionMinSize:指定输出响应数据的最小大小(默认为2048,2KB)
        compressableMimeType:可使用HTTP压缩的文件类型
        server:覆盖HTTP响应的Server头信息
     -->
    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="768"
               minSpareThreads="512"
               acceptCount="128"
               connectionTimeout="1000"
               maxConnections="1024"
               keepAliveTimeout="300000"
               maxKeepAliveRequests="768"
               enableLookups="false"
               URIEncoding="utf-8"
               redirectPort="8443"
               compression="on" compressionMinSize="1024" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json,application/xml" server="webserver" />

这里要注意的是:

  • maxKeepAliveRequests 属性和 Nginx 中的 keepalive_request 属性的功能是一样的,是互相影响的,即达到两边中最小的设置后关闭连接。如果 Tomcat 这边设置的是 5,而 Nginx 那边设置的是 10 的话,Tomcat 到 5 时就会关闭这个长连接。
  • keepAliveTimeout 属性和 Nginx 中的 keepalive_timeout 功能是一样的,也是互相影响的,同上。
  • 如果使用是 Springboot 内嵌 Tomcat 的话,是无法在 application.properties 中设置 maxKeepAliveRequests 属性的。如果使用 Bean 的方式来设置,其它在 Springboot 中无法设置的属性也可以使用此方法来设置。另外,如果是在 application.properties 文件中设置了属性,也在 Bean 声明时设置了属性的话,application.properties 中设置的属性优先生效。
@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    
    
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
    factory.addConnectorCustomizers(connector -> {
    
    
        ((AbstractHttp11Protocol) connector.getProtocolHandler()).setMaxKeepAliveRequests(-1);
        ((AbstractHttp11Protocol) connector.getProtocolHandler()).setConnectionTimeout(20000);
    });
    return factory;
}

关于 Tomcat 的 connector 设置,可以参考:The HTTP Connector
关于 Springboot 设置,可以参考:Appendix A. Common application properties

3、测试

1,测试命令

为了测试长连接设置是否生效,可以使用下面两个命令来测试。

  • ab:用来进行压力测试的命令。例如:ab -c 8 -n 8000 127.0.0.1:10000/crm/,启用 8 个异步处理,发送总共 8000 个请求。
  • netstat:用来查看连接的状态。例如:netstat -an|grep ES|awk '{if($5~10001) print}'|wc -l,查看 Nginx 到 Tomcat 的正在使用连接。如果想要每秒刷新,可以这么做:while [ 1 -eq 1 ] ; do netstat -an|grep ES|awk '{if($5~10001) print}'|wc -l; sleep 1; echo ; done

2,测试准备

为了测试长连接是否起作用,最好把 Tomcat 部分按下面设置:

  • MaxKeepAliveRequests:设置成 -1。这样就不会因为请求个数,造成连接的断开重新创建。用 netstat 查看连接时,看到的就是稳定的状态。
  • ConnectionTimeout:设置成一个比较大的值,例如 60 秒,这样不会因为压测时间长,造成连接的断开重新创建

Nginx 的 keepalive_requests 和 keepalive_timeout 和 Tomcat 上面两个值作用相同,最好设置成一样,以免造成不稳定,而不知道是哪出现的原因。

在按照上面的设置进行测试后,保存长连接可用后,可以修改上面的参数,来查看参数的作用和预想结果是否相同。

3,进行测试

1,启动一个 Terminal,执行while [ 1 -eq 1 ] ; do netstat -an|grep ES|awk '{if($5~10001) print}'|wc -l; sleep 1; echo ; done。这样就可以查看连接创建的个数了。显示如下:

       0
       0
       0
       0

2,再打开一个 Terminal,使用 ab 命令,进行压测:ab -c 8 -n 8000 127.0.0.1:10000/crm/
ab 结果如下:

This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 800 requests
Completed 1600 requests
Completed 2400 requests
Completed 3200 requests
Completed 4000 requests
Completed 4800 requests
Completed 5600 requests
Completed 6400 requests
Completed 7200 requests
Completed 8000 requests
Finished 8000 requests


Server Software:        nginx/1.15.1
Server Hostname:        127.0.0.1
Server Port:            10000

Document Path:          /crm/
Document Length:        9 bytes

Concurrency Level:      8
Time taken for tests:   12.685 seconds
Complete requests:      8000
Failed requests:        0
Total transferred:      1304000 bytes
HTML transferred:       72000 bytes
Requests per second:    630.67 [#/sec] (mean)
Time per request:       12.685 [ms] (mean)
Time per request:       1.586 [ms] (mean, across all concurrent requests)
Transfer rate:          100.39 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   5.0      0     147
Processing:     1   11  16.4      7     316
Waiting:        0   10  15.8      6     310
Total:          1   12  17.5      8     316

Percentage of the requests served within a certain time (ms)
  50%      8
  66%     12
  75%     15
  80%     16
  90%     23
  95%     30
  98%     45
  99%     78
 100%    316 (longest request)

查看连接状态命令输出如下。从下面输出可以看出,创建了 8 个长连接。连接的个数,应该和 Nginx 中 upstream 中的 keepalive 的参数一致。

       0
       0
       8
       8
       8
       8
       8
       8
       8

3,结过 Nginx 的 keepalive_timeout 时间后,长连接数应该变成 0。

       0
       0
       0

参考

Tomcat 安全

9.1 配置安全

1) 删除webapps 目录下的所有文件,禁用tomcat管理界面;

2 ) 注释或删除tomcat-users.xml文件内的所有用户权限;

3 ) 更改关闭tomcat指令或禁用;

tomcat 的server.xml中定义了可以直接关闭 Tomcat 实例的管理端口 (默认8005)。 可以通过 telnet 连接上8005该端口之后,输入 SHUT DOWN (此为默认关闭指令)即可关闭 Tomcat 实例 (注意,此时虽然实例关闭了,但是进程还是存在的)。由于默认关闭 Tomcat 的端口和指令都很简单。默认端口为8005,指令为SHUT DOWN 。

方案一: 更改端口号和指令

<Server port="8456" shutdown="itcast_shut">

方案二: 禁用8005端口:

<Server port="‐1" shutdown="SHUTDOWN">

4 ) 定义错误页面

在webapps/ ROOT 目录下定义错误页面 404.html,500.html;

然后在tomcat/conf/web.xml中进行配置 , 配置错误页面:

<error‐page> 
    <error‐code>404</error‐code> 
    <location>/404.html</location> 
    </error‐page>
<error‐page> 
    <error‐code>500</error‐code> 
    <location>/500.html</location> 
    </error‐page>

这样配置之后,用户在访问资源时出现404,500这样的异常,就能看到我们自定义的错误 页面,而不会看到异常的堆栈信息,提高了用户体验,也保障了服务的安全性。

9.2 应用安全

在大部分的Web应用中,特别是一些后台应用系统,都会实现自己的安全管理模块 (权限模块),用于控制应用系统的安全访问,基本包含两个部分:认证 (登录/单点登录)和授权 (功能权限、数据权限)两个部分。

对于当前的业务系统,可以自己做一套适用于自己业务系统的权限模块,也有很多的应用系统直接使用一些功能完善的安全框架,将其集成到我们的web应用中,如:SpringSecurityApache Shiro等。

9.3 传输安全

9.3.1 HTTPS介绍

HTTPS的全称是超文本传输安全协议 (Hypertext Transfer Protocol Secure ),是一种网络安全传输协议。在HTT P的基础上加入SSL/TLS来进行数据加密,保护交换数据不被泄露、窃取。

SSL 和 TLS 是用于网络通信安全的加密协议,它允许客户端和服务器之间通过安全链接通信。SSL 协议的3个特性:

  • 1) 保密:通过SSL链接传输的数据时加密的。
  • 2 ) 鉴别:通信双方的身份鉴别,通常是可选的,单至少有一方需要验证。
  • 3 ) 完整性:传输数据的完整性检查。

从性能角度考虑,加解密是一项计算昂贵的处理,因为尽量不要将整个Web应用采用SSL 链接, 实际部署过程中, 选择有必要进行安全加密的页面 (存在敏感信息传输的页面) 采用SSL通信。

HTTPS和HTT P的区别主要为以下四点:

1) HTT PS协议需要到证书颁发机构CA 申请SSL证书, 然后与域名进行绑定,HTT P不用申 请证书;

2 ) HTT P是超文本传输协议,属于应用层信息传输,HTT PS 则是具有SSL加密传安全性传输协议,对数据的传输进行加密,相当于HTT P的升级版;

3 ) HTT P和HTT PS使用的是完全不同的连接方式,用的端口也不一样,前者是8080,后者是8443 。

4 ) HTT P的连接很简单,是无状态的;HTT PS协议是由SSL+HTT P协议构建的可进行加密传输、身份认证的网络协议,比HTT P协议安全。

HTTPS协议优势:

1) 提高网站排名,有利于SEO。谷歌已经公开声明两个网站在搜索结果方面相同,如果一个网站启用了SSL,它可能会获得略高于没有SSL网站的等级,而且百度也表明对安装了SSL的网站表示友好。因此,网站上的内容中启用SSL都有明显的SEO优势。

2 ) 隐私信息加密,防止流量劫持。特别是涉及到隐私信息的网站,互联网大型的数据泄露的事件频发发生,网站进行信息加密势在必行。

3 ) 浏览器受信任。 自从各大主流浏览器大力支持HTT PS协议之后,访问HTT P的网站都会提示“不安全” 的警告信息。

9.3.2 Tomcat支持HTTPS

1) 生成秘钥库文件。 keytool是JDK提供的工具

keytool ‐genkey ‐alias tomcat ‐keyalg RSA ‐keystore tomcatkey.keystore
  • genkey生成证书
  • alias别名
  • keyalg
  • keystore往哪个证书文件中存储

输入对应的密钥库密码, 秘钥密码等信息之后,会在当前文件夹中出现一个秘钥库文件:tomcatkey.keystore

2 ) 将秘钥库文件 tomcatkey.keystore 复制到tomcat/conf 目录下。

3 ) 配置tomcat/conf/server.xml

<Connector port="8443"  
           protocol="org.apache.coyote.http11.Http11NioProtocol" 
           maxThreads="150" schema="https" secure="true" SSLEnabled="true">

    <SSLHostConfig certificateVerification="false">
        <Certificate certificateKeystoreFile="D:/DevelopProgramFile/apache‐tomcat‐8.5.42‐windows‐x64/apache‐tomcat‐8.5.42/conf/tomcatkey.keystore"
                     certificateKeystorePassword="itcast"  type="RSA" />

    </SSLHostConfig>
</Connector>

4 )访问Tomcat ,使用https协议。

Tomcat 性能调优

10.1 Tomcat 性能测试

对于系统性能,用户最直观的感受就是系统的加载和操作时间,即用户执行某项操作的耗时。从更为专业的角度上讲,性能测试可以从以下两个指标量化。

  • 响应时间:如上所述,为执行某个操作的耗时。大多数情况下,我们需要针对同一个操作测试多次,以获取操作的平均响应时间。
  • 吞吐量:即在给定的时间内,系统支持的事务数量,计算单位为 TPS。

通常情况下,我们需要借助于一些自动化工具来进行性能测试,因为手动模拟大量用户的并发访问几乎是不可行的,而且现在市面上也有很多的性能测试工具可以使用,如:

A pacheBench、A pacheJMeter、WCAT 、WebPolygraph、LoadRunner。

我们课程上主要介绍两款免费的工具:A pacheBench。

10.1.1 ApacheBench

A pacheBench(ab)是一款A pacheServer基准的测试工具,用户测试A pache Server的 服务能力 (每秒处理请求数),它不仅可以用户A pache的测试,还可以用于测试 Tomcat 、Nginx 、lighthttp、IIS等服务器。

1) 安装

yum install httpd‐tools 
# 查看版本
ab ‐V 

2 ) 部署war包, 准备环境

  • 安装tomcat
  • 部署war到webapps下 ,启动Tomcat

3 ) 测试性能

ab ‐n 1000 ‐c 100 ‐p data.json ‐T application/json  http://localhost:9000/course/search.do?page=1&pageSize=10 

要编写好data.json文件

查看测试报告

参数说明

参数 含义描述
-n 在测试会话中所执行的请求个数,默认只执行一次请求
-c 一次产生的请求个数,默认一次一个
-p 包含了需要POST的数据文件
-t 测试所进行的最大秒数,默认没有时间限制
-T POST数据所需要使用的Content-Type头信息
-v 设置显示信息的详细程度
-w 以HTML表的格式输出结果,默认是白色背景的两列宽度的一张表
重要指标
指标 含义
Server Software 服务器软件
Server Hostname 主机名
Server Port 端口号
Document Path 测试的页面
Document Length 测试的页面大小
Concurrency Level 并发数
Time taken for tests 整个测试持续的时间
Complete requests 完成的请求数量
Failed requests 失败的请求数量,这里的失败是指请求的连接服务器、发送数据、接收数据等环节发生异常,以及无响应后超时的情况。
Write errors 输出错误数量
Total transferred 整个场景中的网络传输量,表示所有请求的响应数据长度总和,包括每个http响应数据的头信息和正文数据的长度。
HTML transferred 整个场景中的HTML内容传输量,表示所有请求的响应数据中正文数据的总和
Requests per second 每秒钟平均处理的请求数(相当于 LR 中的 每秒事务 数)这便是我们重点关注的吞吐率,它等于:Complete requests / Time taken for tests
Time per request 每个线程处理请求平均消耗时间(相当于 LR 中的 平均事务响应时间)用户平均请求等待时间
Transfer rate 平均每秒网络上的流量
Percentage of the requests served within a certain time (ms) 指定时间里,执行的请求百分比

10.2 Tomcat 性能优化

10.2.1 JVM参数调优

Tomcat是一款Java应用,那么JV M的配置便与其运行性能密切相关,而JV M优化的重点则集中在内存分配和GC策略的调整上,因为内存会直接影响服务的运行效率和吞吐量, JVM垃圾回收机制则会不同程度地导致程序运行中断。可以根据应用程序的特点,选择不 同的垃圾回收策略,调整JV M垃圾回收策略,可以极大减少垃圾回收次数,提升垃圾回收效率,改善程序运行性能。

1) JVM内存参数

参数 参数作用 优化建议
-server 启动Server,以服务端模式运行 服务端模式建议开启
-Xms 最小堆内存 建议与-Xmx设置相同
-Xmx 最大堆内存 建议设置为可用内存的80%
-XX:MetaspaceSize 元空间初始值
- XX:MaxMetaspaceSize 元空间最大内存 默认无限
-XX:MaxNewSize 新生代最大内存 默认16M
-XX:NewRatio 年轻代和老年代大小比值,取值为整数,默认为2 不建议修改
-XX:SurvivorRatio Eden区与Survivor区大小的比值,取值为整数,默认为8 不建议修改
查看tomcat的默认GC

在tomcat/bin/catalina.sh中在原来基础上添加

JAVA_OPTS="-Djava.rmi.server.hostname=192.168.1.2 -Dcom.sun.managament.jmxremote.port=8999 -Dcom.sun.management.jmxremote.rmi=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

打开jconsole,查看远程tomcat的概要信息

改变GC也是在里面设置

猜你喜欢

转载自blog.csdn.net/hancoder/article/details/113065948