小知识:
#tomcat
java web 程序的容器
#web 容器
weblogic 收费(java)
uwsgi python
fastcgi php
#nginx 反向代理 web 容器
JDK
java 运行时环境(JRE)
JVM java 虚拟机
依赖类库(lib)
java 集成工具
jps 专门用于查看系统中的 java 进程
bin
startup.sh
shutdown.sh
conf
server.xml
logs
catalina.out
webapps # 网站发布目录
ROOT
端口
8080 接受web请求
8005 关闭
8009 监控
server.xml
Host
appsBase 指定默认的网站发布目录
[root@localhost ~]# cd /usr/local
[root@localhost local]# ls
tomcat
[root@localhost local]# cp -r tomcat/ tomcat_2
[root@localhost local]# ls
tomcat tomcat_2
以启动多实例。多实例之间端口不能一致
[root@localhost local]# sed -i 's#8005#8011#;s#8080#8081#' tomcat/conf/server.xml
[root@localhost local]# sed -i 's#8005#8012#;s#8080#8082#' tomcat_2/conf/server.xml
[root@localhost local]# sed -i 's#8009#8019#' tomcat/conf/server.xml
[root@localhost local]# sed -i 's#8009#8029#' tomcat_2/conf/server.xml
[root@localhost local]# diff tomcat/conf/server.xml tomcat_2/conf/server.xml
22c22
< <Server port="8011" shutdown="SHUTDOWN">
---
> <Server port="8012" shutdown="SHUTDOWN">
> 67c67
> < Define a non-SSL/TLS HTTP/1.1 Connector on port 8081
---
> Define a non-SSL/TLS HTTP/1.1 Connector on port 8082
> 69c69
> < <Connector port="8081" protocol="HTTP/1.1"
---
> <Connector port="8082" protocol="HTTP/1.1"
> 75c75
> < port="8081" protocol="HTTP/1.1"
---
> port="8082" protocol="HTTP/1.1"
> 115c115
> < <!-- Define an AJP 1.3 Connector on port 8019 -->
---
> <!-- Define an AJP 1.3 Connector on port 8029 -->
> 119c119
> < port="8019"
---
> port="8029"
[root@localhost local]# ls /opt/
webapps
[root@localhost local]# cp -r /opt/webapps/ROOT/ tomcat/webapps/
cp:是否覆盖"tomcat/webapps/ROOT/WEB-INF/web.xml"?
[root@localhost local]# cp -r /opt/webapps/ROOT/ tomcat_2/webapps/
cp:是否覆盖"tomcat_2/webapps/ROOT/WEB-INF/web.xml"?
[root@localhost local]# echo 8081 >> tomcat/webapps/ROOT/index.jsp
[root@localhost local]# echo 8082 >> tomcat_2/webapps/ROOT/index.jsp
[root@localhost local]# cd tomcat_2/bin/
[root@localhost bin]# vim start.sh
[root@localhost bin]# chmod +x start.sh
#修改catalina.sh ---添加如下内容
[root@localhost bin]# vim catalina.sh
CATALINA_HOME=/usr/local/tomcat_2 #添加的环境变量注意修改
[root@localhost bin]# cd /usr/local/tomcat/bin/
[root@localhost bin]# vim start.sh
#!/bin/bash
#tomcat
export CATALINA_BASE="/usr/local/tomcat"
case "$1" in
start)
$CATALINA_BASE/bin/startup.sh
;;
stop)
$CATALINA_BASE/bin/shutdown.sh
esac
[root@localhost bin]# chmod +x start.sh
[root@localhost bin]# vim catalina.sh
CATALINA_HOME=/usr/local/tomcat
# 如果多实例部署使用的 JDK 版本不同,修改catalina.sh再这里定义java
JAVA_HOME=
JRE_HOME=
启动
[root@localhost bin]# /usr/local/tomcat/bin/start.sh start
[root@localhost bin]# /usr/local/tomcat_2/bin/start.sh start
[root@localhost bin]# netstat -lntp | grep java
tcp 0 0 127.0.0.1:8005 0.0.0.0:* LISTEN 43336/java
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 88398/java
tcp 0 0 0.0.0.0:8082 0.0.0.0:* LISTEN 88475/java
在浏览器访问,进行测试
检查多实例的启动
http://192.168.116.155:8081/
[本实验使用的是tomcat默认网站]
关闭防火墙和selinux
yum安装nginx
[root@nginx-proxy ~]# cd /etc/yum.repos.d/
[root@nginx-proxy yum.repos.d]# vim nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
[root@nginx-proxy yum.repos.d]# yum install yum-utils -y
[root@nginx-proxy yum.repos.d]# yum install nginx -y
备份原配置文件并修改
[root@localhost ~]# cd /etc/nginx/conf.d/
[root@localhost conf.d]# vim default.conf
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/proxy.access.log main;
location / {
proxy_pass http://testweb;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
创建upstream配置文件:
[root@localhost conf.d]# vim upstream.conf
upstream testweb {
server 192.168.116.155:8081 weight=1 max_fails=1 fail_timeout=2s;
server 192.168.116.155:8082 weight=1 max_fails=1 fail_timeout=2s;
}
启动nginx
[root@localhost ~]# /usr/local/nginx/sbin/nginx
使用curl 命令进行测试,tail进行关键字提取
[root@localhost /]# curl 192.168.116.157 | tail -1
8081
[root@localhost /]# curl 192.168.116.157 | tail -1
8082
http://192.168.116.157/
所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的VisualBox、VMware就属于系统虚拟机。他们完全是对物理计算机的仿真。提供了一个可以运行完整操作系统的软件平台。
程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。
同一个JAVA程序,通过JAVA虚拟机(JVM)运行于各大主流操作系统平台
比如Windows、CentOS、Ubuntu等。程序以虚拟机为中介,来实现跨平台.
我们要对JVM虚拟机的结构有一个感性的认知。毕竟我们不是编程人员,认知程度达不到那么深入。
VM中堆空间可以分成三个大区,年轻代、老年代、永久代(方法区)。
**新生代:**新生区
类在这里产生和应用,最后被垃圾回收。所有的对象在这个区被new出来,当这个区满了,GC会对该区不用的对象销毁,剩余有用的转到幸存区。
**老年代:**老年区
用于存放生成周期比较长的对象。
**永久代:**永久区
存放JDK自带的class,interface。
我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的,我在这里也认识了很多人。在年老代里,我生活了20年(每次GC加一岁),然后被回收。
jvm区域总体分两类,heap区和非heap区。
eap区又分:Eden Space(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代-养老区)。
非heap区又分:Code Cache(代码缓存区)、Perm Gen(永久代)、Jvm Stack(java虚拟机栈)、Local Method Statck(本地方法栈)。
JVM 虚拟机提供了三种类型参数
标准参数中包括功能和输出的参数都是很稳定的,很可能在将来的JVM版本中不会改变。你可以用 java 命令(或者是用 java -help)检索出所有标准参数。
非标准化的参数,在将来的版本中可能会改变。所有的这类参数都以 -X 开始。
在实际情况中 X 参数和 XX 参数并没有什么不同。X 参数的功能是十分稳定的。
用一句话来说明 XX 参数的语法。所有的 XX 参数都以"-XX:"开始,但是随后的语法不同,取决于参数的类型:
1)对于布尔类型的参数,我们有"+"或"-",然后才设置 JVM 选项的实际名称。
例如,-XX:+ 用于激活选项,而 -XX:- 用于注销选项。
Example:
开启GC日志的参数: -XX:+PrintGC
2) 对于需要非布尔值的参数,如 string 或者 integer,我们先写参数的名称,后面加上"=",最后赋值。
-Xms:初始堆大小
-Xmx:最大堆大小
实际生产环境中, 我们通常将初始化堆(-Xms) 和 最大堆(-Xmx) 设置为一样大。以避免程序频繁的申请堆空间。设置为物理内存的一半.
[root@java-tomcat1 bin]# vim catalina.sh 添加
JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx1024m"
跟踪JAVA虚拟机的垃圾回收
GC日志:jvm垃圾回收,记录jvm的运行状态,oom内存溢出的报错信息等。
开启GC日志:
[root@java-tomcat1 bin]# vim catalina.sh 添加
JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx1024m -Xloggc:/data/logs/gc-%t.log"
[root@java-tomcat1 bin]# mkdir -p /data/logs
重启tomcat
用来查看Java进程的具体状态, 包括进程ID,进程启动的路径及启动参数等等,与unix上的ps类似,只不过jps是用来显示java进程
常用参数如下:
-v:输出传给jvm的参数
#查看已经运行的JVM 进程的实际启动参数
[root@localhost ~]# jps -v
29792 Bootstrap -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp
54084 Bootstrap -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp
jstack用于打印出给定的java进程ID或远程调试服务的Java堆栈信息。此信息通常在运维的过程中被保存起来(保存故障现场),以供 RD (开发人员)们去分析故障。
常用参数如下:
jstack <pid>
jstack [-l] <pid> //长列表. 打印关于锁的附加信息
jstack [-F] <pid> //当’jstack [-l] pid’没有响应的时候强制打印栈信息
[root@localhost ~]# jstack -F 119300 > /tmp/jstack.log
#输出重定向,一般把这个东西给开发人员就好了~
类别 | 配置内容及说明 | 标准配置 | 备注 |
---|---|---|---|
降权启动 | 1.tomcat启动用户权限必须为非root权限,尽量降低tomcat启动用户的目录访问权限;2.如需直接对外使用80端口,可通过普通账号启动后,配置iptables规则进行转发; | 避免一旦tomcat 服务被入侵,黑客直接获取高级用户权限危害整个server的安全; |
[root@java-tomcat1 ~]# useradd tomcat
[root@java-tomcat1 ~]# chown tomcat.tomcat /usr/local/tomcat/ -R
[root@java-tomcat1 ~]# su -c '/usr/local/tomcat/bin/start.sh start' tomcat
Using CATALINA_BASE: /data/application/tomcat
Using CATALINA_HOME: /data/application/tomcat
Using CATALINA_TMPDIR: /data/application/tomcat/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /data/application/tomcat/bin/bootstrap.jar:/data/application/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@java-tomcat1 ~]# ps -ef | grep tomcat
tomcat 1065 1 64 20:33 ? 00:00:06 /usr/local/java/bin/java -Djava.util.logging.config.file=/data/applicationtomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /data/application/tomcat/bin/bootstrap.jar:/data/application/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/data/application/tomcat -Dcatalina.home=/data/application/tomcat -Djava.io.tmpdir=/data/application/tomcat/temp org.apache.catalina.startup.Bootstrap start
root 1112 1027 0 20:33 pts/0 00:00:00 grep --color=auto tomcat
上策:优化代码
该项需要开发经验足够丰富,对开发人员要求较高
中策:jvm优化机制 垃圾回收机制 把不需要的内存回收
优化jvm–优化垃圾回收策略
优化catalina.sh配置文件。在catalina.sh配置文件中添加代码
# tomcat分配1G堆内存模板
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m
# 重启服务
su -c '/home/tomcat/tomcat8_1/bin/shutdown.sh' tomcat
su -c '/home/tomcat/tomcat8_1/bin/startup.sh' tomcat
下策:加足够大的内存
该项的资金投入较大
下下策:每天0点定时重启tomcat
使用较为广泛
在主机名解析为 IP 地址后,资源 IP 地址将保存在 JVM 的高速缓存中。如果改变了资源的 IP 地址,则需要重新启动应用服务器,使 Identity Manager 能够检测所做更改 (ID-3635)。这是 Sun JDK(1.3 及更高版本)中的设置,可以使用 sun.net.inetaddr.ttl
属性(通常在 jre/lib/security/java.security
中设置)控制
设置解析成功的域名记录JVM中缓存的有效时间,JVM默认是永远有效,这样一来域名IP重定向必须重启JVM,这里修改为5秒钟有效,0表示禁止缓存,-1表示永远有效
java.security.Security.setProperty("networkaddress.cache.ttl", "5");
//设置解析失败的域名记录JVM中缓存的有效时间,JVM默认是10秒,0表示禁止缓存,-1表示永远有效
java.security.Security.setProperty("networkaddress.cache.negative.ttl", "2");
方式一:在JAVA_OPTS里设置
-Dsun.net.inetaddr.ttl=3 -Dsun.net.inetaddr.negative.ttl=1
方式二:修改property
System.setProperty("sun.net.inetaddr.ttl", "3");
System.setProperty("sun.net.inetaddr.negative.ttl", "1");