企业级web应用服务器之Tomcat

Tomcat介绍

Tomcat 由 Apache 软件基金会下属的 Jakarta 项目开发。它实现了 Java Servlet 和 JavaServer Pages(JSP)等 Java EE 技术规范,为基于 Java 的 Web 应用程序提供运行环境。

主要特点

  1. 轻量级

    • Tomcat 是一个相对轻量级的服务器,易于部署和使用。它占用系统资源较少,适合在各种规模的环境中运行,从开发环境到生产服务器都能胜任。
    • 启动速度快,能够快速响应开发和测试中的需求变化。
  2. 开源免费

    • 作为开源软件,Tomcat 允许开发者查看和修改源代码,这使得开发者可以根据自己的特定需求进行定制和扩展。
    • 免费的特性降低了开发和部署成本,受到众多企业和开发者的青睐。
  3. 兼容性强

    • 严格遵循 Java EE 规范,能够与各种符合规范的 Java Web 应用程序无缝集成。
    • 可以与其他开源软件和商业软件配合使用,如数据库服务器、应用服务器集群等,构建强大的企业级应用解决方案。
  4. 稳定性高

    • 经过多年的发展和广泛的使用,Tomcat 具有很高的稳定性。它在处理大量并发请求时表现出色,能够保证 Web 应用的持续稳定运行。
    • 提供了丰富的配置选项和管理工具,方便管理员对服务器进行监控和调优,进一步提高了稳定性。

工作原理

  1. 接受请求
    • Tomcat 监听特定的端口(通常是 8080),等待来自客户端(如浏览器)的 HTTP 请求。
  2. 解析请求
    • 当接收到请求后,Tomcat 解析请求的内容,包括请求的 URL、HTTP 方法(GET、POST 等)、请求头和请求体等信息。
  3. 调用 Servlet
    • 根据请求的 URL 和配置的 Servlet 映射关系,Tomcat 确定要调用的 Servlet。如果请求是静态资源(如 HTML、CSS、图片等),Tomcat 直接从文件系统中读取并返回给客户端。
    • 对于动态内容,Tomcat 会创建 Servlet 实例,并调用相应的方法来处理请求。Servlet 可以访问请求中的参数、会话信息等,并生成动态的响应内容。
  4. 生成响应
    • Servlet 处理完请求后,将生成的响应内容返回给 Tomcat。Tomcat 会将响应内容封装成 HTTP 响应格式,并发送回客户端。

Tomcat的部署

两台Tomcat主机,Tomcat-node2主机上的操作与Tomcat-node1上相同。

bash 复制代码
# 安装Java环境
[root@tomcat-node1 ~]# yum install java-1.8.0-openjdk.x86_64 -y

# 安装并启动Tomcat
[root@tomcat-node1 ~]# tar zxf apache-tomcat-9.0.93.tar.gz -C /usr/local/
[root@tomcat-node1 ~]# ln -s /usr/local/apache-tomcat-9.0.93/ /usr/local/tomcat
[root@tomcat-node1 ~]# /usr/local/tomcat/bin/startup.sh

# 查看端口
[root@tomcat-node1 ~]# netstat -antlupe | grep java       
tcp6       0      0 :::8080                 :::*                    LISTEN      1001       84108      35429/java     

访问Tomcat

bash 复制代码
# 生成Tomcat的主配置文件
[root@tomcat-node1 ~]# vim /usr/local/tomcat/conf/tomcat.conf
JAVA_HOME=/etc/alternatives/jre_openjdk

# 生成启动文件
[root@tomcat-node1 ~]# 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
结合反向代理实现Tomcat部署
  • standalone模式,Tomcat单独运行,直接接受用户的请求,不推荐。

  • 反向代理,单机运行,提供了一个Nginx作为反向代理,可以做到静态由nginx提供响应,动态jsp代理给Tomcat

    • LNMT:Linux + Nginx + MySQL + Tomcat
    • LAMT:Linux + Apache(Httpd)+ MySQL + Tomcat
  • 前置一台Nginx,给多台Tomcat实例做反向代理和负载均衡调度,Tomcat上部署的纯动态页面更适合

    • LNMT:Linux + Nginx + MySQL + Tomcat
  • 多级代理

    • LNNMT:Linux + Nginx + Nginx + MySQL + Tomcat
利用nginx反向代理实现

利用nginx反向代理功能,实现图中的代理功能,将用户请求全部转发至指定的同一个tomcat主机

利用nginx指令proxy_pass 可以向后端服务器转发请求报文,并且在转发时会保留客户端的请求报文中的host首部

bash 复制代码
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    server_name www.qwert.org;
    root /data/web/html;
    index index.html;
    
    location ~ \.jsp$ {
        proxy_pass http://tomcat;
    }
}
# 重启服务进行测试
# 浏览器中访问www.qwert.org/test.jsp
实现Tomcat中的负载均衡

动态服务器的问题,往往就是并发能力太弱,往往需要多台动态服务器一起提供服务。如何把并发的压力分摊,这就需要调度,采用一定的调度策略,将请求分发给不同的服务器,这就是Load Balance负载均衡。

