Tomcat简介
Tomcat背景
tomcat就是常用的的中间件之一,tomcat本身是一个容器,专门用来运行java程序,java语言开发的网页.jsp就应该运行于tomcat中。而tomcat本身的运行也依赖于jdk环境。 tomcat常应用于lnmt环境
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。 诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。目前Tomcat最新版本为9.0。
Tomcat简介
Tomcat服务器是一个免费的开放源代码的Web应用服务器,运行jsp和servlet,使用HTTP与客户端(通常是浏览器)进行通信。Tomcat是一个小型的轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍应用,是开发和调试JSP程序的首选,因为Tomcat技术先进,性能稳定,成为目前比较流行的Web应用服务器,Tomcat是应用(java)服务器,他只是一个servlet容器,是apache的扩展,但他是独立运行的.
tomcat软件本身是Java语言编写的,所以需要jdk的环境才能运行,且java语言编写的应用程序在启动时会有一个编译的过程,所以java语言编写的应用程序的启动速度相对于C语言编写的应用程序会慢一些。
# 常用的编写动态页面的语言: PHP——> LAMP LNMP
# 借助于PHP的应用程序实现对PHP页面的解析java(jsp -- java server pages)
# 开源工具<网站服务器>
# WebLogical > Oracl 重量级商业工具,用于解析大型java项目
# WebSphere > IBM 重量级商业工具
# resin Python > CAUCHO 使用Django模块,编写动态页面
# Jboss
了解java吗?
java三大平台,1999年SUN发不了基于java的三个平台技术标准。
# JAVASE: java标准平台,允许开发和部署在桌面,服务器,嵌入式环境和实时环境中使用的JAVA应用程序。比如做一个桌面版QQ。
# JAVAEE: java企业平台,可帮助开发和部署可移植,健壮,可伸缩且安全的服务器端java应用程序。EE是基于SE基础上构建的,提供web服务,组件模型,挂了你和通信API,可以用来实现企业级的面向服务体系结构和web等应用程序
# JAVAME: java微型平台,也叫K-JAVA,用来开发和部署可以只和嵌入式设备(比如手机和打印机等).
java是如何跨平台的?
Java通过产生一种和系统平台无关的文件,然后再在各个平台的电脑上撞上模拟器(JVM虚拟机),让跨平台的文件运行在模拟器里面。
# 原理:
# 1.编译之后会生成与平台无关的字节码文件
# 2.得以来不同平台的虚拟机(JVM)
# JVM是不跨平台
JRE,JDK,JVM分别是什么?
# JRE: java运行环境,如果运行java程序,就需要JRE支持,JRE里面包含JVM
# JDK: java开发工具,包含java程序的所有工具,如javac和java等,JDK里包含JRE。
# JVM是JAVA语言的运行环境,也是java最具吸引力的特性之一。JVM用于读取并处理编译过的与平台无关的字节码class文件,从而实现java的移植性。但是JVM是不跨平台的。
# JVM是java程序的解释和执行器.
Tomcat常见的架构:
- tomcat本身即解析动态页面,又解析静态页面,适用于访问量极小的情况 client tomcat
- 静态页面的请求由httpd负责;动态页面,配置apache将请求转交给tomcat来完成,整合apache和tomcat需要Mod_jk的模块。这两款软件都是apache组织编写的,所以兼容性较好。
http://tomcat.apache.org/download-connectors.cgi client HTTPD tomcat - 客户端访问的是静态页面直接由Nginx解析;动态页面,使用Nginx的反向代理功能,代理到后端的tomcat服务器上面,由tomcat来响应客户端的动态页面。当然Nginx的代理也可以开启缓存功能,将后端tomcat服务器上经常访问的页面缓存到本地,来提高响应效率。
这里的Nginx即做静态页面的响应又完成反向代理的功能 client Nginx代理 tomcat tomcat
yum部署
curl -o /etc/yum.repos.d/163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo &>/dev/null
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo &>/dev/null
yum install java-1.8.0-openjdk
yum install tomcat-webapps tomcat-admin-webapps
systemctl start tomcat
ss -antp |grep java
LISTEN 0 100 :::8009 :::* users:(("java",pid=7979,fd=50))
LISTEN 0 100 :::8080 :::* users:(("java",fd=49))
tar包部署
1.安装JDK环境
# CentOS7安装Java,有tar包和rpm包两种
1>. rpm -ivh jdk-8u121-linux-x64.rpm
2>. tar xvf jdk-8u151-linux-x64.tar.gz -C /usr/local/
cd /usr/local/
mv jdk1.8.0_151/ jdk
tail -3 /etc/profile
JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# tomcat软件启动时,会默认到系统的环境变量中查找一个名称叫JAVA_HOME的变量。这个变量的作用找到tomcat启动所需的jvm。
# tomcat软件启动后,除了查找JAVA_HOME后,还会再查找一个叫CATALINA_HOME变量,这个变量的作用是设置tomcat的根目录。
source /etc/profile
2.安装Tomcat
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.55/bin/apache-tomcat-8.5.55.tar.gz
tar xvf apache-tomcat-8.5.47.tar.gz -C /usr/local/
ln -s /usr/local/apache-tomcat-8.5.47/ /usr/local/tomcat
tail -1 /etc/profile
export CATALINA_HOME=/usr/local/tomcat
source /etc/profile
env |grep -i home
CATALINA_HOME=/usr/local/tomcat
HOME=/root
# 查看熵池的大小:
cat /proc/sys/kernel/random/entropy_avail 180
增加熵池大小,解决Tomcat在CentOS 7巨慢的问题
# 安装rng服务,增大熵池
yum -y install rng-tools
systemctl start rngd && systemctl enable rngd
# 启动服务访问Tomcat页面快一百倍..
3.启动Tomcat
/usr/local/tomcat/bin/catalina.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
ss -antp |grep java
LISTEN 0 100 *:8009 *:* users:(("java",pid=857,fd=58))
LISTEN 0 100 *:8080 *:* users:(("java",fd=53))
LISTEN 0 1 127.0.0.1:8005 *:* users:(("java",fd=73))
@H_404_99@Tomcat三个端口
# 8005: 是tomcat本身的端口,本地管理端口号
# 8080: 主端口号,是tomcat负责建立http连接的端口,通过浏览器访问tomcat服务器的web 应用时,使用此端口
# 8009: 是tomcat负责和其他http服务器建立连接的端口,ajp的编辑器
Tomcat启动脚本
vim /etc/init.d/tomcat
#!/bin/bash
#chkconfig: 2345 96 14
export JAVA_HOME=/usr/java/jdk1.8.0_121
export CATALINA_HOME=/usr/local/tomcat
exec $CATALINA_HOME/bin/catalina.sh $*
# $*将脚本本身自带的参数全部传递过来,就是catalina.sh --help看到的所有的参数start stop等
chmod +x /etc/init.d/tomcat
chkconfig --add tomcat
chkconfig tomcat on
service tomcat start
systemctl status tomcat
tail -f catalina.out 服务启动不起来查看这个日志文件
Tomcat组件分类及内部组成
组件分类
# 顶级组件
Server,代表整个Tomcat容器
# 服务类组件
Service,组织Engine和Connector,里面只能包含一个Engine
# 连接器组件
Connector,有HTTP、HTTPS、A JP协议的连接器
# 容器类
# Engine、Host、Context都是容器类组件,可以嵌入其它组件,内部配置如何运行应用程序。
# 内嵌类
# 可以内嵌到其他组件内,valve、logger、realm、loader、manager等。以logger举例,在不同容器组件内定义。
# 集群类组件
# listener、cluster
Tomcat内部组成
名称 | 说明 |
---|---|
Server | tomcat的进程示例 |
Connector | 负责客户端的HTTP/HTTPS/AJP等协议的连接,一个Connter只属于一个Engine |
Service | 用来组织Connter和Engine之间的关系 |
Engine | 响应并处理用户请求。一个引擎可以绑定多个Connter。 |
Host | 虚拟主机 |
Context | 应用的上下文,配置路径映射path=>directory |
Tomcat目录介绍
/usr/local/tomcat/bin
# 工具,脚本及启动时用到的类(二进制程序startup.sh shutdown.sh catalina.sh)
/usr/local/tomcat/conf
# 配置文件 server.xml
/usr/local/tomcat/lib
# 库文件,存放jar包,用来连接后端不同的应用程序,相当于httpd的模块文件
/usr/local/tomcat/logs
# 日志文件目录
/usr/local/tomcat/webapps
# 默认的应用程序目录
/usr/local/tomcat/work
# 工作目录,存放编译后的字节码文件
/usr/local/tomcat/temp
# 临时文件目录
/etc/tomcat
# 主配置配置文件目录: /etc/tomcat/
/etc/tomcat/server.xml
# 主配置文件
/usr/share/tomcat/webapps/
# 两个路径是链接的,里面目录都一样
/var/lib/tomcat/webapps/
# 这两个目录下文件和/usr/share/tomcat/webapps/下是同步的
[http://39.108.140.0:8080](http://39.108.140.0:8080/) # 打开浏览器系统默认会显示/var/lib/tomcat/webapps/ROOT/index.jsp的文件主页面
Tomcat核心文件
/usr/local/tomcat/conf/server.xml
<Server> # Tomcat实例
<Service> # 定义网站服务
<Connector /> # 定义对外提供服务的端口
<Engine> # Tomcat虚拟主机运行的环境
<Host> # Tomcat虚拟主机
<Context>
# 某应用程序的数据文件存放目录
<Context/>
</Host>
</Engine>
</Service>
</Server>
# Server(服务): tomcat的一个实例,实际部署tomcat多实例时,每一个实例都需要准备配置文件,表示一个运行于JVM的tomcat实例.
# Service: 将connector关联至engine,因此一个server内部只有一个service,一个service内部只有一个engine,但是一个service内部可以有多个connector.
# Connector: 连接器,接受用户请求,类似于httpd的listen配置监听端口,根据需要可以有多个,8080端口在这里定义的;
# Engine:核心容器组件,catalina引擎,负责通过connector接受用户请求,并处理请求,将请求转至对应的虚拟主机host.
# Host:类似于httpd中的虚拟主机,一般而言支持基于FQDN的虚拟主机.
# Context:
# 应用程序的数据文件存放的目录名字为ROOT的时候是不需要写的,但是如果不是ROOT的名字就必须要写context的配置
/web/app/ROOT 不需要context
/web/app/test 需要context
# alias: 为webapp指定额外的属性,如部署方式等.
# Valve: 阀门,拦截请求并在将其转至对应的webapp前进行某种处理操作,可以用于任何容器中,比如记录日志(access log valve),基于IP做访问控制(remote address filter value);
# logger: 日志记录器,用于记录组件内部的状态信息,可以用于除context外的任何容器中;
# realm: 可用于任意容器类的组件中,关联一个用户认证库,实现认证和授权,可以关联的认证库有两种: UserDatebaseRealm,MemoryRealm和JDBCRealm;
# MemoryRealm: 认证信息定义在tomcat-user.xml中;
# JDBCRealm: 认证信息定义在数据库中,并通过JDBC连接至数据库中查找认证用户;
Listener className:tomcat在实现时调用的内部代码的类,调用类来实现某些功能
8009端口:AJP协议用的,是tomcat和apache结合使用的,现在用的不多了,可注释掉
pattern="%h %l %u %t "%r" %s %b" />:日志的格式:
%h 客户端的ip
%l 客户端的用户名
%u 基于密码认证的用户名
%t 访问的时间
" 双引号
%r http请求报文里面第一行内容 uri地址和http协议的版本
%s 状态码
%b http报文大小
在tomcat配置文件/conf/server.xml下配置
className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%{X-Forwarded-For}i %h %l %u %t %r %s %b" />
systemctl restart tomcat
Tomcat配置文件注释
<?xml version='1.0' encoding='utf-8'?>
<!--
<Server>元素代表整个容器,是Tomcat实例的顶层元素.由org.apache.catalina.Server接口来定义.它包含一个<Service>元素.并且它不能做为任何元素的子元素.
port指定Tomcat监听shutdown命令端口.终止服务器运行时,必须在Tomcat服务器所在的机器上发出shutdown命令.该属性是必须的.
shutdown指定终止Tomcat服务器运行时,发给Tomcat服务器的shutdown监听端口的字符串.该属性必须设置
-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!--service服务组件-->
<Service name="Catalina">
<!--
connector:接收用户请求,类似于httpd的listen配置监听端口.
port指定服务器端要创建的端口号,并在这个端口监听来自客户端的请求。
address:指定连接器监听的地址,默认为所有地址(即0.0.0.0)
protocol连接器使用的协议,支持HTTP和AJP。AJP(Apache Jserv Protocol)专用于tomcat与apache建立通信的, 在httpd反向代理用户请求至tomcat时使用(可见Nginx反向代理时不可用AJP协议)。
minProcessors服务器启动时创建的处理请求的线程数
maxProcessors最大可以创建的处理请求的线程数
enableLookups如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip地址
redirectPort指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号
acceptCount指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
connectionTimeout指定超时的时间数(以毫秒为单位)
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!--engine,核心容器组件,负责通过connector接收用户请求,将请求转至对应的虚拟主机host
defaultHost指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的
-->
<Engine name="Catalina" defaultHost="localhost">
<!--Realm表示存放用户名,密码及role的数据库-->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<!--
host表示一个虚拟主机
name指定主机名
appBase应用程序基本目录,即存放应用程序的目录.一般为appBase="webapps" ,相对于CATALINA_HOME而言的,也可以写绝对路径。
unpackWARs如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接从WAR文件中运行应用程序
autoDeploy:在tomcat启动时,是否自动部署。
xmlValidation:是否启动xml的校验功能,一般xmlValidation="false"。
xmlNamespaceAware:检测名称空间,一般xmlNamespaceAware="false"。
-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!--
Context表示一个web应用程序,通常为WAR文件
docBase应用程序的路径或者是WAR文件存放的路径,也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径。
path表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/path/****
reloadable这个属性非常重要,如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,可以在不重启tomcat的情况下改变应用程序
-->
<Context path="" docBase="" debug=""/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
Tomcat三种运行模式
# Tomcat是一个jsp/server容器,三种运行模式,BIO,NIO和APR.HTTP协议;
# Tomcat的连接器有两种: HTTP和AJP
# AJP:面向数据包的基于TCP/IP的协议,它在Apache和Tomcat的实例之间提供了一个专用通信通道;
主要有以下特征:
1.在快速网络有较好的性能表现,支持数据压缩传输;
2.支持SSL,加密及客户端证书;
3.支持Tomcat实例集群;
4.支持在Apache和Tomcat之间的重用;
BIO
- 使用传统的javaI/O操作,基于java的http/1.1连接器,Tomcat7以下版本默认以BIO模式运行的。当中性能最低;
一个线程处理一个请求,缺点:并发量很高时,线程数较多,浪费资源;
@H_403_226@
- 是javaSE1.4及后续版本提供的一种新的I/O操作方式,基于缓冲区,并能提供非阻塞I/O操作的Java API,他拥有比传统I/O操作更好的并发运行性能;
- 利用java的异步请求IO处理,可以通过少量的线程处理大量的请求;8默认NIO; @H_403_226@
- Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理问阿金读取或网络传输操作,大大提高Tomcat对静态文件处理性能,高并发应用首选模式;
- APR是原生C语言编写的非阻塞I/O,利用了操作系统的网络连接功能,连接很快,需要先安装APR和Native,若直接启动就支持APR,能大幅度提升性能;
需要以下三个组件支持:
APR library,自带的Tomcat-native,OpenSSL libraries; - 根据工作分为: 作为独立服务器和应用程序服务器; @H_403_226@
NIO
APR
Tomcat管理
测试功能,生产环境不要用。
Tomcat管理功能用于对Tomcat自身以及部署在Tomcat上的应用进行管理的web应用。在默认情况下是处于禁用状态的。如果需要开启这个功能,就需要配置管理用户,即配置前面说过的tomcat-users.xml。
cat /usr/local/tomcat/conf/tomcat-users.xml
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>
</tomcat-users>
# tomcat7以上版本还需要修改以下两个文件
# 默认文件是下面这样
cat webapps/host-manager/Meta-INF/context.xml
<Context antiResourceLocking="false" privileged="true" >
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.d+.d+.d+|::1|0:0:0:0:0:0:0:1" />
</Context>
# 这段代码的作用是限制来访IP的,127.d+.d+.d+|::1|0:0:0:0:0:0:0:1,是正则表达式,表示IPv4和IPv6的本机环回地址,所以这也解释了,为什么我们本机可以访问管理界面,但是其他机器确是403。
# 那么修改一下这里的正则表达式即可,我们修改为所有人都可以访问,那么改成这样就可以:
cat webapps/host-manager/Meta-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="^.*$" />
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
WEB站点部署
部署(deploy)webapp的相关操作
将应用程序文件和其依赖的类资源都放到主页面路径里
部署的两种方式:
1.自动部署: auto deploy
2.手动部署:
# 冷部署: 把webapp复制到指定的位置,而后才启动tomcat;
# 热部署: 在不停止tomcat的前提下进行部署: (支持热部署)需要依赖以下工具
# 部署工具: manager,ant脚本,tcd(tomcat client deployer)等
# undeploy: 拆除(反部署),停止webapp,并从tomcat实例上卸载webapp;
webapp归档格式:
.war:webapp;
(如果从程序员那里得到的是.war格式的文件,则直接放在主页面目录下就可以了,系统会自动展开的)
.jar:EJB的类打包文件(类库);
.rar:资源适配器类打包文件;
.ear:企业级webapp;
java代码打包示例
我们先写一个java版本的helloworld
cat Hello.java
public class Hello
{
public static void main (String args[])
{
System.out.println ("Hello World!");
}
}
javac Hello.java // 编译
java -cp . Hello
Hello World!
// 打包成jar包
jar -cvf hello.jar Hello.class
// 此时不能直接java -jar 运行,需要修改下jar包解压出来的manifest文件,里面记载着一些启动参数,如果是可运行的jar包,这个是必不可少的,所以我们去修改下
// jar包其实就是一个压缩的zip包,不过后缀名是jar,所以可以当成zip解压修改后再重新打包
unzip hello.jar
vim Meta-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 1.8.0_151 (Oracle Corporation)
Main-Class: Hello
jar cvfm hello.jar ./Meta-INF/MANIFEST.MF ./Hello.class
java -jar hello.jar
Hello World!
// 打包成war包
// 将当前目录打包成war包
jar cvf test.war */ .
// 命令格式:
// java cvf 打包文件名称 要打包的目录 打包文件保存路径
// 解压自然就是:
jar xvf temp.war
cp test.war /usr/local/tomcat/webapps/
// 重新启动下tomcat
ls /usr/local/tomcat/webapps/test
Hello.class hello.jar Hello.java Meta-INF
可以看到有我们之前打包的代码了
jar包和war包的介绍和区别
JavaSE程序能够打包成Jar包(J其实能够理解为Java了),而JavaWeb程序能够打包成war包(w其实能够理解为Web了)。而后把war发布到Tomcat的webapps目录下,Tomcat会在启动时自动解压war包。web
JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它容许将许多文件组合成一个压缩文件。为 J2EE 应用程序建立的 JAR 文件是 EAR 文件(企业 JAR 文件)。app
JAR 文件格式以流行的 ZIP 文件格式为基础。与 ZIP 文件不一样的是,JAR 文件不只用于压缩和发布,并且还用于部署和封装库、组件和插件程序,并可被像编译器和 JVM 这样的工具直接使用。在 JAR 中包含特殊的文件,如 manifests 和部署描述符,用来指示工具如何处理特定的 JAR。webapp
若是一个Web应用程序的目录和文件很是多,那么将这个Web应用程序部署到另外一台机器上,就不是很方便了,咱们能够将Web应用程序打包成Web 归档(WAR)文件,这个过程和把Java类文件打包成JAR文件的过程相似。利用WAR文件,能够把Servlet类文件和相关的资源集中在一块儿进行发布。在这个过程当中,Web应用程序就不是按照目录层次结构来进行部署了,而是把WAR文件做为部署单元来使用。工具
一个WAR文件就是一个Web应用程序,创建WAR文件,就是把整个Web应用程序(不包括Web应用程序层次结构的根目录)压缩起来,指定一个.war扩展名。下面咱们将第2章的Web应用程序打包成WAR文件,而后发布.net
要注意的是,虽然WAR文件和JAR文件的文件格式是同样的,而且都是使用jar命令来建立,但就其应用来讲,WAR文件和JAR文件是有根本区别的。JAR文件的目的是把类和相关的资源封装到压缩的归档文件中,而对于WAR文件来讲,一个WAR文件表明了一个Web应用程序,它能够包含 Servlet、HTML页面、Java类、图像文件,以及组成Web应用程序的其余资源,而不单单是类的归档文件。插件
咱们何时应该使用WAR文件呢?在开发阶段不适合使用WAR文件,由于在开发阶段,常常须要添加或删除Web应用程序的内容,更新 Servlet类文件,而每一次改动后,从新创建WAR文件将是一件浪费时间的事情。在产品发布阶段,使用WAR文件是比较合适的,由于在这个时候,几乎不须要再作什么改动了。blog
在开发阶段,咱们一般将Servlet源文件放到Web应用程序目录的src子目录下,以便和Web资源文件区分。在创建WAR文件时,只须要将src目录从Web应用程序目录中移走,就能够打包了。
Jar包介绍
#很多时候开发会给我们一个jar包,让我们进行运行,命令如下
nohup java -jar jar包名称.jar > user.out &
上线代码两种方式:
# 第一种方式是直接将程序目录放到webapps目录下面
# 第二种方式是使用开发工具将程序打包成war包,然后上传到webapps目录下面
自定义默认网站目录
// 将meminfo.jsp或其他程序放在tomcat/webapps/ROOT目录下即可。因为默认网站根目录为tomcat/webapps/ROOT
vim /usr/local/tomcat/conf/server.xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="" docBase="/application/tomcat/webapps/test" debug="0" reloadable="false" crossContext="true"/>
Tomcat虚拟主机
一个应用程序在某一个端口启动运行产生了一系列的进程就是一个实例,让tomcat启动两个不同的相互独立的进程,产生两个不同的套接字,分别运行在不同的端口,让不同的端口响应不同的请求,就是多实例.
作用
# 1.多个实例运行相同的应用,实现负载均衡,支持高并发处理,解决session问题.
# 2.多个实例运行不同的应用(类似虚拟主机)
多实例Example
配置三个Tomcat实例,分别运行/webapps/ROOT下的同一网站,达到负载均衡的作用
实例目录 | 工作端口 | 实例端口 |
---|---|---|
tomcat_instance1: /usr/local/tomcat/instance1/{conf,logs,temp,work} | 8081 | 8091 |
tomcat_instance2: /usr/local/tomcat/instance1/{conf,work} | 8082 | 8092 |
tomcat_instance3: /usr/local/tomcat/instance1/{conf,work} | 8083 | 8093 |
1.安装JDK环境
# CentOS7安装Java,有tar包和rpm包两种
1>. rpm -ivh jdk-8u121-linux-x64.rpm
2>. tar xvf jdk-8u151-linux-x64.tar.gz -C /usr/local/
cd /usr/local/
mv jdk1.8.0_151/ jdk
tail -3 /etc/profile
JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
source /etc/profile
2.安装Tomcat
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.55/bin/apache-tomcat-8.5.55.tar.gz
tar xvf apache-tomcat-8.5.47.tar.gz -C /usr/local/
ln -s /usr/local/apache-tomcat-8.5.47/ /usr/local/tomcat
tail -1 /etc/profile
export CATALINA_HOME=/usr/local/tomcat
source /etc/profile
env |grep -i home
CATALINA_HOME=/usr/local/tomcat
HOME=/root
# 查看熵池的大小:
cat /proc/sys/kernel/random/entropy_avail 180
增加熵池大小,解决Tomcat在CentOS 7巨慢的问题
# 安装rng服务,增大熵池
yum -y install rng-tools
systemctl start rngd && systemctl enable rngd
# 启动服务访问Tomcat页面快一百倍..
3.启动Tomcat
/usr/local/tomcat/bin/catalina.sh start
# ss -antp |grep java
# LISTEN 0 100 *:8009 *:* users:(("java",fd=58))
# LISTEN 0 100 *:8080 *:* users:(("java",fd=53))
# LISTEN 0 1 127.0.0.1:8005 *:* users:(("java",fd=73))
/usr/local/tomcat/bin/shutdown.sh
配置多实例目录
mkdir /webapps/ROOT -p
echo "welcome to tomcat mulit instance" > /webapps/ROOT/index.jsp
echo "hello everyone" > /webapps/ROOT/a.jsp
mkdir -p /usr/local/tomcat/instance{1,2,3}/{conf,work}
配置实例server.xml
\cp /usr/local/tomcat/conf/* /usr/local/tomcat/instance1/conf/
\cp /usr/local/tomcat/conf/* /usr/local/tomcat/instance2/conf/
\cp /usr/local/tomcat/conf/* /usr/local/tomcat/instance3/conf/
# Context配置
# Context作用
# 路径映射
# 应用独立配置,例如单独配置应用日志,单独配置应用访问控制
vim /usr/local/tomcat/instance1/conf/server.xml
<Server port="8091" shutdown="SHUTDOWN"> # 管理实例端口
<Connector port="8081" protocol="HTTP/1.1" # 提供web服务端口
connectionTimeout="20000"
redirectPort="8443" />
<Host name="localhost" appBase="/webapps"
# 如果两个实例对应两个不同的页面,那么直接修改appBase后端的路径就可以了
unpackWARs="true" autoDeploy="true">
vim /usr/local/tomcat/instance2/conf/server.xml
<Server port="8092" shutdown="SHUTDOWN">
<Connector port="8082" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Host name="localhost" appBase="/webapps"
unpackWARs="true" autoDeploy="true">
vim /usr/local/tomcat/instance3/conf/server.xml
<Server port="8093" shutdown="SHUTDOWN">
<Connector port="8083" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Host name="localhost" appBase="/webapps"
unpackWARs="true" autoDeploy="true">
创建一个脚本方便启动
chmod +x /usr/local/tomcat/instance1/ins1.sh
#每个tomcat下的instance都要创建一个ins1.sh,并且修改里面的instance
#!/bin/bash
#instace1 script
export JAVA_OPTS='-Xms64m -Xmx128m'
#tomcat实例启动时最小分配的内存为64M,最大为128M
export CATALINA_HOME=/usr/local/tomcat
#tomcat的安装目录
export CATALINA_BASE=/usr/local/tomcat/instance1
#实例1的目录
case $1 in
start)
$CATALINA_HOME/bin/startup.sh
;;
stop)
$CATALINA_HOME/bin/shutdown.sh
;;
restart)
$CATALINA_HOME/bin/shutdown.sh
sleep 3
$CATALINA_HOME/bin/startup.sh
;;
esac
chmod +x /usr/local/tomcat/instance1/ins1.sh
cp instance1/ins1.sh instance2/
cp instance1/ins1.sh instance3/
vim instance3/ins1.sh
vim instance2/ins1.sh # 修改tomcat安装目录instanace分别对应什么目录即可
/usr/local/tomcat/instance1/ins1.sh start
/usr/local/tomcat/instance2/ins1.sh start
/usr/local/tomcat/instance3/ins1.sh start
elinks --dump 39.108.140.0:8081
# welcome to tomcat mulit instance
elinks --dump 39.108.140.0:8082
# welcome to tomcat mulit instance
elinks --dump 39.108.140.0:8083
# welcome to tomcat mulit instance
Nginx+Tomcat负载均衡
用户在访问时,需要手动输入端口号,所以需要一个代理服务器,使用Nginx做代理,用户访问Nginx,然后由Nginx访问后端的tomcat。代理方案有两种.
客户端所有请求全部代理到后端Tomcat服务器
修改配置文件,重启服务
# 为了测试看效果使用不同的页面
mkdir /webapp{1..3}
mkdir /webapps1/ROOT
mkdir /webapps2/ROOT
mkdir /webapps3/ROOT
echo webapp1 > /webapps1/ROOT/index.jsp
echo webapp2 > /webapps2/ROOT/index.jsp
echo webapp3 > /webapps3/ROOT/index.jsp
vim /usr/local/tomcat/instance1/conf/server.xml # 分别修改三个配置文件的appBase
vim /usr/local/tomcat/instance2/conf/server.xml
vim /usr/local/tomcat/instance3/conf/server.xml
# 除了修改配置文件appBase,为保证后端Tomcat服务器的日志可以记录客户端真实IP
vim /usr/local/tomcat/instance1/conf/server.xml
prefix="localhost_access_log" suffix=".txt"
pattern="**%{x-real-ip}i** %l %u %t "%r" %s %b" />
/usr/local/tomcat/instance3/ins1.sh start
/usr/local/tomcat/instance2/ins1.sh start
/usr/local/tomcat/instance1/ins1.sh start
配置Nginx
vim /etc/Nginx/Nginx.conf
http {
upstream tomcatsrv {
server 39.108.140.0:8081 weight=1 max_fails=2 fail_timeout=2;
server 39.108.140.0:8082 weight=1 max_fails=2 fail_timeout=2;
server 39.108.140.0:8083 weight=1 max_fails=2 fail_timeout=2;
}
vim /etc/Nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcatsrv;
proxy_set_header x-real-ip $remote_addr;
root /usr/share/Nginx/html;
index index.html index.htm;
}
Nginx -s reload
elinks --dump 39.108.140.0
webapp1
elinks --dump 39.108.140.0
webapp2
elinks --dump 39.108.140.0
webapp3
# 我们去看下tomcat日志是否记录了真实日志
tail -2 /usr/local/tomcat/instance1/logs/localhost_access_log.2019-11-05.txt
39.108.140.0 - - [05/Nov/2019:12:28:17 +0800] "GET / HTTP/1.0" 200 8
47.92.24.137 - - [05/Nov/2019:12:35:13 +0800] "GET / HTTP/1.0" 200 8
客户端访问静态页面由Nginx解析,客户端如访问jsp页面访问请求代理到后端Tomcat服务器
只需要准备一台能解析静态页面的Nginx,或者httpd,修改下配置文件即可
vim /etc/Nginx/Nginx.conf
http {
upstream Nginxsrv {
server 49.233.69.195:80 weight=1 max_fails=2 fail_timeout=2;
}
upstream tomcatsrv {
server 39.108.140.0:8081 weight=1 max_fails=2 fail_timeout=2;
server 39.108.140.0:8082 weight=1 max_fails=2 fail_timeout=2;
server 39.108.140.0:8083 weight=1 max_fails=2 fail_timeout=2;
}
vim /etc/Nginx/conf.d/default.conf
location ~* \.html$ {
root /usr/share/Nginx/html;
index index.html index.htm;
proxy_pass http://Nginxsrv;
proxy_set_header x-real-ip $remote_addr;
}
location ~* \.jsp$ {
proxy_pass http://tomcatsrv;
proxy_set_header x-real-ip $remote_addr;
}
Nginx -s reload
elinks --dump 39.108.140.0/index.html
welcome to Nginx
elinks --dump 39.108.140.0/index.jsp
webapp1
elinks --dump 39.108.140.0/index.jsp
webapp2
如果tomcat上面搭建的是一个实际的网站,点击登录去登录,却发现登录不成功,可能是session会话不一致的问题
session(会话) 暂时没有使用共享方式,目前采用的会话保持,软件方面可以通过会话同步到数据库是实现session会话共享。或者前方代理比如Nginx使用ip_hash之类的算法,一个用户固定访问后端的一个web服务器
即将同一个client的访问始终调度到同一后端实例.后面文章有写如何使用redis共享会话