Jusene's Blog

JAVA Tomcat入门

字数统计: 4.4k阅读时长: 19 min
2017/06/04 Share

JAVA

JAVA一直作为企业级应用编程的不二选择,其核心理念“一次编译,到处运行”,也一直多年来位于全世界编程语言榜首,一起从运维视角探究java和tomcat。

JAVA的体系结构规范

  • java编程语言
  • java class文件格式
  • java api
  • java vm

java语言具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点,也是越来越多企业级项目转向java开发的原因,java作为纯面向对象的编程,所以的对象都是需要通过类来实现的,整个java语言的运行大致过程为: .java–>.class–>class loader–>JVM–>执行引擎

JVM的运行时区域:

  • 方法区:线程共享,用于存储被jvm加载的class信息,常量,静态变量,方法等;持久代
  • 堆:是jvm所管理的内在的最大的一部分,也是GC管理的主要区域;主流的垃圾收集算法基于分代收集机制
  • java栈:线程私有,存储线程自己的局部变量
  • PC寄存器:线程私有的内存空间,程序的指令指针
  • 本地方法栈:调用本地c库

JAVA体系:

  • JAVA 2 SE:JDK
    OpenJDK;OracleJDK
  • JAVA 2 EE:JDK+企业级类
    Servlet;JSP;EJB;JMS;JMX;JavaMail…
  • JAVA 2 ME:移动领域

Servlet+JSP构建了如今JAVA web编程的基础:

Serlet相当于为CGI提供解析成html的格式输出,而html标签需要硬编码进java代码,极其不便。
JSP为JAVA代码嵌入进html标签,java无须硬编码html标签。

Servlet index.java->javac->index.class->class loader->jvm
JSP index.jsp ->jsper->index_jsp.java->javac->index_jsp.class->class loader->jvm

Web Container

为了实现java在运行过程中自动进行通过javac编译,我们需要可以提供JAVA 2 EE的容器,而这样的web容器有许多,其中最著名的开源实现就是tomcat。

tomcat大致的实现构造,也是我们配置tomcat需要考虑的构造:

tomcat的配置文件都是通过xml文件来实现,其大致配置结构如下:

1
tomcat:
2
	<server>
3
		<service>
4
			<Connector>
5
			<Conector>
6
			<Engine>
7
				<Host>
8
					<Context>
9
					...
10
				</Host>
11
				<Host>
12
				...
13
				</Host>
14
			<Engine>
15
		</service>
16
	</server>

tomcat本身是通过java实现的,所以全部的组件也都是遵循java,每个组件都是通过类来实现。

此些组件可分为如下几类:

  • 顶级组件:server
  • 服务组件:service
  • 连接器组件:http https ajp
  • 容器类:Engine Host Context
  • 被嵌套组件:valve logger realm loader manager
  • 集群类组件:listener…

安装tomcat

tomcat由java实现所以它本身就依赖java运行环境,所以得先安装JDK:
1、安装openjdk

1
~]# yum install -y java-1.7.0-openjdk java-1.7.0-openjdk-devel
2
~]# which java
3
/usr/bin/java
4
~}# ll /usr/bin/java
5
lrwxrwxrwx. 1 root root 22 May 29 04:19 /usr/bin/java -> /etc/alternatives/java
6
~]# ll /etc/alternatives/java
7
lrwxrwxrwx. 1 root root 76 May 29 04:19 /etc/alternatives/java -> /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.141-2.6.10.1.el7_3.x86_64/jre/bin/java
8
9
所以当我们同时存在多版本的openjdk的时候,可以通过alternatives来切换openjdk
10
11
~]# vim /etc/profile.d/java.sh
12
JAVA_HOME=/usr
13
export JAVA_HOME

2、安装oraclejdk
这个需要去oracle官网下载oraclejdk,建议使用rpm包