当单机Tomcat,演化出多机多级部署的时候,一个问题便凸显出来,这就是Session。而这个问题的由来,都是由于HTTP协议在设计之初没有想到未来的发展。

bash 复制代码
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
upstream tomcat {
      #ip_hash;
      hash $cookie_JSESSIONID;
      server 172.25.254.10:8080;
      server 172.25.254.20:8080;
}
server {
    listen 80;
    server_name www.qwert.org;
    root /data/web/html;
    index index.html;


    location ~ \.php$ {
        root /data/web/php;
        set $key $uri$args;
        srcache_fetch GET /memc $key;
        srcache_store PUT /memc $key;
        fastcgi_pass 172.25.254.100:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    location ~ \.jsp$ {
        proxy_pass http://tomcat;
    }
}

# 重启服务进行测试
# 浏览器中访问www.qwert.org/test.jsp

Memcached

Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统memcached。虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失,当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并提供服务。

Memcached 借助了操作系统的 libevent 工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的session实现session共享

Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page

Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等

Memcached 官网:http://memcached.org/

memcached的安装与启动
bash 复制代码
[root@tomcat-node1 ~]# yum install memcached -y
[root@tomcat-node1 ~]# vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 0.0.0.0,::1"
[root@tomcat-node1 ~]# systemctl enable --now memcached
[root@tomcat-node1 ~]# netstat -antlupe | grep memcache
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN
980 97815 34711/memcached

# Tomcat-node2上操作相同

session会话保持

msm(memcached session manager)提供将Tomcat的session保持到memcached可以实现高可用。

项目早期托管在google code,目前在Github

github网站链接: https://github.com/magro/memcached-session-manager

支持Tomcat的 6.x、7.x、8.x、9.x

  • Tomcat的Session管理类,Tomcat版本不同

    • memcached-session-manager-2.3.2.jar
    • memcached-session-manager-tc9-2.3.2.jar
  • Session数据的序列化、反序列化类

    • 官方推荐kyro
    • 在webapp中WEB-INF/lib/下
  • 驱动类

    • memcached(spymemcached.jar)
    • Redis(jedis.jar)
安装

参考链接: https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

将spymemcached.jar、memcached-session-manage、kyro相关的jar文件都放到Tomcat的lib目录中,这个目录是 $CATALINA_HOME/lib/ ,对应本次安装就是/usr/local/tomcat/lib。

复制代码
kryo-3.0.3.jar
asm-5.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
minlog-1.3.1.jar
kryo-serializers-0.45.jar
msm-kryo-serializer-2.3.2.jar
memcached-session-manager-tc9-2.3.2.jar
spymemcached-2.12.3.jar
memcached-session-manager-2.3.2.jar

下载相关jar包,参考下面官方说明的下载链接

https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

bash 复制代码
# 修改Tomcat配置
[root@tomcat-node1 ~]# vim /usr/local/tomcat/conf/context.xml
====================省略=========================
<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
      memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"
      failoverNodes="n1"
      requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
      transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>

[root@tomcat-node2 ~]# vim /usr/local/tomcat/conf/context.xml
=====================省略======================
<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
      memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"
      failoverNodes="n2"
      requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
      transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>


# nginx配置
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
upstream tomcat {
      #ip_hash;
      hash $cookie_JSESSIONID;
      server 172.25.254.10:8080;
      server 172.25.254.20:8080;
}
server {
    listen 80;
    server_name www.qwert.org;
    root /data/web/html;
    index index.html;


    location ~ \.php$ {
        root /data/web/php;
        set $key $uri$args;
        srcache_fetch GET /memc $key;
        srcache_store PUT /memc $key;
        fastcgi_pass 172.25.254.100:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    location ~ \.jsp$ {
        proxy_pass http://tomcat;
    }
}

# 重启nginx
# 重启memcached
# 重启tomcat
# 在两台tomcat都开启的情况下在浏览器访问www.qwert.org/test.jsp进行测试,然后停掉一台主机的tomcat继续提交信息看是否可以读取到之前的会话信息


停掉node1进行测试

相关推荐
@atweiwei6 小时前
深入解析gRPC服务发现机制
微服务·云原生·rpc·go·服务发现·consul
123过去6 小时前
hashid使用教程
linux·网络·测试工具·安全
C+++Python6 小时前
Linux/C++多进程
linux·运维·c++
最贪吃的虎7 小时前
GitHub推送又超时了?试试SSH
运维·ssh·github
XZY0287 小时前
如何使用grpc
运维·服务器
rleS IONS7 小时前
SQL2000在win10上安装的方法
运维·服务器
Stack Overflow?Tan907 小时前
linux ubuntu22.04安装ROS2humble完整版的流程
linux·docker·ros2
zly35007 小时前
centos7 sshd无法启动
linux·运维·服务器
编程大师哥8 小时前
Linux 命名管道(FIFO)通信 超清晰讲解
linux·运维·服务器
Smile_2542204188 小时前
linux服务器清理磁盘
linux·运维·服务器