tomcat的介绍
Tomcat是一个开源的轻量级Web应用服务器,它由Apache软件基金会下属的Jakarta项目开发。Tomcat是一个Servlet容器,主要用于运行Java Web应用程序。它支持JSP(Java Server Pages)技术,允许在HTML页面中嵌入Java代码,实现动态网页的开发。Tomcat的顶层架构包括一个Server容器,它可以包含多个Service,每个Service由一个或多个Connector和一个Container组成。Connector负责处理连接和请求,而Container则封装和管理Servlet,处理Request请求。
Tomcat的主要特性包括:
JSP容器:用于将JSP动态网页翻译成Servlet代码,实现用户界面的动态化。
JMX-based嵌入:基于Java Management Extensions (JMX)的嵌入,提供了对Tomcat的监控和管理能力。
增强的安全管理支撑:提供了更强大的安全管理功能,保障应用程序的安全运行。
Session集群集成:支持session集群,提高了应用程序的可扩展性和可用性。
文档扩充:提供了丰富的文档,方便用户学习和使用。
Tomcat支持多种操作系统,包括Windows和Unix,这使得它成为一个跨平台的解决方案。随着版本的更新,Tomcat不断引入新功能和改进,以满足不断变化的Web开发需求。例如,最新的版本可能包括了提高Taglibs的支撑能力、改进的数据池和tag插件等,以提供更好的性能和功能给开发者使用12。
Tomcat是一个开源的轻量级Web应用服务器,它由Apache软件基金会下属的Jakarta项目开发。Tomcat是一个Servlet容器,主要用于运行Java Web应用程序。它支持JSP(Java Server Pages)技术,允许在HTML页面中嵌入Java代码,实现动态网页的开发。Tomcat的顶层架构包括一个Server容器,它可以包含多个Service,每个Service由一个或多个Connector和一个Container组成。Connector负责处理连接和请求,而Container则封装和管理Servlet,处理Request请求。
体系结构
Tomcat 的基本组件包括 Catalina、Server、Service、Connector、Container、Engine、Host、Context 和 Wrapper。其中,Tomcat 服务器的顶层容器是一个 Catalina 容器,Catalina 容器的顶层容器是 Server 容器,三者的关系是 1∶1∶1,也就是说,每个 Tomcat 实例有一个 Catalina 容器和一个 Server 容器。
1. Catalina:这是一个 Servlet 容器,用于处理 Servlet。它负责解析 Tomcat 的配置文件 (server.xml),从而创建并管理服务器组件。
2. Server:这是管理 Tomcat 实例的组件,负责组装和启动 Servlet 引擎及 Tomcat 连接器。Server 通过实现 Lifecycle 接口,为整个系统提供优雅的启动和关闭方式。
3. Service:这是一个逻辑组件,用于绑定 Connector 和 Container。Service 组件允许对外提供服务,可以认为一个 Service 对应启动一个 JVM。更严格来说,一个 Engine 组件对应一个 JVM,只不过 Connector 也在 JVM 中工作。
4. Connector:这是一个监听组件,具有以下四个功能:
打开监听套接字,监听外部请求并与客户端建立 TCP 连接。
使用 protocolHandler 解析请求中的协议和端口等信息,如 HTTP 协议、AJP 协议。
根据解析到的信息,使用 processor 将处理后的请求转发给绑定的 Engine。
接收响应数据并返回客户端。
5. Container:这是一个容器,负责处理用户的 Servlet 请求并将对象返回给 Web 用户。Container 是一类组件,包含四个容器类组件:Engine 容器、Host 容器、Context 容器和 Wrapper 容器。
6. Engine:用于从 Connector 组件接收已建立的 TCP 连接,还用于接收并解析客户端发送的 HTTP 请求,然后根据解析结果将相关参数传递给匹配的虚拟主机。Engine 还用于指定默认主机。
7. Host:用于定义虚拟主机。由于 Tomcat 主要作为 Servlet 容器使用,因此为每个 Web 应用指定了它们的根目录 appBase。
8. Context:根据 path 和 docBase 获取信息,并将结果交给其内的 Wrapper 组件处理,为 Wrapper 提供运行环境。一般采用默认的标准 Wrapper 类,因此在 Context 容器中几乎不会出现 Wrapper 组件。
9. Wrapper:对应 Servlet 的处理过程。它管理 Servlet 的生命周期,根据 Context 提供的信息及解析 web.xml 中的映射关系,负责加载相关类,初始化 Servlet 对象 (init())、执行 Servlet 代码 (service()) 以及在服务结束时销毁 Servlet 对象 (destroy())
原理图
工作原理
启动Tomcat:启动时会加载配置文件(如 server.xml 和 web.xml),创建 Server 和 Service 实例,初始化连接器(Connector)和容器(Container)。
等待请求:启动后,Tomcat 进入等待请求的状态,监听配置的端口(默认是 8080)。
接收请求:当客户端发送请求到 Tomcat 服务器,Connector 接收这些请求,并将请求封装成 Request 和 Response 对象。
处理请求:Connector 将请求发送给 Container 进行处理,Container 会根据请求的 URL 找到对应的 Wrapper,然后由 Wrapper 调用 Servlet 的相应方法处理请求。
返回响应:Servlet 处理完请求后,返回响应给 Container,Container 将响应转换为响应协议发送回 Connector,再由 Connector 发送回客户端
目录构成
实验部署
安装tomcat
通过xftp来给虚拟机传输tomcat压缩包,安装到后端的服务器上
解压到/usr/local,两台都要
[root@httpd2 ~]# tar zxf apache-tomcat-9.0.93.tar.gz -C /usr/local/
安装java环境,两台都要
[root@httpd2 ~]# yum install java-1.8.0-openjdk.x86_64 -y 正在更新 Subscription Management 软件仓库。 无法读取客户身份 本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。 上次元数据过期检查:1 day, 23:45:52 前,执行于 2024年08月21日 星期三 15时56分35秒。 依赖关系解决。 ============================================================== 软件包 架构 版本 仓库 大小 ============================================================== 安装: java-1.8.0-openjdk x86_64 1:1.8.0.345.b01-5.el9 AppStream 464 k 安装依赖关系: copy-jdk-configs noarch 4.0-3.el9 AppStream 29 k ibus-gtk2 x86_64 1.5.25-2.el9 AppStream 28 k java-1.8.0-openjdk-headless x86_64 1:1.8.0.345.b01-5.el9 AppStream 33 M javapackages-filesystem noarch 6.0.0-3.el9 AppStream 18 k lksctp-tools x86_64 1.0.19-2.el9 BaseOS 98 k lua x86_64 5.4.2-4.el9 AppStream 192 k lua-posix x86_64 35.0-8.el9 AppStream 155 k mkfontscale x86_64 1.2.1-3.el9 AppStream 34 k ttmkfdir x86_64 3.0.9-65.el9 AppStream 55 k tzdata-java noarch 2022d-1.el9_1 AppStream 236 k xorg-x11-fonts-Type1 noarch 7.5-33.el9 AppStream 509 k 安装弱的依赖: adwaita-gtk2-theme x86_64 3.28-14.el9 AppStream 217 k gtk2 x86_64 2.24.33-7.el9 AppStream 3.5 M libcanberra-gtk2 x86_64 0.30-26.el9 AppStream 28 k 事务概要 ============================================================== 安装 15 软件包 总计:39 M 安装大小:136 M 下载软件包: 运行事务检查 事务检查成功。 运行事务测试 事务测试成功。 运行事务 运行脚本: copy-jdk-configs-4.0-3.el9.noarch 1/1 运行脚本: java-1.8.0-openjdk-headless-1:1.8.0.345.b01 1/1 准备中 : 1/1 安装 : libcanberra-gtk2-0.30-26.el9.x86_64 1/15 安装 : gtk2-2.24.33-7.el9.x86_64 2/15 安装 : adwaita-gtk2-theme-3.28-14.el9.x86_64 3/15 安装 : lksctp-tools-1.0.19-2.el9.x86_64 4/15 安装 : tzdata-java-2022d-1.el9_1.noarch 5/15 安装 : ttmkfdir-3.0.9-65.el9.x86_64 6/15 安装 : mkfontscale-1.2.1-3.el9.x86_64 7/15 安装 : xorg-x11-fonts-Type1-7.5-33.el9.noarch 8/15 运行脚本: xorg-x11-fonts-Type1-7.5-33.el9.noarch 8/15 安装 : lua-posix-35.0-8.el9.x86_64 9/15 安装 : lua-5.4.2-4.el9.x86_64 10/15 安装 : copy-jdk-configs-4.0-3.el9.noarch 11/15 安装 : javapackages-filesystem-6.0.0-3.el9.noarc 12/15 安装 : java-1.8.0-openjdk-headless-1:1.8.0.345.b 13/15 运行脚本: java-1.8.0-openjdk-headless-1:1.8.0.345.b 13/15 安装 : java-1.8.0-openjdk-1:1.8.0.345.b01-5.el9. 14/15 运行脚本: java-1.8.0-openjdk-1:1.8.0.345.b01-5.el9. 14/15 安装 : ibus-gtk2-1.5.25-2.el9.x86_64 15/15 运行脚本: copy-jdk-configs-4.0-3.el9.noarch 15/15 运行脚本: java-1.8.0-openjdk-headless-1:1.8.0.345.b 15/15 运行脚本: java-1.8.0-openjdk-1:1.8.0.345.b01-5.el9. 15/15 运行脚本: ibus-gtk2-1.5.25-2.el9.x86_64 15/15 验证 : adwaita-gtk2-theme-3.28-14.el9.x86_64 1/15 验证 : copy-jdk-configs-4.0-3.el9.noarch 2/15 验证 : gtk2-2.24.33-7.el9.x86_64 3/15 验证 : ibus-gtk2-1.5.25-2.el9.x86_64 4/15 验证 : java-1.8.0-openjdk-1:1.8.0.345.b01-5.el9. 5/15 验证 : java-1.8.0-openjdk-headless-1:1.8.0.345.b 6/15 验证 : javapackages-filesystem-6.0.0-3.el9.noarc 7/15 验证 : libcanberra-gtk2-0.30-26.el9.x86_64 8/15 验证 : lua-5.4.2-4.el9.x86_64 9/15 验证 : lua-posix-35.0-8.el9.x86_64 10/15 验证 : mkfontscale-1.2.1-3.el9.x86_64 11/15 验证 : ttmkfdir-3.0.9-65.el9.x86_64 12/15 验证 : tzdata-java-2022d-1.el9_1.noarch 13/15 验证 : xorg-x11-fonts-Type1-7.5-33.el9.noarch 14/15 验证 : lksctp-tools-1.0.19-2.el9.x86_64 15/15 已更新安装的产品。 已安装: adwaita-gtk2-theme-3.28-14.el9.x86_64 copy-jdk-configs-4.0-3.el9.noarch gtk2-2.24.33-7.el9.x86_64 ibus-gtk2-1.5.25-2.el9.x86_64 java-1.8.0-openjdk-1:1.8.0.345.b01-5.el9.x86_64 java-1.8.0-openjdk-headless-1:1.8.0.345.b01-5.el9.x86_64 javapackages-filesystem-6.0.0-3.el9.noarch libcanberra-gtk2-0.30-26.el9.x86_64 lksctp-tools-1.0.19-2.el9.x86_64 lua-5.4.2-4.el9.x86_64 lua-posix-35.0-8.el9.x86_64 mkfontscale-1.2.1-3.el9.x86_64 ttmkfdir-3.0.9-65.el9.x86_64 tzdata-java-2022d-1.el9_1.noarch xorg-x11-fonts-Type1-7.5-33.el9.noarch 完毕!
做链接好操作,两台都要
[root@httpd2 local]# ln -s apache-tomcat-9.0.93 tomcat
切换到bin底下启动程序
[root@httpd2 bin]# cd /usr/local/tomcat/bin/ [root@httpd2 bin]# ./startup.sh Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Using CATALINA_OPTS: Tomcat started.
可以查看端口是否开启,此时8080端口就会打开
[root@httpd2 bin]# netstat -antlpue |grep java tcp6 0 0 127.0.0.1:8005 :::* LISTEN 1001 26328 971/java tcp6 0 0 :::8080 :::* LISTEN 1001 25869 971/java
在浏览器测试,此时机会访问到
生成tomcat的启动文件,可以更方便的开启文件等
配置tomcat的主配置文件
[root@httpd2 ~]# cd /usr/local/tomcat/conf/ [root@httpd2 conf]# vim tomcat.conf JAVA_HOME=/etc/alternatives/jre_openjdk
生成启动文件
[root@httpd2 ~]# vim /lib/systemd/system/tomcat.service [Unit] Description=Tomcat #After=syslog.target network.target remote-fs.target nss-lookup.target After=syslog.target network.target [Service] Type=forking EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf ExecStart=/usr/local/tomcat/bin/startup.sh ExecStop=/usr/local/tomcat/bin/shutdown.sh PrivateTmp=true User=tomcat Group=tomcat [Install] WantedBy=multi-user.target [root@httpd2 ~]# systemctl daemon-reload
此时就可以启动文件了
[root@httpd2 ~]# systemctl start tomcat.service
tomcat的部署
自己编写一个网页,把网页放到tomcat的默认发布目录里
[root@httpd2 ~]# cp test.jsp /usr/local/tomcat/webapps/ROOT/
网页内容(可以根据自己的喜好来写)
<%@ page contentType="text/html; charset=GBK" %> <%@ page import="java.util.*" %> <html><head><title>Cluster App Test</title></head> <body> Server Info: <% out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%> <% out.println("<br> ID " + session.getId()+"<br>"); String dataName = request.getParameter("dataName"); if (dataName != null && dataName.length() > 0) { String dataValue = request.getParameter("dataValue"); session.setAttribute(dataName, dataValue); } out.print("<b>Session list</b>"); Enumeration e = session.getAttributeNames(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); String value = session.getAttribute(name).toString(); out.println( name + " = " + value+"<br>"); System.out.println( name + " = " + value); } %> <form action="test.jsp" method="POST"> name:<input type=text size=20 name="dataName"> <br> key:<input type=text size=20 name="dataValue"> <br> <input type=submit> </form> </body> </html>
可以在浏览器查看
利用nginx来实现tomcat的反向代理和负载均衡
反向代理
在配置了nginx的主机里,编写配置文件,并重启服务
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/php.conf server { listen 80; server_name www.timinglee.org; root /data/web/html; location ~ \.jsp$ { proxy_pass http://tomcat; } } [root@nginx conf.d]# nginx -s reload
此时在浏览器访问
负载均衡
在nginx的配置文件里编写,并重启服务,算法使用了对cookie进行hash
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/php.conf upstream tomcat { hash $cookie_JSESSIONID; server 172.25.254.100:8080; server 172.25.254.110:8080; } server { listen 80; server_name www.timinglee.org; root /data/web/html; location ~ \.jsp$ { proxy_pass http://tomcat; } } [root@nginx conf.d]# nginx -s reload
此时在浏览器测试,可以看出在两台不同的浏览器里访问,他访问的tomcat的服务器不同
tomcat的session的会话保持
Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个 key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的 session实现session共享 Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等
安装memcache,在后端的服务器上安装,两台都要
[root@httpd ~]# yum install memcached -y
编辑memcache文件
[root@httpd ~]# vim /etc/sysconfig/memcached PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="64" OPTIONS="-l 0.0.0.0,::1"
启动程序
[root@httpd ~]# systemctl enable --now memcached
查看端口
[root@httpd ~]# netstat -antlpue |grep memcache tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 976 23718 935/memcached
将spymemcached.jar、memcached-session-manage、kyro相关的jar文件都放到Tomcat的lib目录 中,这个目录是 $CATALINA_HOME/lib/ ,对应本次安装就是/usr/local/tomcat/lib
通过xftp来给虚拟机传输文件
复制到/usr/local/tomcat/lib/里
[root@httpd ~]# cd jar/ [root@httpd jar]# ls asm-5.2.jar kryo-3.0.3.jar kryo-serializers-0.45.jar memcached-session-manager-2.3.2.jar memcached-session-manager-tc9-2.3.2.jar minlog-1.3.1.jar msm-kryo-serializer-2.3.2.jar objenesis-2.6.jar reflectasm-1.11.9.jar spymemcached-2.12.3.jar [root@httpd jar]# cp * /usr/local/tomcat/lib/
修改tomcat的配置文件,两台都要
[root@httpd ~]# vim /usr/local/tomcat/conf/context.xml
添加参数,不过两台的IP要改变
重启服务
[root@httpd ~]# systemctl restart tomcat.service
nginx的配置不变
测试
先输入内容,此时他连的110这台主机的
此时关掉110主机的tomcat的服务
[root@httpd2 ~]# systemctl stop tomcat.service