Tomcat 与 HTTPS 支持
HTTPS 是用来加强数据传输安全的,HTTP超文本传输协议,明文传输是非常不安全的,HTTPS在传输的过程中会对传输的数据进行加密。
SSL协议
基本介绍
TLS(Stransport Layer Security)协议 HTTP协议是互联网应用最广泛的数据传输协议之一,但HTTP本身不具备加密功能,传输的数据为明文,存在被窃听、篡改、伪造的风险。
HTTPS协议则通过TLS(旧称SSL)加密通道,提供:
- 数据机密性(Confidentiality):确保数据在传输过程中不会被窃听。
- 数据完整性(Integrity):确保传输过程中数据不会被篡改或破坏。
- 身份认证(Authentication):客户端和服务端之间可进行身份验证,确认通信双方的真实性。
工作原理
HTTPS在HTTP基础上,引入了一个TLS/SSL加密层。通信步骤如下:
- 客户端请求连接:客户端向服务器发送HTTPS请求。
- 服务器响应并发送证书:服务器返回一个包含其公钥的数字证书。
- 客户端验证证书:客户端校验数字证书是否合法。验证证书上的域名是否与当前访问域名匹配。
- 协商加密方式并生成会话密钥:客户端生成随机的对称密钥(Session Key),使用服务器证书中的公钥加密后传给服务器。服务器用自己的私钥解密获得会话密钥。
- 建立安全连接并传输数据:客户端和服务器端使用会话密钥进行数据加密和解密,实现安全通信。
技术基础
非对称加密(公钥加密)
- 使用一对密钥,分别是公开密钥(Public Key)和私密密钥(Private Key)。
- 公钥用于加密数据,私钥用于解密数据,私钥永远只存储在服务器端。
对称加密
- HTTPS传输数据的主体使用对称加密技术,即客户端和服务器端拥有相同的密钥用于加密和解密数据。
TLS握手过程
TLS握手过程是建立HTTPS通信的关键步骤:
- 客户端发起连接,提出支持的TLS版本与密码套件。
- 服务器回应自己的证书、公钥、选定的密码套件。
- 客户端验证证书有效性后,生成随机密钥,用服务器公钥加密发送给服务器。
- 服务器用私钥解密出会话密钥,完成握手。
Tomcat HTTPS
生成证书
首先我们需要生成免密的秘钥证书:
keytool -genkey -alias wzkicu -keyalg RSA -keystore wzkicu.keystore
配置XML
修改 /opt/servers/apache-tomcat-9.0.98/conf/server.xml 中的Connector部分:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" schema="https" secure="true" SSLEnabled="true">
<SSLHostConfig>
<Certificate
certificateKeystoreFile="/opt/wzk/wzkicu.keystore" certificateKeystorePassword="123123" type="RSA"
/>
</SSLHostConfig>
</Connector>
Tomcat 性能优化
基本介绍
系统性能的衡量指标,主要是响应时间和吞吐量。
- 响应时间:执行某个操作的耗时
- 吞吐量:系统在给定时间内能够支持的事务数量,单位TPS
Tomcat优化主要从以下方面进行:
- JVM的虚拟机优化(优化内存模型)
- Tomcat自身配置的优化(比如是否使用了共享线程池?IO模型?)
参数调整
连接器(Connector)
常用配置示例:
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
acceptCount="100"
maxConnections="10000"
maxThreads="200"
minSpareThreads="10"
enableLookups="false"
compression="on"
compressibleMimeType="text/html,text/xml,text/plain,text/javascript,text/css"/>
Java虚拟机内存相关的参数
在Tomcat启动脚本中优化JVM:
JAVA_OPTS="-server -Xms2G -Xmx2G -Xss512k \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-Djava.awt.headless=true"