1
~]# rpm -ivh jdk-7u80-linux-x64.rpm
2
~]# cd /usr/java/
3
~}# ll
4
total 4
5
lrwxrwxrwx. 1 root root   16 May 28 05:46 default -> /usr/java/latest
6
drwxr-xr-x. 8 root root 4096 May 28 05:46 jdk1.7.0_80
7
lrwxrwxrwx. 1 root root   21 May 28 05:46 latest -> /usr/java/jdk1.7.0_80
8
~]# vim /etc/profile.d/java.sh
9
JAVA_HOME=/usr/java/latest
10
export JAVA_HOME

1、通过yum来安装tomcat

1
~]# yum install -y tomcat tomcat-lib tomcat-webapps tomcat-admin-webapps

2、通过tomcat.apache.org下载tomcat二进制安装

1
~]# tar xf apache-tomcat-7.0.78.tar.gz -C /usr/local/
2
~]# ln -s /usr/local/apache-tomcat-7.0.78 /usr/local/tomcat
3
~]# vim /etc/profile.d/catalina.sh
4
CATALINA_BASE=/usr/local/tomcat
5
PATH=$PATH:$CATALINA_BASE/bin
6
export PATH CATALINA_BASE

tomcat目录结构:

  • bin:脚本,及启动时用到的类
  • lib:类库
  • conf:配置文件
  • logs:日志文件
  • webapps:默认的部署目录
  • work:工作目录
  • temp:临时文件目录

tomcat的配置文件:

  • server.xml:主配置文件
  • context.xml:每个webapp都可以有专用的配置文件,这些配置文件通常位于webapp应用程序自己目录下的WEB-INF目录中,此context.xml为每个webapp提供默认配置
  • web.xml:每个webapp只有在部署后才能被访问,此文件则用于为各webapps定义默认的部署方式,每个webapp都可以有专用的配置文件,这些配置文件通常位于webapp应用程序自己目录下的WEB-INF目录中。
  • tomcat-user.xml:用户认证的账号和密码文件
  • catalina.policy:当使用-security选项来启动tomcat实例时,会取此配置文件来实现安全策略的运行方式
  • catalina.properties: java属性的定义文件,用于设定类加载器路径,以及一些于jvm调优相关的参数等
  • logging.properties: 日志系统相关配置

JSP WebAPP的组织结构:
/:webapps的根目录

  • index.jsp主页
  • WEB-INF/:当前webapp的私有资源的目录,通常存放当前webapp自用的web.xml
  • META-INF/:当前webapp的私有资源的目录,通常存放当前webapp资源的context.xml
  • classes/:类文件,当前webapp的私有类
  • lib/:当前webapp的私有类,被打包成jar格式

webapp归档格式:

  • .war:webapp
  • .jar:EJB的打包文件
  • .rar:资源适配器
  • .ear:企业级应用

手动测试tomcat应用的方法:
1、创建webapp特有的目录结构
mkdir -p myapp/{classes,WEB-INF,META-INF,lib}
2、提供webapp的测试页面
myapp/index.jsp

1
<%@ page language="java" %>
2
<%@ page import="java.util.*" %>
3
<html>
4
	<head>
5
		<title>JSP Page</title>
6
	</head>
7
	<body>
8
		<% out.println("hello world!"); %>
9
	</body>
10
</html>

tomcat自带的应用程序:
manager app:webapp管理工具
host manager:vhost管理工具

如果想要访问这些app管理工具,可以在/PATH/TO/TOMCAT/conf/tomcat-users.xml

1
<role rolename="manager-gui"/>   #manager app
2
<role rolename="admin-gui"/>     #host manager
3
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>

重启tomcatcatalina.sh stop && catalina.sh start

可以查看整个tomcat的运行情况

应用管理,支持热部署

虚拟主机管理,支持直接创建虚拟主机

tomcat配置文件

1
~}# cat /usr/local/tomcat/conf/server.xml
2
<Server port="8005" shutdown="SHUTDOWN">
3
    <!--Server元素代表整个Catalina Servlet容器,是Tomcat实例的顶级元素;
4
    port,指定Tomcat服务器监听shutdown命令的端口;
