Tomcat 进阶三

《Tomcat 进阶三》

提示: 本材料只做个人学习参考,不作为系统的学习流程,请注意识别!!!



7.JVM 配置

最常见的JVM配置当属内存分配,因为在绝大多数情况下,JVM默认分配的内存可能不能够满足我们的需求,特别是在生产环境,此时需要手动修改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"

参数说明 :
在这里插入图片描述配置之后, 重新启动Tomcat ,访问 :
在这里插入图片描述

8. Tomcat 集群

8.1 简介

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

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/; 
	} 
}

8.3 负载均衡策略

1). 轮询

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

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

参数说明:
在这里插入图片描述
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; 
}

8.4 Session共享方案

在Tomcat集群中,如果应用需要用户进行登录,那么这个时候,用于tomcat做了负载均衡,则用户登录并访问应用系统时,就会出现问题 。
在这里插入图片描述
解决上述问题, 有以下几种方案:

8.4.1 ip_hash 策略

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

8.4.2 Session复制

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

<%@ page contentType="text/html;charset=UTF‐8" language="java" %>
<html>
<head>
	<title>
		Title
	</title>
</head>
<body>
	TOMCAT ‐ 9999 :
	<br/>
	sessionID :<%=s ession.getId()%>
	<br/>
		<% Object loginUser=s ession.getAttribute( "loginUser"); if(loginUser
		!=n ull && 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 配置如下:

 <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共享的方案之一 。
在这里插入图片描述

9. Tomcat 安全

9.1 配置安全

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

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

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

方案一:

更改端口号和指令:

<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应用中,如:SpringSecurity、Apache Shiro等。

9.3 传输安全

9.3.1 HTTPS介绍

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

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

1) 保密:通过SSL链接传输的数据时加密的。

2) 鉴别:通信双方的身份鉴别,通常是可选的,单至少有一方需要验证。

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

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

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

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

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

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

HTTPS协议优势:

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

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

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

9.3.2 Tomcat支持HTTPS

1) 生成秘钥库文件。

keytool ‐genkey ‐alias tomcat ‐keyalg RSA ‐keystore tomcatkey.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协议。
在这里插入图片描述

10. Tomcat 性能调优

10.1 Tomcat 性能测试

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

1). 响应时间:如上所述,为执行某个操作的耗时。大多数情况下,我们需要针对同一个操作测试多次,以获取操作的平均响应时间。 2). 吞吐量:即在给定的时间内,系统支持的事务数量,计算单位为 TPS。 通常情况下,我们需要借助于一些自动化工具来进行性能测试,因为手动模拟大量用户的并发访问几乎是不可行的,而且现在市面上也有很多的性能测试工具可以使用,如: ApacheBench、ApacheJMeter、WCAT、WebPolygraph、LoadRunner。 我们课程上主要介绍两款免费的工具:ApacheBench。

10.1.1 ApacheBench

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

yum install httpd‐tools

2) 查看版本号

ab ‐V

在这里插入图片描述
3) 部署war包, 准备环境

A. 在Linux系统上安装Tomcat 上传 : alt + p ‐‐‐‐‐‐‐> put D:/apache‐tomcat‐8.5.42.tar.gz 解压 : tar ‐zxvf apache‐tomcat‐8.5.42.tar.gz ‐C /usr/local 修改端口号:8005 , 8080 , 8009
B. 将资料中的war包上传至Tomcat的webapps下 上传: alt + p ‐‐‐‐‐‐‐‐‐> put D:/ROOT.war 启动Tomcat解压
C. 导入SQL脚本 , 准备环境

4) 测试性能

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

参数说明
在这里插入图片描述
结果说明
在这里插入图片描述
重要指标
在这里插入图片描述

10.2 Tomcat 性能优化

10.2.1 JVM参数调优

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

1) JVM内存参数
在这里插入图片描述

JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:SurvivorRatio=8"

jmap -heap 51421

2 )GC策略

JVM垃圾回收性能有以下两个主要的指标:

  • 吞吐量:工作时间(排除GC时间) 占总时间的百分比,工作时间并不仅是指程序运行的时间,还包含内存分配的时间。
  • 暂停时间:测试时间段内,由垃圾回收导致的应用程序停止响应次数、时间。

在HotSpotJVM中,包含以下几种不同类型的垃圾收集器:

参考: https://blog.csdn.net/weixin_43695916/article/details/109031884

垃圾收集器分类(运行方式)作用位置算法特点适用场景
Serial串行新生代复制算法响应速度优先单CPU,Client模式
ParNew并行新生代复制算法响应速度优先多CPU,Server模式,配合CMS
Parallel并行新生代复制算法吞吐量优先后台运算而不需太多交互场景
Serial Old串行老年代标记压缩响应速度优先单CPU,Client模式
Parallel Old并行老年代标记压缩吞吐量优先后台运算而不需太多交互场景
CMS并发老年代标记清除响应速度优先互联网或B/S业务
G1并发、并行新生代、老年代标记压缩、复制算法响应速度优先面向服务端应用

