从零开始的Nginx [ 9 ] --- 单机多实例部署、tomcat反向代理集群、jvm虚拟机使用及排障,tomcat安全优化


小知识:

#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

1 修改端口

以启动多实例。多实例之间端口不能一致

[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"

2 启动tomcat多实例

[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

3 启动

[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

4 检查端口查看是否启动:

[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/

在这里插入图片描述
http://192.168.116.155:8082/

在这里插入图片描述

二、tomcat反向代理集群

[本实验使用的是tomcat默认网站]

1、负载均衡器说明

关闭防火墙和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

2、配置负载均衡器

备份原配置文件并修改

[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

3、使用命令进行访问测试

使用curl 命令进行测试,tail进行关键字提取

[root@localhost /]# curl 192.168.116.157 | tail -1
8081
[root@localhost /]# curl 192.168.116.157 | tail -1
8082

4、在浏览器上使用代理机进行访问测试

http://192.168.116.157/在这里插入图片描述

http://192.168.116.157/

在这里插入图片描述

三、JVM 虚拟机常识

1 什么是java虚拟机

所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的VisualBox、VMware就属于系统虚拟机。他们完全是对物理计算机的仿真。提供了一个可以运行完整操作系统的软件平台。
程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。

2 java 如何做到跨平台

同一个JAVA程序,通过JAVA虚拟机(JVM)运行于各大主流操作系统平台
比如Windows、CentOS、Ubuntu等。程序以虚拟机为中介,来实现跨平台.

3 虚拟机堆内存结构(基础认识)

我们要对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(本地方法栈)。

4、常用虚拟机参数

JVM 虚拟机提供了三种类型参数

1、标准参数

标准参数中包括功能和输出的参数都是很稳定的,很可能在将来的JVM版本中不会改变。你可以用 java 命令(或者是用 java -help)检索出所有标准参数。

2、X 类型参数

非标准化的参数,在将来的版本中可能会改变。所有的这类参数都以 -X 开始。

3、XX 类型参数

在实际情况中 X 参数和 XX 参数并没有什么不同。X 参数的功能是十分稳定的。
用一句话来说明 XX 参数的语法。所有的 XX 参数都以"-XX:"开始,但是随后的语法不同,取决于参数的类型:
1)对于布尔类型的参数,我们有"+"或"-",然后才设置 JVM 选项的实际名称。
   例如,-XX:+ 用于激活选项,而 -XX:- 用于注销选项。
   Example:
   开启GC日志的参数: -XX:+PrintGC
2) 对于需要非布尔值的参数,如 string 或者 integer,我们先写参数的名称,后面加上"=",最后赋值。

4、常用的JVM参数

1、配置JAVA虚拟机的堆空间
-Xms:初始堆大小
-Xmx:最大堆大小
实际生产环境中, 我们通常将初始化堆(-Xms) 和 最大堆(-Xmx) 设置为一样大。以避免程序频繁的申请堆空间。设置为物理内存的一半.
[root@java-tomcat1 bin]# vim catalina.sh   添加
JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx1024m"
2、开启GC日志

跟踪JAVA虚拟机的垃圾回收

GC日志:jvm垃圾回收,记录jvm的运行状态,oom内存溢出的报错信息等。

  • %t 将会被替代为时间字符串,格式为: YYYY-MM-DD_HH-MM-SS

开启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

5、JVM 运维实用排障工具

1、jps

用来查看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

2、jstack

jstack用于打印出给定的java进程ID或远程调试服务的Java堆栈信息。此信息通常在运维的过程中被保存起来(保存故障现场),以供 RD (开发人员)们去分析故障。
常用参数如下:

jstack <pid>
jstack [-l] <pid> //长列表. 打印关于锁的附加信息
jstack [-F] <pid> //当’jstack [-l] pid’没有响应的时候强制打印栈信息

[root@localhost ~]# jstack -F 119300  > /tmp/jstack.log
#输出重定向,一般把这个东西给开发人员就好了~

6、Tomcat安全优化

1、降权启动(强制)

类别 配置内容及说明 标准配置 备注
降权启动 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

7、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

使用较为广泛

8、设置 JVM 缓存

在主机名解析为 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");

9、设置dns缓存

方式一:在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");

猜你喜欢

转载自blog.csdn.net/Houaki/article/details/111819610