5
    shutdown,指定当终止Tomcat服务器时,发送给它的shutdown监听端口的字符串。 -->
6
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
7
      <!-- className,指定实现此Server接口的类。-->
8
9
  <Service name="Catalina">
10
      <!-- Service元素用于关联一个引擎和与此引擎相关的连接器;
11
      name,用于定义Service的名字;
12
      className,指定实现此Service接口的类-->
13
    <Connector port="8080" protocol="HTTP/1.1"
14
               connectionTimeout="20000"
15
               redirectPort="8443" />
16
        <!-- Connector元素是与客户端交互的组件;
17
        port,设定监听端口号;
18
        protocol,设定使用的协议;
19
        connectionTimeout,定义超时时长,以毫秒为单位;
20
        redirectPort,如果某连接器支持的协议是http,当接收到https请求时,转发至此属性定义的端口;
21
        enableLookups,是否支持服务器对客户端进行域名解析。 -->
22
23
24
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
25
               maxThreads="150" SSLEnabled="true" >
26
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
27
        <SSLHostConfig>
28
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
29
                         certificateFile="conf/localhost-rsa-cert.pem"
30
                         certificateChainFile="conf/localhost-rsa-chain.pem"
31
                         type="RSA" />
32
        </SSLHostConfig>
33
    </Connector>
34
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
35
36
    <Engine name="Catalina" defaultHost="localhost">
37
        <!-- Engine是Servlet处理器的一个实例,即Servlet引擎;
38
        name,定义Engine的名字;
39
        defaultHost:指定处理客户端请求的默认主机名;
40
        jvmRoute,定义Tomcat路由标示。 -->
41
42
      <Realm className="org.apache.catalina.realm.LockOutRealm">
43
44
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
45
               resourceName="UserDatabase"/>
46
      </Realm>
47
48
      <Host name="localhost"  appBase="webapps"
49
            unpackWARs="true" autoDeploy="true">
50
          <!-- 定义用于接收客户端请求并进行相应处理的主机或虚拟主机;
51
          name,定义虚拟主机的名字;
52
          appBase,指定虚拟主机的目录,可以指定绝对路径,也可以指定相对于<CATALINA_HOME>的相对路径;
53
          unpackWARs,在启用此WebApp时是否对WAR格式的归档文件先进行展开;
54
          autoDeploy,在Tomcat处于运行状态时放置于appBase目录下的应用程序文件是否自动进行部署;
55
          alias,指定虚拟主机的别名,可以指定多个别名。 -->
56
          <Context path="/bbs"
57
            docBase="/web/threads/bbs"
58
            reloadable="true">
59
         </Context>
60
            <!-- Context在某些意义上类似于apache中的路径别名,一个Context定义用于标识Tomcat实例中的一个Web应用程序;
61
            path,指定访问该Web应用的URL(相对于此Web服务器根路径)入口,如果为"",则表示为此Webapp的根路径;
62
            docBase,指定Web应用的存放位置;
63
            reloadable,是否允许重新加载此context相关的Web应用程序相关的类; -->
64
65
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
66
67
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
68
               prefix="localhost_access_log" suffix=".txt"
69
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
70
        <!-- 定义日志格式;
71
        directory:指定于log存放的目录
72
        prefix:指定日志的前缀格式
73
        suffix:指定日志的结尾
74
        pattern:日志格式定义,可以参照httpd的宏定义
75
        --!>
76
      </Host>
77
    </Engine>
78
  </Service>
79
</Server>