不同的应用程序,对于垃圾回收会有不同的需求。JVM会根据运行的平台、服务器资源配置等情况选择合适的垃圾收集器、堆内存大小及运行时编译器,如无法满足需求,参考以下准则:

  1. 程序数据量较小。选择串行收集器
  2. 应用运行在单核处理器上且没有暂停时间要求,可交由JVM自行选择或者选择串行收集器。
  3. 如果考虑到应用程序的峰值性能,没有暂停时间要求,可以选择并行收集器。
  4. 如果应用程序的响应时间比整体吞吐量更重要,可以选择并发收集器。

在这里插入图片描述

查看Tomcat中默认的垃圾收集器:

  1. 在tomcat、bin、catalina.sh的配置中,加入如下配置:
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.192.138 -Dcom.sun.management.jmxremote"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=8999"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
  1. 打开jconsole,查看远程的tomcat概要信息,连接远程tomcat

在这里插入图片描述
GC参数:
在这里插入图片描述
我们也可以在测试的时候,将JVM参数调整之后,将GC的信息打印出来,便于为我们进行参数调整提供依据,具体参数如下:
在这里插入图片描述
在bin/catalina.sh脚本中, 追加如下配置:

JAVA_OPTS="-XX:+UseConcMarkSweepGC -XX:+PrintGCDetails"

10.2.2 Tomcat配置调优

调整tomcat/conf/server.xml中关于连接器的配置可以提升应用程序服务器的性能

参数说明
maxConnections最大连接数,当到达该值后,服务器接口但不会处理更多的请求,额外的请求会阻塞知道连接数低于maxConnections,可通过ulimit -a查看服务器的限制。对于CPU要求更高(计算型)时,建议不要配置过大;对于CPU要求不是特别高时,建议配置在2000左右。当然这个需要服务器硬件的支持
maxThreads最大线程数,需要根据服务器的硬件情况,进行一个合理的设置
acceptCount最大排队等待数,当服务器接收的请求数量达到maxConnections,此时的Tomcat会将后面的请求,存放在任务队列中进行排序,acceptCount指的就是任务队列中排队等待的请求数。一台Tomcat的最大请求处理数量是:maxConnections+acceptCount

11. Tomcat附加功能

11.1 WebSocket

11.1.1 WebSocket介绍

WebSocket是HTXL5新增的协议,它的目的是在浏览器和服务器之问建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。

为什么传统的HTTP协议不能做到WebSocket实现的功能?这是因为HTTP协议是一个请求 - 响应协议,请求必须先由浏览器发给服务器服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动清求,服务器是没法主动发数据给浏览器的。

这样一来,要在浏览器中搞一个实时聊天,或者在线多人游戏的话就没法实现了,只能借助E1ash这些插件。也有人说,HTTE协议其实也能实现啊,比如用轮询或者comet。轮询是指浏览器通过Javascript启动-一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息。这个机制的缺点一是实时性不够,二是频繁的清求会给服务器带来极大的压力。

Comet本质上也是轮询,但是在没有消息的情况下,服务器先拖一段时间,等到有消息了再回复。这个机制暂时地解决了实时性问题,但是它带来了新的问题:以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态 ,极大地浪费服务器资源。另外一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的,这就要求comet连接必须定
期发一些ping数据表示连接〝正常工作”。
在这里插入图片描述
首先WebSocket连接必须是由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:
在这里插入图片描述
该请求与普通HTTP请求有几点不同:

  1. GET请求的地址不是类似http://, 而是ws://开头的地址;
  2. 请求头Connection: Upgrade 和 请求头 Upgrade : websocket表示这个连接要被转换为websocket连接
  3. Sec-WebSocket-Key是用于标识这个连接, 是一个BASE64编码的秘闻,要求服务端响应一个对应加密的Sec-WebSocket-Accept头信息作为应答;
  4. Sec-WebSocket-Version 指定了websocket的协议版本;
  5. HTTP101 状态码标识服务端已经识别并切换为WebSocket协议,Sec-WebSocket-Accept是服务端与客户端一致的秘钥计算出来的信息

11.1.2 Tomcat的WebSocket

Tomcat的7.0.5版本开始支持WebSocket,并且实现了Java WebSocket规范(JSR356),而且在7.0.5版本之前(7.0.2之后)则采用自定义API, 即WebSocketServlet实现。

Java WebSocket应用由一系列的WebSocketEndpoint组成,Endpoint是一个Java对象,代表着WebSocket连接的一端,对于服务端,我们可以视为处理具体的WebSocket消息的接口,就像Servlet与http请求一样。

我们可以通过两种方式定义Endpoint:

  1. 编程式: 即继承javax.websocket.Endpoint并实现其方法;
  2. 注解式: 即定义一个POJO,并添加@ServerEndpoint相关注解

Endpoint实例在WebSocket握手时创建,并在客户端与服务端连接过程中有效,最后在连接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法,规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:

方法含义描述注解
onOpen当开启一个新的会话时调用,该方法是客户端与服务端握手成功后调用的方法@OnOpen
onClose当会话关闭时调用@OnClose
onError当连接过程中异常时调用@OnError

通过Session添加MessageHandler消息处理器来接收消息,当采用注解方式定义Endpoint时,我们还可以通过@OnMessage注解指定接收消息的方法。发送消息则由RemoteEndpoint完成,其实例由Session维护,根据使用情况,我们可以通过Session.getBasicRemote获取同步消息发送的实例, 然后调用其setXxx()方法就可以发送消息,可以通过Session.getAsyncRemote获取异步消息发送实例。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值