Tomcat多实例集群架构 安全优化和性能优化
Tomcat多实例
复制tomcat目录
#将tar解压出来的tomcat复制出两个实例来
cp -a /usr/local/apache-tomcat-8.0. /usr/local/tomcat1
cp -a /usr/local/apache-tomcat-8.0. /usr/local/tomcat2
修改多实例配置文件
#创建多实例的网页根目录
mkdir -p /data/www/www/ROOT
#修改多实例配置文件的以下三行
vim /usr/local/tomcat/conf/server.xml
<Server port="" shutdown="SHUTDOWN"> #管理端口及停止命令
<Connector port="" protocol="HTTP/1.1" #对外提供服务的端口
<Host name="localhost" appBase="webapps" #网站域名及网页根目录路径 第一个实例
<Server port="" shutdown="SHUTDOWN">
<Connector port="" protocol="HTTP/1.1"
<Host name="localhost" appBase="/data/www/www"
第二个实例
<Server port="" shutdown="SHUTDOWN">
<Connector port="" protocol="HTTP/1.1"
<Host name="localhost" appBase="/data/www/www"
启动多实例
/usr/local/tomcat1/bin/startup.sh
/usr/local/tomcat2/bin/startup.sh
Tomcat集群
使用nginx+Tomcat反向代理集群
Tomcat安全优化和性能优化
安全优化
- 降权启动
- telnet管理端口保护
- ajp连接端口保护
- 禁用管理端
(1)降权启动(同nginx优化部分的监牢模式)
降权的原则就是利用普通用户来启动Tomcat :
(1)将Tomcat程序目录拷贝到普通用户家目录下
(2)修改家目录下程序的配置文件(启动端口,检测端口等),并重新指定网页根目录路径。
(3)递归授权拷贝后的Tomcat程序的属主属组为普通用户。
(4)用su命令切换为普通用户,启动Tomcat进程
(5)此时Tomcat进程的权限为普通用户权限
(6)如果利用/etc/rc.local文件配置普通用户程序的开机启动,那么需要利用su -c临时切换身份启动。具体可参考linux基础教案里的用户管理部分
passwd wk #创建普通用户wk
cp -a /usr/local/apache-tomcat-8.0./ /home/wk/tomcat #复制tar解压的tomcat到wk的家目录
vim conf/server.xml #修改配置文件 改启动端口 监听端口 网页家目录位置
<Server port="" shutdown="SHUTDOWN">
<Connector port="" protocol="HTTP/1.1"
<Host name="localhost" appBase="/home/wk/tomcat/webapps"
chown -R wk:wk tomcat #修改权限
su wk #进入普通影虎
./tomcat/bin/startup.sh #启动tomcat
(2)telnet管理端口保护
cat /usr/local/tomcat/conf/server.xml
<Server port="" shutdown="SHUTDOWN"> #表示通过8005端口来接受SHUTDOWN,用来停止Tomcat进程。默认的方式是非常危险的。需要进行修改
Tomcat默认通过8005端口来接收SHUTDOWN这个字符串来关闭Tomcat进程,但这是非常危险的,因此需要修改端口号来防护。否则,通过telnet命令即可强行关闭Tomcat进程
#利用Telnet来关闭Tomcat进程
telnet 127.0.0.1 #通过telnet连接本地8005端口
[wk@wk ~]$ telnet 127.0.0.1
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
SHUTDOWN #输入大写shutdown关闭tomcat
Connection closed by foreign host.
(3)ajp连接端口保护
vim tomcat/conf/server.xml
<Connector port="" protocol="AJP/1.3" redirectPort="" /> #这是AJP协议打开的端口,我们并不需要开启这个端口,因此注释掉本行
<!--Connector port="" protocol="AJP/1.3" redirectPort="" /-->
(4)禁用管理端
Tomcat默认在安装完成后的网页目录里有很多多余的目录,删除所有不需要用到的目录,并清空ROOT网页默认根目录下的所有东西,规避可能的代码漏洞
cd tomcat/webapps/
mkdir /tmp/webapps.b
mv * /tmp/webapps.b
mkdir ROOT
性能优化
1 屏蔽DNS查询 enableLookups="false"
DNS查询非常消耗时间,如果开启会影响Tomcat性能,因此关闭。
#默认没有,需添加配置文件如下代码段,在Connector标签位置。表示禁止DNS查询
<Connector port="" protocol="HTTP/1.1"
connectionTimeout="" enableLookups="false" acceptCount=""
redirectPort="" />
2 jvm调优
Tomcat最吃内存,只要内存足够,这只猫就跑的很快。
如果系统资源有限,那就需要进行调优,提高资源使用率。
#优化catalina.sh初始化脚本。在catalina.sh初始化脚本中添加以下代码:
#catalina.sh的路径为:/usr/local/tomcat/bin/catalina.sh
#此行优化代码需要加在脚本的最开始,声明位置。不要放在后边
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m"
#代码说明:
server:一定要作为第一个参数,在多个CPU时性能佳
-Xms:初始堆内存Heap大小,使用的最小内存,cpu性能高时此值应设的大一些
-Xmx:初始堆内存heap最大值,使用的最大内存
上面两个值是分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半。
-XX:PermSize:设定内存的永久保存区域
-XX:MaxPermSize:设定最大内存的永久保存区域
-XX:MaxNewSize:
-Xss 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512k.
+XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。
-Xss:每个线程的Stack大小
-verbose:gc 现实垃圾收集信息
-Xloggc:gc.log 指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一
-XX:+UseParNewGC :缩短minor收集的时间
-XX:+UseConcMarkSweepGC :缩短major收集的时间
JVM的调优比较复杂,如果想要更详细的理解JVM如何调优,那么请参考网友文章:http://www.cnblogs.com/xingzc/p/5756119.html
企业案例:Linux下java/http进程高解决案例
生产环境下某台tomcat7服务器,在刚发布的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高。诸如此类问题,请排查!
问题分析:
(1)程序属于CPU密集型,和开发沟通过,排除此类情况
(2)程序代码有问题,出现死循环,可能性极大
问题解决:
(1)开发那边无法排查代码某个模块有问题,从日志上也无法分析得出
(2)我们可以尝试通过jstack命令来精确定位出现错误的代码段,从而拿给开发排查
首先查找进程高的PID号(先找到是哪个PID号的进程导致的)
top -H
查看这个进程所有系统调用(再找到是哪个PID号的线程导致的)
strace -p 进程的PID
如果是Web应用,可以继续打印该线程的堆栈信息(找出有问题的代码块)
printf "%x\n" 线程的PID --->#将有问题的线程的PID号转换成16进制格式
jstack 进程的PID | grep 线程PID号的十六进制格式 -A #过滤出有问题的线程的堆栈信息,找出问题代码块
实际操作演示:
pgrep -l java
java #java进程及对应PID号
java
java
strace -p #查看PID号为2031的java进程的所有线程调用情况
Process attached - interrupt to quit
futex(0x7f4cdd0e79d0, FUTEX_WAIT, , NULL #只有一个线程,线程的PID号为2032
^C <unfinished ...>
Process detached
printf "%x\n" #将线程的PID号2032转换成十六进制格式
7f0
jstack | grep 7f0 -A #追踪进称号为2031的进程的所有线程调用,从里面过滤出16进制为7f0的线程的代码调用情况
"main" # prio= os_prio= tid=0x00007f4cd4008800 nid=0x7f0 runnable [0x00007f4cdd0e5000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:) #圆括号里显示的是(代码类名:具体调用的代码行号)
at java.net.ServerSocket.implAccept(ServerSocket.java:)
at java.net.ServerSocket.accept(ServerSocket.java:)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:)
at org.apache.catalina.startup.Catalina.await(Catalina.java:)
at org.apache.catalina.startup.Catalina.start(Catalina.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:)
"VM Thread" os_prio= tid=0x00007f4cd406d000 nid=0x7f1 runnable
"VM Periodic Task Thread" os_prio= tid=0x00007f4cd40b8800 nid=0x7f8 waiting on condition
JNI global references:
Tomcat多实例集群架构 安全优化和性能优化的更多相关文章
- 万级K8s集群背后etcd稳定性及性能优化实践
背景与挑战 随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...
- 万级K8s集群背后 etcd 稳定性及性能优化实践
1背景与挑战随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...
- 19.Tomcat集群架构
1.Nginx+Tomcat集群架构介绍 2.Nginx+Tomcat集群架构实战 [root@lb01 conf.d]# cat proxy_zrlog.cheng.com.conf upstrea ...
- Galera Cluster——一种新型的高一致性MySQL集群架构
原文链接:https://www.sohu.com/a/147032902_505779,最近被分配定位mysql的问题,学习下. 1. 何谓Galera Cluster 何谓Galera Clust ...
- Memcached 集群架构方面的问题 [z]
集群架构方面的问题 memcached是怎么工作的? Memcached的神奇来自两阶段哈希(two-stage hash).Memcached就像一个巨大的.存储了很多<key,v ...
- Memcached集群架构方面的问题(转)
add by zhj: 这是一个系列中的第二篇,该系列有四篇,英文原文没找到,译文见:http://blog.csdn.net/jarfield/article/details/4336035 ,附上 ...
- Memcached 集群架构问题归纳
集群架构方面的问题o memcached是怎么工作的?o memcached最大的优势是什么?o memcached和MySQL的query cache相比,有什么优缺点?o memcached和服务 ...
- Memcached 集群架构方面的问题
* 集群架构方面的问题 o memcached是怎么工作的? o memcached最大的优势是什么? o memcached和MySQL的query cache相比,有什么优缺点? o memca ...
- PB级数据实时查询,滴滴Elasticsearch多集群架构实践
PB级数据实时查询,滴滴Elasticsearch多集群架构实践 mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达 点 ...
随机推荐
- 【python】写csv文件时遇到的错误
1.错误 在许多文件中,写入csv文件时都加"wb",w指写入,b指二进制 如: csvwrite=csv.writer(open("output.csv",& ...
- JavaSpring【七、AspectJ】
AspectJ 概念 @AspectJ类似纯Java注解的普通Java类 Spring可以使用AspectJ来作为切入点 AOP在运行时仍是纯SpringAOP,对AspectJ无依赖 配置: 对@A ...
- MinGW-W64 编译 LLVM 与 Clang
原文: http://blog.csdn.net/happywjh666/article/details/51415723 编译环境: 系统 --win10 64位 gcc -- version 5. ...
- 对称加密实现重要日志上报Openresty接口服务
记录后端接收日志的流程: 由于记录的是广告数据,单次计费数据都会上报,全国内约10几万终端上报. 终端上报:Android电视端Apk上报 接收终端:Openresty(Nginx+lua)利用ngi ...
- ECMAScript 6 入门——ES6 声明变量的六种方法
ES6 声明变量的六种方法 ES5 只有两种声明变量的方法:var命令和function命令.ES6 除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和cla ...
- React给state赋值的两种写法
如果你看过React的官方文档,就会对怎么给局部state赋值有一定的了解.如下代码: class Test extends React.Component { constructor(props) ...
- debug:The key "" is not recognized and ignored.
今天写代码时候发现chrome浏览器有一个警告The key "" is not recognized and ignored.既然发现了就处理一下吧,于是就有了这篇小文章. 查阅 ...
- HTML嵌入多媒体对象
[问题描述]如何在HTML中嵌入pdf.word,音频(如mp3),视频(如mp4),flash呢? [分析] 1 嵌入pdf (1) 利用object <object classid=&quo ...
- 长春理工大学第十四届程序设计竞赛D Capture The Flag——哈希&&打表
题目 链接 题意:给定一个字符串 $s$,求不同于 $s$ 的字符串 $t$,使得 $Hash(s) = Hash(t)$,其中 $\displaystyle Hash(s) = \sum_0^{le ...
- 【ArcCatalog】
1.添加文件夹链接文件夹链接的添加删除操作 2.新建/删除数据库(1)新建个人地理数据库(.mdb)(2)新建文本地理数据库(.gdb) 3.新建/删除要素数据集(1)要素数据集属性: 常规--XY坐 ...