每一个组件都是通过特定的类来实现的,而且实现的方法不止一种:

  • Server: tomcat实例:即运行的一个JVM进程,监听于8005端口接受SHUTDOWN,各Server监听的端口不能相同,因此,一个物理主机上启动多个Server实例应该使用不同的端口。

  • Service:用于实现将一个或多个Connector关联至一个Engine

  • Connector组件:
    进入tomcat的请求可分为两类
    tomcat自己作为独立的应用程序服务器:standalone,此时,请求将来之于浏览:
    http,https
    tomcat作为应用程序服务器:请求将来之于前面的反代主机
    httpd:http,https,ajp
    nginx:http,https
    属性:

    1
    address:监听的ip地址
    2
    maxThreads:最大并发连接数,默认为150
    3
    ort:监听的端口
    4
    protocol:连接器使用的协议,一般为HTTP/1.1或AJP/1.3
    5
    redirectPort:
    6
    connectionTimeout:连接的超时时长,单位为毫秒,默认为60000
    7
    enableLookups:
    8
    acceptCount:定义等待的队列的长度
    9
    scheme:
    10
    debug
    11
    secure
    12
    clientAuth
    13
    sslProtocol
  • Engine:Servlet的一个实例,即Servlet引擎,其内部可以有一个或多个Host组件来定义站点,通常需要通过defaultHost的属性定义默认虚拟主机
    属性:

    1
    name
    2
    defaultHost
    3
    jvmRoute
  • Host:位于Engine容器中用于接受请求并进行相应处理的主机和虚拟主机
    常用属性:

    1
    appBase:此host的webapps目录,即存放非归档的web应用程序的目录或归档后的war文件的目录路径;可以使用基于$CATALINA_HOME的相对路径
    2
    autoDeploy:在tomcat处于运行状态时放置于appBase目录下的应用程序文件是否自动进行deploy,默认为true
    3
    unpackWars:在启动此webapps时是否对WAR格式的归档文件先进行展开,默认为true

    虚拟主机定义实例:

    1
    <Engine name="Catalina" defaultHost="localhost">
    2
    	<Host name="localhost" appBase="webapps">
    3
    		<Context path="" docBase="ROOT"/>
    4
    		<Context path="/bbs" docBase="/www/bbs"
    5
    		reloadable="true" crossContext="true"/>
    6
    	</Host>
    7
    8
    	<Host name='jusene.com' appBase="/data/www">
    9
    	</Host>
    10
    </Engine>
  • Context组件:
    在某些意义上类似apache中的路径别名,一个context定义表示一个tomcat实例中的web应用程序;

    1
    <Context path='/chat' docBase="/web/chat"/>

    在tomcat6中,每一个context定义也可以使用一个xml文件进行,其文件的目录为$CATALINTA_HOME/conf/{engine name}/{hostname},可以用于Context中的xml元素有Loader,Manager,Realm,Resource和WatchdResource.
    常用的属性定义有:
    docBase:相应的web应用程序的存放位置,也可以使用相对路径,起始路径为此Context所属Host中的appBase定义的路径,切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字 path:相对于web服务器的根路径而言的url,如果为空,则表示为此webapp的根路径,如果context定义在一个单独的xml文件中,此属性不需要定义
    reloadable:是否允许重新加载此context相关的web应用程序的类,默认为false

  • Realm组件:
    一个Realm表示一个安全上下文,它是一个授权访问某个Context的用户列表和某用户所允许切换的角色相关定义的列表,因此,Realm就像是一个用户和组织相关的数据库,定义Realm时唯一必须提供的属性是classname,它是Realm的多种不同实现,用于表示此Realm认证的用户及角色等认证信息的存放位置。
    JAASRealm:基于java authintication and authorization service实现用户认证:
    JDBCRealm:通过jdbc访问某关系性数据库表用户认证
    JNDIRealm:基于jndi使用目录服务实现认证信息的获取,ldap
    MemoryRealm:查找tomcat-users.xml文件实现用户信息的获取
    UserDataseRealm:基于UserDatabase文件(通常是tomcat-user.xml)实现用户认证,它实现了一个完全可更新和持久有效的MemoryRealm,因此能够根标准的memoryrealm兼容,它通过JNDI实现
    下面是一个常见的userdatabase的配置:

    1
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
    2
    resourceName="UserDatabase"/>

    下面是一个使用JDBC方式获取用户认证信息的配置:

    1
    <Realm className="org.apache.catalina.realm.JDBCRealm" debug=99
    2
    driveName="org.gjt.mm.mysql.Driver"
    3
    connectionURL="jdbc:mysql://localhost/authority"
    4
    userTable="users" userNameCol="user_name"
    5
    userCredCol="user_pass"
    6
    userRoleTable="user_roles" roleNameCol="role_name" />
  • Valve组件
    Valve类似于过滤器,它可以工作于engine和host/context 之间,host和context之间以及context和web应用程序的某资源之间,一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序,Tomcat6种实现了多种不同的Valve.
    AccessLogValve:访问日志Valve
    RemoteAddrValve:基于远程地址的访问控制
    RemoteHostValve:基于远程主机名的访问控制
    AccessLogValve:

    1
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
    2
    prefix="localhost_access_log." suffix=".txt"
    3
    pattern="%h %l %u %t "%r" %s %b" />

    RemoteHostValve和RemoteAddrValve可以通过基于ip活着主机名的方式来进行访问控制,控制本身可以通过allow和deny来进行定义:

    1
    <Context path="/probe" docBase="probe">
    2
    <Valve className="org.apache.catalina.valves.RemoteAddrValve"
    3
    allow="127\.0\.0\.1"/>
    4
    </Context>

    其中相关的属性定义:
    calssroom:相关的java实现的类名,相当于分别应该为org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.RemoteAddrValve
    allow: 以逗号分开的允许访问的ip地址列表,支持正则表达式,因此,点号“.”用于ip地址时需要转义;仅定义allow时,非明确allow的地址均为deny
    deny:以逗号分开的禁止访问的ip地址列表,支持正则表达式,使用方法同allow

