Tomcat和Java基础
软件架构模式
- 分层架构:表现层,业务层,持久层,数据库层
- 事件驱动架构:分布式一步架构,调度解耦
- 微内核架构:即插件式架构,把大的架构做成小的核心模块和插件的形式。
- 微服务架构:API REST-based,application REST-based,中心化消息,组成架构的每个模块都是一个服务,都需要监听套接字。
- 基于空间的架构:云架构
Java代码的运行:
*.java(source code) –> javac –> *.class(bytecode)
jvm:class loader,加载程序的类文件,及程序的类文件依赖到的其它的类文件而后运行; 整个运行表现为一个jvm进程;threads;
java技术体系:
- Java编程语言
- Java Class文件格式
- Java API
- Java VM
class loader
执行引擎
JVM运行时区域:
- 方法区:线程共享; 用于存储被JVM加载的class信息、常量、静态变量、方法等;堆:是jvm所管理的内存中占用空间最大的一部分;也是GC管理的主要区域;存储对象;
- Java栈:线程私有,存储 线程自己的局部变量;
- PC寄存器:线程私有的内存空间,程序的指令指针;
- 本地方法栈:
安装JDK
了解当前的Java环境
~]#java -version
JDK分类:
openjdk
java-VERSION-openjdk:
The OpenJDK runtime environment.
java-VERSION-openjdk-headless:
The OpenJDK runtime environment without audio and video support.
java-VERSION-openjdk-devel:
The OpenJDK development tools.
注意:多版本并存时,可使用alternatives命令设定默认使用的版本。
Oracle JDK:
安装相应版本的rpm包;
jdk-VERSION-OS-ARCH.rpm
例如:jdk-1.8.0_25-linux-x64.rpm
注意:安装完成后,要配置JAVA_HOME环境变量,指向java的安装路径;
OpenJDK:
JAVA_HOME=/usr
Oracle JDK:
JAVA_HOME=/usr/java/jdk_VERSION
JVM是C语言编写的,其需要编写多个版本以适应不同的操作系统,而Java程序则只需一个版本就可以运行在不同的操作系统之上,即一次编写,处处运行。Java是纯对象编程。
编译:将源代码转换成对CPU指令集调用的格式,使其可以在CPU上运行。
Java的编译:将Java程序转换成可以在JVM上运行的格式。
编译运行和解释运行:
编译运行:将程序编译完成后在运行,运行速度快。
解释运行:编译一行,运行一行,运行速度慢。
J2SE:Standard Edition,标准版
J2ME:Mobile Edition,移动版
J2EE:Enterprise Edition,企业版
JDK:Java development killer Java开发工具箱
GC:垃圾回收器
Java程序运行过程:
.jsp -> Jasper -> .java -> JavaC -> .class -> Servlet ->
jsp时Java 2 EE类库中的组件。
使用Tomcat前的准备工作
安装JDK
jdk有两种,openjdk和oraclejdk,
#####rpm包方式安装官方OracleJDK(需先下载rpm包)
1 | [root@node01 ~]# rpm -ivh jdk-8u191-linux-x64.rpm |
安装目录为
1 | [root@node01 ~]# ls /usr/java/ -l |
其中latest和default可以不是同一个,只需手动修改符号链接即可。
测试安装是否成功
1 | [root@node01 bin]# pwd |
如果能看到Java的版本号说明JDK安装成功。
将Java加入环境变量
1 | [root@node01 bin]# vi /etc/profile.d/java.sh |
安装openjdk
1 | [root@node01 bin]# yum -y install java-11-openjdk-devel |
jdk多版本是可以同时安装的,可以使用alternatives命令设定默认使用的版本。
安装Tomcat
yum安装
Tomcat相关包介绍
1 | [root@node01 bin]# yum list tomcat* |
安装Tomcat
1 | [root@node01 bin]# yum -y install tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp |
安装完成后会自动生成一个unit file,可借助该unit file管理Tomcat。
Tomcat本身是java编写的文件,其各项功能的实现都需要通过类文件。提供类文件的包为tomcat-lib
1 | [root@node02 yum.repos.d]# yum info tomcat-lib |
tomcat默认监听的端口有
- 8080:http
- 8009:ajp
- 8005: 管理接口
二进制安装
由于yum仓库提供的版本比较旧,因此可以选择到官网下载较新的安装包自行安装。
1 | [root@node02 tools]# wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.gz |
经过以上步骤,实现了两种方式安装tomcat
OpenJDK 11 + Tomcat 7.0
Oracle JDK 8u191 + Tomcat 8.5
配置tomcat
tomcat的配置文件构成:
server.xml:主配置文件;
web.xml:每个webapp只有“部署”后才能被访问,它的部署方式通常由web.xml进行定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认部署相关的配置;
context.xml:每个webapp都可以专用的配置文件,它通常由专用的配置文件context.xml来定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置;
tomcat-users.xml:用户认证的账号和密码文件;
catalina.policy:当使用-security选项启动tomcat时,用于为tomcat设置安全策略;
catalina.properties:Java属性的定义文件,用于设定类加载器路径,以及一些与JVM调优相关参数;
logging.properties:日志系统相关的配置; log4j
Tomcat的核心组件:server.xml
<Server>
<Service>
<connector/>
<connector/>
...
<Engine>
<Host>
<Context/>
<Context/>
...
</Host>
<Host>
...
</Host>
...
</Engine>
</Service>
</Server>
每一个组件都由一个Java“类”实现,这些组件大体可分为以下几个类型:
顶级组件:Server
服务类组件:Service
连接器组件:http, https, ajp(apache jserv protocol)
容器类:Engine, Host, Context
被嵌套类:valve, logger, realm, loader, manager, …
集群类组件:listener, cluster, …
java时春面向对象的,所以其每个组建的应用都必须先定义成一个类。
对象式编程:以数据为中心,代码服务于数据。
类:类通过属性实例化,类要通过方法进行调用。
过程式编程:以代码为中心,数据服务于代码。
JSP WebAPP的组织结构:
/: webapps的根目录
index.jsp, index.html:主页;
WEB-INF/:当前webapp的私有资源路径;通常用于存储当前webapp的web.xml和context.xml配置文件;
META-INF/:类似于WEB-INF/;
classes/:类文件,当前webapp所提供的类;
lib/:类文件,当前webapp所提供的类,被打包为jar格式;
root /web/htdocs
bbs/index.html => /bbs/index.html
images/logo.jpg => /images/logo.jpg
WEB-INF/web.xml => /WIN-INF/web.xml
webapp归档格式:
.war:webapp
.jar:EJB的类打包文件;
.rar:资源适配器类打包文件;
.ear:企业级webapp;
部署(deploy)webapp的相关操作:
deploy:将webapp的源文件放置于目标目录(网页程序文件存放目录),配置tomcat服务器能够基于web.xml和context.xml文件中定义的路径来访问此webapp;将其特有的类和依赖的类通过class loader装载至JVM;
部署有两种方式:
自动部署:auto deploy
手动部署:
冷部署:把webapp复制到指定的位置,而后才启动tomcat;
热部署:在不停止tomcat的前提下进行部署;
部署工具:manager、ant脚本、tcd(tomcat client deployer)等;
undeploy:反部署,停止webapp,并从tomcat实例上卸载webapp;
start:启动处于停止状态的webapp;
stop:停止webapp,不再向用户提供服务;其类依然在jvm上;
redeploy:重新部署;
部署一个新子站点示例
创建站点所需的目录及测试文件
1 | [root@node02 ~]# mkdir testapp/{WEB-INF,META-INF,classes,lib} -pv |
修改配置文件
将创建的测试程序放入tomcat主站点内,如果是yum安装的tomcat,则主站点在/usr/share/tomcat/webapps/目录下,这里是二进制安装的tomcat,如下:
1 | [root@node02 webapps]# cp -r /root/testapp-v0.1/ . |
此时在浏览器访问该站点就可以看到该程序内容
将上述的子站点更改为一个独立的虚拟主机
修改配置文件,在engine内新增一个Host
1 | [root@node01 ~]# vi /etc/tomcat/server.xml |
tomcat的工作目录
1 | [root@node02 work]# pwd |
tomcat的server.xml配置文件
1 | [root@node02 tomcat]# vi conf/server.xml |
定义虚拟主机host组件的常用属性说明
(1) appBase:此Host的webapps的默认存放目录,指存放非归档的web应用程序的目录或归档的WAR文件目录路径;可以使用基于$CATALINA_BASE变量所定义的路径的相对路径;
(2) autoDeploy:在Tomcat处于运行状态时,将某webapp放置于appBase所定义的目录中时,是否自动将其部署至tomcat;
在server.xml中新增一个host用于测试
1 | <Host name="www.msq.com" appBase="/data/testapp" |
此时在linux中按照配置生成测试文件如下
1 | [root@node02 tomcat]# tree /data/ |
此时在浏览器中就可以基于主机名访问host,注意名字解析!
context组件
Context组件:类似于nginx中的alias。可内嵌与host组建中使用。
示例:
<Context path="/PATH" docBase="/PATH/TO/SOMEDIR" reloadable=""/>
Context使用示例,在上述创建的host中内嵌一个Context
1 | <Host name="www.msq.com" appBase="/data/testapp" |
valve组件
过滤器
Valve存在多种类型:
定义访问日志:org.apache.catalina.valves.AccessLogValve
定义访问控制:org.apache.catalina.valves.RemoteAddrValve
<Valve className="org.apache.catalina.valves.RemoteAddrValve" deny="172\.16\.100\.67"/>
manager app
管理应用程序的组件,程序的部署,反部署,启动,停止,增加虚拟主机或删除虚拟主机。
使用manager app
编辑tomcat-users.xml配置文件在其中增加一个管理用户
1 | [root@apache ~]#cd /etc/tomcat/ |
之后在网站首页点击manager-app,输入用户名和密码即可使用manager app
在manager app中可以很方便的部署应用程序。
host manager
管理虚拟主机的组件,可以停止或者启动,删除虚拟主机。
使用nginx反向代理tomcat
使用nginx方向代理tomcat,如果被代理的tomcat上有多个虚拟主机时,要写被代理主机的主机名而非ip地址,如果内网主机太多时,就需要构建内网dns服务器。有两种代理方式
一、将所有的请求都代理给tomcat
location / {
proxy_pass http://127.0.0.1:8080
}
二、动静分离的方式代理
location ~* \.(jsp|do) {
proxy_pass http://127.0.0.1:8080;
}
location / {
root /data/myapp/ROOT/;
}
将tomcat放在docker容器中,在宿主机上安装nginx,使用nginx方向代理tomcat
1 | [root@apache ~]#docker run --name tc1 -v /uar/local/tomcat/webapps/ tomcat:8.5-alpine |
使用httpd反向代理tomcat
httpd的代理模块:
proxy_module
proxy_http_module:适配http协议客户端;
proxy_ajp_module:适配ajp协议客户端;
proxy_http_module代理配置示例:
<VirtualHost *:80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://tc1.magedu.com:8080/
ProxyPassReverse / http://tc1.magedu.com:8080/
<Location />
Require all granted
</Location>
</VirtualHost>
<LocationMatch "\.(jsp|do)$>
ProxyPass / http://tc1.magedu.com:8080/
</LocationMatch>
proxy_ajp_module代理配置示例:
<VirtualHost *:80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / ajp://tc1.magedu.com:8009/
ProxyPassReverse / ajp://tc1.magedu.com:8009/
<Location />
Require all granted
</Location>
</VirtualHost>
<%@ page language=”java” %>
TomcatA.magedu.com
Session ID | <% session.setAttribute("magedu.com","magedu.com"); %><%= session.getId() %> |
Created on | <%= session.getCreationTime() %> |
tomcat会话保持
session sticky:会话保持,需要调度器用调度算法解决,会影响调度器的调度效果,也会导致session单点故障风险。
session replication cluster:后端服务器,组织成集群,会增加服务器负载。
session server:在后端服务器之后设置session服务器专门存储session,session放在专门的session server上。将问题不断后置,对session server需要做高可用及主从。
在使用nginx负载均衡tomcat时,默认的算法为轮询(round roubin),这会导致每一个会话都会被当成一个新会话,没有会话保持的功能,session会话保持一:session sticky可以利用负载均衡器的算法实现:
配置负载均衡器
1 | [root@docker ~]#vi /etc/nginx/nginx.conf |
上述配置可以实现将每个请求根据源地址哈希之后,都转发给固定的web服务器响应,但是这会影响负载均衡的效果,也会导致session单点丢失的可能。
基于httpd的sessionsticky和blancer-manager功能
1 | ~]#vi /etc/httpd/conf.d/tomcat-httpd-claster.conf |
session replication cluster
配置server.xml文件,在host配置段增加一个cluster的配置。
1 | [root@apache tomcat]#vi /etc/tomcat/server.xml |
配置web.xml文件,添加以下元素
1 | [root@apache tomcat]#vi /webapps/myapp/WEB-INF/web.xml |
此时,session cluster就完成了配置,重启tomcat服务器就可以实现session replication cluster。
session server
将session会话保存到特殊的存储服务器上,存储系统性能要足够高,而且要有冗余能力,
基于memcached建立session server
memcached是一种基于cache的存储系统,
- cache:无持久能力,重启后数据丢失。
redis是一种store类型的存储系统
- store:持久是必备功能
memcached实用内存的方法,将分配的内存一次性占用完,做预分配,减少出现内存随便,
安装memcached
1 | ~]#yum -y install memcached |
安装memcached客户端命令
1 | ~]#yum -y install libmemcached |
tomcat要使用memcached作为session服务器,需要安装相关组件:
https://github.com/magro/memcached-session-manager
1 | [root@apache tomcat]#wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/2.3.2/memcached-session-manager-2.3.2.jar |
修改配置文件,对需要增加配置的虚拟主机增加一个context
1 | ~]#vi /etc/tomcat/server.xml |
此时重启tomcat局可以将session保存在memcached中,需要保证java正常启动不报错,openjdk和tomcat7组合使用会报错,tomcat7和openjdk8组合使用正常。