1、总结 tomcat实现多虚拟机
1、修改配置文件
[root@slave conf]# pwd
/usr/local/tomcat/conf
[root@slave conf]# vim server.xml
</Host>
#添加了以下行
<Host name="node1.wang.org" appBase="/data/webapps1/" unpackWARs="true"
autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="node1_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
<Host name="node2.wang.org" appBase="/data/webapps2/" unpackWARs="true"
autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="node2_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
2、准备数据
[root@slave conf]# mkdir -pv /data/webapps{1,2}/ROOT
mkdir: created directory '/data/webapps1'
mkdir: created directory '/data/webapps1/ROOT'
mkdir: created directory '/data/webapps2'
mkdir: created directory '/data/webapps2/ROOT'
[root@slave conf]# vim /data/webapps1/ROOT/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsp例子</title>
</head>
<body>
后面的内容是服务器端动态生成字符串,最后拼接在一起
<br>
<%=request.getRequestURL()%>
</body>
</html>
[root@slave conf]# vim /data/webapps2/ROOT/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsp例子</title>
</head>
<body>
后面的内容是服务器端动态生成字符串,最后拼接在一起
<br>
<%=request.getRequestURL()%>
</body>
</html>
3、设置权限
[root@slave conf]# chown -R tomcat.tomcat /data/webapps{1,2}/
4、测试
添加名称解析
[root@10 ~]# vim /etc/hosts
10.0.0.159 node1.wang.org node2.wang.org
[root@10 ~]# curl http://node1.wang.org:8080/
[root@10 ~]# curl http://node2.wang.org:8080/
2、总结 tomcat定制访问日志格式和反向代理tomcat
2.1 定制访问日志格式
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
2.2 反向代理
#从yum源安装nginx
#yum install nginx -y
#vim /etc/nginx/nginx.conf
#全部反向代理测试
location / {
# proxy_pass http://127.0.0.1:8080; # 不管什么请求,都会访问后面的localhost虚拟主机
proxy_pass http://node1.wang.org:8080; # 此项将用户访问全部请求转发到node1的虚拟主
机上
#proxy_pass http://node2.wang.org:8080; #此项将用户访问全部请求转发到node2的虚拟主
机上
#proxy_set_header Host $http_host; #转发主机头至后端服务器
#以上两项都需要修改nginx服务器的/etc/hosts,实现node1.wang.org和node2.wang.org到IP的
解析
}
#nginx -t
#systemctl restart nginx
#说明: proxy_pass http://FQDN/ 中的FQDN 决定转发至后端哪个虚拟主机,而与用户请求的URL无关
#如果转到后端的哪个服务器由用户请求决定,可以向后端服务转发请求的主机头实现,示例:
proxy_set_header Host $http_host;
3、完成 tomcat实现MSM集群
环境准备:
-
时间同步,确保NTP或Chrony服务正常运行
-
防火墙规则
IP 主机名 服务 10.0.0.156 proxy.wang.org 调度器 Nginx、HTTPD 10.0.0.157 t1.wang.org tomcat1 JDK8、Tomcat8 10.0.0.158 t2.wang.org tomcat2 JDK8、Tomcat8 3.1 在proxy 主机设置httpd (或nginx)实现后端tomcat主机轮询
[root@proxy ~]# vim /etc/httpd/conf.d/tomcat.conf <Proxy balancer://tomcat-server> BalancerMember http://t1.wang.org:8080 loadfactor=1 BalancerMember http://t2.wang.org:8080 loadfactor=1 </Proxy> <VirtualHost *:80> ServerName proxy.wang.org ProxyRequests Off ProxyVia On ProxyPreserveHost On ProxyPass / balancer://tomcat-server/ ProxyPassReverse / balancer://tomcat-server/ </VirtualHost> [root@proxy ~]# systemctl restart httpd
3.2 在所有后端tomcat主机上修改conf/server.xml
3.2.1 修改1主机的 conf/server.xml
[root@t1 ~]#vim /usr/local/tomcat/conf/server.xml <Host name="t1.wang.org" appBase="/data/webapps" autoDeploy="true" > <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="10.0.0.157" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> </Host> root@t1:~# systemctl status tomcat ● tomcat.service - Tomcat Loaded: loaded (/lib/systemd/system/tomcat.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2024-07-11 12:32:39 UTC; 2s ago Process: 48652 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS) Main PID: 48660 (java) Tasks: 15 (limit: 2177) Memory: 47.7M CPU: 4.080s CGroup: /system.slice/tomcat.service └─48660 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/l> Jul 11 12:32:39 t1 systemd[1]: Starting Tomcat... Jul 11 12:32:39 t1 startup.sh[48652]: Tomcat started. Jul 11 12:32:39 t1 systemd[1]: Started Tomcat.
3.2.2 修改 t2 主机的 conf/server.xml
root@t2:~# vim /usr/local/tomcat/conf/server.xml <Host name="t2.wang.org" appBase="/data/webapps" autoDeploy="true" > <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="10.0.0.158" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> </Host> root@t2:~# systemctl restart tomcat.service
3.2.3 修改t主机的应用目录下的WEB-INF/web.xml文件
root@t1:/usr/local# mkdir -p /data/webapps/ROOT/ root@t1:/usr/local# cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/webapps/ROOT/ root@t1:~# vim /data/webapps/ROOT/WEB-INF/web.xml </description> <distributable/> #添加此行 </web-app> root@t1:~# systemctl restart tomcat
3.2.4 修改t2主机的应用目录下的WEB-INF/web.xm文件
root@t2:~# mkdir /data/webapps/ROOT/ -p root@t2:~# cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/webapps/ROOT/ root@t2:~# vim /data/webapps/ROOT/WEB-INF/web.xml </description> <distributable/> #倒数第二行添加此行 </web-app> root@t2:~# ll /data/webapps/ROOT/WEB-INF/ total 12 drwxr-x--- 2 tomcat tomcat 4096 Jul 11 12:52 ./ drwxr-xr-x 3 root root 4096 Jul 11 12:52 ../ -rw-r----- 1 tomcat tomcat 1243 Jul 11 12:52 web.xml root@t2:~# systemctl restart tomcat
4、总结 JVM垃圾回收算法和分代
4.1 标记-清除Mark-Sweep
分垃圾标记阶段和内存释放两个阶段。
-
标记阶段,找到所有可访问对象打个标记。清理阶段,遍历整个堆
-
对未标记对象(即不再使用的对象)逐一进行清理。
特点:
优点:算法简单
缺点:标记-清除最大的问题会造成内存碎片,但是不浪费空间,效率较高(如果对象较多时,逐一删除效率也
会受到影响)
4.2 标记-压缩Mark-Compact
分垃圾标记阶段和内存整理两个阶段。
- 标记阶段,找到所有可访问对象打个标记。
- 内存清理阶段时,整理时将对象向内存一端移动,整理后存活对象连续的集中在内存一端。
特点:
标记-压缩算法好处是整理后内存空间连续分配,有大段的连续内存可分配,没有内存碎片。
缺点是内存整理过程有消耗,效率相对低下
4.3 复制Copying
先将可用内存分为大小相同两块区域A和B,每次只用其中一块,比如A。当A用完后,则将A中存活的对象复制到B。复制到B的时候连续的使用内存,最后将A一次性清除干净。
特点
好处是没有碎片,复制过程中保证对象使用连续空间,且一次性清除所有垃圾,所以即使对象很多,收回效率也很高
缺点是比较浪费内存,只能使用原来一半内存,因为内存对半划分了,复制过程毕竟也是有代价。
4.4 堆内存分代
将heap内存空间分为三个不同类别:年轻代、老年代、持久代
Heap堆内存分为
年轻代Young:Young Generation
- 伊甸园区eden: 只有一个,刚刚创建的对象
- 幸存(存活)区Servivor Space:有2个幸存区,一个是from区,一个是to区。大小相等、地位相同、可互换。
from 指的是本次复制数据的源区
to 指的是本次复制数据的目标区
老年代Tenured:Old Generation, 长时间存活的对象
4.4.1 年轻代回收 Minor GC
-
起始时,所有新建对象(特大对象直接进入老年代)都出生在eden,当eden满了,启动GC。这个称为Young GC 或者 Minor GC。
-
先标记eden存活对象,然后将存活对象复制到s0(假设本次是s0,也可以是s1,它们可以调换),eden剩余所有空间都清空。GC完成。
-
继续新建对象,当eden再次满了,启动GC。
-
先同时标记eden和s0中存活对象,然后将存活对象复制到s1。将eden和s0清空,此次GC完成
-
继续新建对象,当eden满了,启动GC。
-
先标记eden和s1中存活对象,然后将存活对象复制到s0。将eden和s1清空,此次GC完成以后就重复上面的步骤。
4.4.2 老年代回收Major GC
进入老年代的数据较少,所以老年代区被占满的速度较慢,所以垃圾回收也不频繁。
如果老年代也满了,会触发老年代GC,称为Old GC或者 Major GC。
由于老年代对象一般来说存活次数较长,所以较常采用标记-压缩算法。
当老年代满时,会触发 Full GC,即对所有"代"的内存进行垃圾回收
Minor GC比较频繁,Major GC较少。但一般Major GC时,由于老年代对象也可以引用新生代对象,所
以先进行一次Minor GC,然后在Major GC会提高效率。可以认为回收老年代的时候完成了一次Full GC。
所以可以认为 MajorGC = FullGC
5、总结memcache使用,安装和MSM原理
5.1 memcatched 常见选项
-u username memcached运行的用户身份,必须普通用户
-p 绑定的端口,默认11211
-m num 最大内存,单位MB,默认64MB
-c num 最大连接数,缺省1024
-d 守护进程方式运行
-f 增长因子Growth Factor,默认1.25
-v 详细信息,-vv能看到详细信息
-M 使用内存直到耗尽,不许LRU
-U 设置UDP监听端口,0表示禁用UDP
5.2 五种基本 memcached 命令执行最简单的操作
root@t1:~/memcached-1.6.20# telnet localhost 11211
#加
add mykey 1 60 4
test
STORED
#查
get mykey
VALUE mykey 1 4
test
END
#改
set mykey 1 60 5
test1
STORED
get mykey
VALUE mykey 1 5
test1
END
#删除
delete mykey
DELETED
get mykey
范例: 非交互式取信息
6.6.3 Python 语言连接 memcached
6.6.3.1 范例: python3 测试代码
6.6.3.2 范例: Python2 测试代码
END
#清空
flush_all
OK
get mykey
END
quit
5.3 编译安装
root@t1:~# apt update && apt install gcc make libevent-dev -y
root@t1:~# tar xf memcached-1.6.20.tar.gz
root@t1:~# cd memcached-1.6.20/
root@t1:~/memcached-1.6.20# ./configure --prefix=/apps/memcached
root@t1:~/memcached-1.6.20# make && make install
root@t1:~/memcached-1.6.20# tree /apps/memcached/
/apps/memcached/
├── bin
│ └── memcached
├── include
│ └── memcached
│ ├── protocol_binary.h
│ └── xxhash.h
└── share
└── man
└── man1
└── memcached.1
6 directories, 4 files
root@t1:~/memcached-1.6.20# ln -s /apps/memcached/bin/memcached /usr/local/bin
root@t1:~/memcached-1.6.20# memcached
can't run as root without the -u switch
root@t1:~/memcached-1.6.20# useradd -r -s /sbin/nologin memcached
root@t1:~/memcached-1.6.20# memcached -u memcached -d -f 2 -vv
root@t1:~/memcached-1.6.20# slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 192 perslab 5461
slab class 3: chunk size 384 perslab 2730
slab class 4: chunk size 768 perslab 1365
slab class 5: chunk size 1536 perslab 682
slab class 6: chunk size 3072 perslab 341
slab class 7: chunk size 6144 perslab 170
slab class 8: chunk size 12288 perslab 85
slab class 9: chunk size 24576 perslab 42
slab class 10: chunk size 49152 perslab 21
slab class 11: chunk size 98304 perslab 10
slab class 12: chunk size 196608 perslab 5
slab class 13: chunk size 524288 perslab 2
<22 server listening (auto-negotiate)
root@t1:~/memcached-1.6.20# ss -ntl |grep 11211
LISTEN 0 1024 127.0.0.1:11211 0.0.0.0:*
LISTEN 0 1024 [::]:11211 [::]:*
5.4 MSM原理
MSM(memcached session manager)提供将Tomcat的session保持到memcached或Redis的程序,可以实现高可用。