LNMT

1
server {
2
        listen       80;
3
        server_name  www.jusene.com;
4
        location / {
5
           proxy_pass http://127.0.0.1:8080;
6
           proxy_set_header Host $host;
7
           proxy_set_header X-Real-IP $remote_addr;
8
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
9
        }
10
}

tomcat获取真实ip

1
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
2
prefix="localhost_access_log." suffix=".txt"
3
pattern="%h %{X-Real-IP}i %l %u %t "%r" %s %b" />

LAMT

client–>http–>httpd–>reverse_proxy_module(http)–>tomcat(http connector)
client–>http–>httpd–>reverse_proxy_module(ajp)–>tomcat(ajp connector)

  1. 第一种方式:proxy_module;proxy_http_module

    1
    <VirtualHost *:80>
    2
        ServerName www.jusene.com
    3
        ProxyRequests Off            #关闭正向代理
    4
        ProxyVia On                  #开启代理经过的server
    5
        ProxyPreserveHost On         #开启透传host头部
    6
        <Proxy *>
    7
            Require all granted      #代理授权控制
    8
        </Proxy>
    9
        ProxyPass / http://127.0.0.1:8080/
    10
        ProxyPassReverse / http://127.0.0.1:8080/    #支持代理重新回写url
    11
        <Location />
    12
            Require all granted     #根授权,httpd2.4默认根拒绝访问
    13
        </Location>
    14
     </VirtualHost>
  2. 第二种方式:proxy_module;proxy_ajp_module(官方建议这样的反向代理)

    1
    <VirtualHost *:80>
    2
        ServerName www.jusene.com
    3
        ProxyRequests Off            #关闭正向代理
    4
        ProxyVia On                  #开启代理经过的server
    5
        ProxyPreserveHost On         #开启透传host头部
    6
        <Proxy *>
    7
            Require all granted      #代理授权控制
    8
        </Proxy>
    9
        ProxyPass / ajp://127.0.0.1:8009/
    10
        ProxyPassReverse / ajp://127.0.0.1:8009/    #支持代理重新回写url
    11
        <Location />
    12
            Require all granted     #根授权,httpd2.4默认根拒绝访问
    13
        </Location>
    14
     </VirtualHost>
CATALOG
  1. 1. JAVA
    1. 1.1. JAVA的体系结构规范
    2. 1.2. Web Container
    3. 1.3. 安装tomcat
    4. 1.4. tomcat配置文件
  2. 2. LNMT
  3. 3. LAMT