十一週
一、總結 tomcat實現多虛擬機器
#準備資料目錄
[root@tomcat ~]#mkdir /data/website{1,2,3}/ROOT -pv
[root@tomcat ~]#vim /data/website1/ROOT/index.html
www.a.com
/data/website1/ROOT/index.html
[root@tomcat ~]#vim /data/website2/ROOT/index.html
www.b.com
/data/website2/ROOT/index.html
[root@tomcat ~]#vim /data/website3/ROOT/index.html
www.c.com
/data/website3/ROOT/index.html
#設定許可權
[root@tomcat ~]#chown -R tomcat.tomcat /data/website{1,2,3}/
#修改配置
[root@tomcat ~]#cd /usr/local/tomcat/
[root@tomcat tomcat]#vim conf/server.xml
</Host>
<Host name="www.a.com" appBase="/data/website1/"
unpackWARs="true" autoDeploy="true">
</Host>
<Host name="www.b.com" appBase="/data/website2/"
unpackWARs="true" autoDeploy="true">
</Host>
<Host name="www.c.com" appBase="/data/website3/"
unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
</Service>
</Server>
#重啟Tomcat服務
[root@tomcat tomcat]#systemctl restart tomcat.service
#測試訪問
[root@client ~]#vim /etc/hosts
10.0.0.7 www.a.com www.b.com www.c.com
[root@client ~]#curl www.a.com:8080
www.a.com
/data/website1/ROOT/index.html
[root@client ~]#curl www.b.com:8080
www.b.com
/data/website2/ROOT/index.html
[root@client ~]#curl www.c.com:8080
www.c.com
/data/website3/ROOT/index.html
二、總結 tomcat定製訪問日誌格式和反向代理tomcat
日誌格式: https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#Access_Logging
%a - Remote IP address
%A - Local IP address
%b - Bytes sent, excluding HTTP headers, or '-' if zero
%B - Bytes sent, excluding HTTP headers
%h - Remote host name (or IP address if enableLookups for the connector is
false)
%H - Request protocol
%l - Remote logical username from identd (always returns '-')
%m - Request method (GET, POST, etc.)
%p - Local port on which this request was received. See also %{xxx}p below.
%q - Query string (prepended with a '?' if it exists)
%r - First line of the request (method and request URI)
%s - HTTP status code of the response
%S - User session ID
%t - Date and time, in Common Log Format
%u - Remote user that was authenticated (if any), else '-'
%U - Requested URL path
%v - Local server name
%D - Time taken to process the request in millis. Note: In httpd %D is
microseconds. Behaviour will be aligned to httpd in Tomcat 10 onwards.
%T - Time taken to process the request, in seconds. Note: This value has
millisecond resolution whereas in httpd it has second resolution. Behaviour will
be align to httpd in Tomcat 10 onwards.
%F - Time taken to commit the response, in millis
%I - Current request thread name (can compare later with stacktraces)
%X - Connection status when response is completed:
X = Connection aborted before the response completed.
+ = Connection may be kept alive after the response is sent.
- = Connection will be closed after the response is sent.
There is also support to write information incoming or outgoing headers, cookies,
session or request attributes and special timestamp formats. It is modeled after
the Apache HTTP Server log configuration syntax. Each of them can be used
multiple times with different xxx keys:
%{xxx}i write value of incoming header with name xxx
%{xxx}o write value of outgoing header with name xxx
%{xxx}c write value of cookie with name xxx
%{xxx}r write value of ServletRequest attribute with name xxx
%{xxx}s write value of HttpSession attribute with name xxx
%{xxx}p write local (server) port (xxx==local) or remote (client) port
(xxx=remote)
%{xxx}t write timestamp at the end of the request formatted using the enhanced
SimpleDateFormat pattern xxx
#檢視訪問日誌格式
[root@centos8 ~]#tail /usr/local/tomcat/conf/server.xml
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" /> #說明: "在html
中表示雙引號"符號
</Host>
</Engine>
</Service>
</Server>
#檢視訪問日誌
[root@centos8 ~]#tail /usr/local/tomcat/logs/localhost_access_log.2020-07-14.txt
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET / HTTP/1.1" 200 11215
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /tomcat.css HTTP/1.1" 200 5581
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /tomcat.png HTTP/1.1" 200 5103
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /bg-nav.png HTTP/1.1" 200 1401
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /bg-upper.png HTTP/1.1" 200 3103
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /asf-logo-wide.svg HTTP/1.1" 200
27235
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /bg-middle.png HTTP/1.1" 200 1918
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /bg-button.png HTTP/1.1" 200 713
10.0.0.1 - - [14/Jul/2020:09:08:46 +0800] "GET /favicon.ico HTTP/1.1" 200 21630
編輯此部分修改日誌格式
pattern="%h %l %u %t "%r" %s %b"
反向代理tomcat
透過nginx在HTTP塊中的upstream模組實現反向代理 並用ip_hash 或者cookie實現session保持
透過前端的nginx主機訪問後端的兩臺tomcat主機
#修改/etc/hosts檔案,實現名稱解析
[root@centos8 ~]#vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
centos8.localdomain
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.0.100 node1.wang.org node2.wang.org
#在http塊中加以下內容
#注意名稱不要用下劃線
upstream tomcat-server {
#ip_hash; # 只根據客戶端IP的前三位十進位制數字
#hash $remote_addr consistent; # 根據客戶端IP的全部位
#hash $cookie_jsessionid consistent; # 先禁用看看輪詢,之後開啟開黏性,JSESSIONID要小寫
server t1.wang.org:8080;
server t2.wang.org:8080;
}
server {
location ~* \.(jsp|do)$ {
proxy_pass http://tomcat-server;
#proxy_set_header Host $http_host; #轉發主機頭至後端伺服器
}
}
測試 http://proxy.wang.org/index.jsp,可以看到輪詢排程效果,每次重新整理後端主機和SessionID都會變化
三、完成 tomcat實現MSM叢集
MSM(memcached session manager)提供將Tomcat的session保持到memcached或Redis的程式,可以實現高可用
sticky 模式即前端tomcat和後端memcached有關聯(粘性)關係
Tomcat-1 (t1) will primarily store it's sessions in memcached-2 (m2) which is
running on another machine (m2 is a regular node for t1). Only if m2 is not
available, t1 will store it's sessions in memcached-1 (m1, m1 is the failoverNode
for t1). With this configuration, sessions won't be lost when machine 1 (serving
t1 and m1) crashes. The following really nice ASCII art shows this setup.
Tomcat-1(t1)主要將其會話儲存在另一臺計算機上執行的memcached-2(m2)中(m2是t1的常規節
點)。 僅當m2不可用時,t1才會將其會話儲存在memcached-1中(m1,m1是t1的failoverNode)。 使
用此配置,當計算機1(服務於t1和m1)崩潰時,會話不會丟失。 以下非常好的ASCII藝術顯示了此設定。
<t1> <t2>
. \ / .
. X .
. / \ .
<m1> <m2>
t1和m1部署可以在一臺主機上,t2和m2部署也可以在同一臺。
當新使用者發請求到Tomcat1時, Tomcat1生成session返回給使用者的同時,也會同時發給memcached2備
份。即Tomcat1 session為主session,memcached2 session為備用session,使用memcached相當
於備份了一份Session
如果Tomcat1發現memcached2 失敗,無法備份Session到memcached2,則將Sessoin備份存放在
memcached1中
配置:
修改tomcat配置
修改 $CATALINA_HOME/conf/context.xml
特別注意,t1配置中為failoverNodes="n1", t2配置為failoverNodes="n2"
配置中追加如下
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:10.0.0.101:11211,n2:10.0.0.102:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFac
tory"
/>
配置成功,可以在logs/catalina.out中看到
12-APR-2020 16:24:08.975 INFO [t1.wang.org-startStop-1]
de.javakaffee.web.msm.MemcachedSessionService.startInternal --------
- finished initialization:
- sticky: true
- operation timeout: 1000
- node ids: [n2]
- failover node ids: [n1]
- storage key prefix: null
- locking mode: null (expiration: 5s)
測試msm的python指令碼
[root@t1 ~]#dnf -y install python3 python3-memcached
#或者下面方式也可以安裝
[root@t1 ~]#dnf -y install python3
[root@t1 ~]#pip3 install python-memcached
[root@t1 ~]#chmod +x showmemcached.py
#指令碼內容
[root@centos8 ~]#cat showmemcached.py
#!/usr/bin/python3
import memcache
mc = memcache.Client(['10.0.0.101:11211'], debug=True)
stats = mc.get_stats()[0]
print(stats)
for k,v in stats[1].items():
print(k, v)
print('-' * 30)
# 檢視全部key
print(mc.get_stats('items')) # stats items 返回 items:5:number 1
print('-' * 30)
print(mc.get_stats('cachedump 5 0')) # stats cachedump 5 0 # 5和上面的items返回的值
有關;0表示全部
透過指令碼驗證session內容和網頁驗證,可以看到瀏覽器端被排程到不同Tomcat上,但是都獲得了同樣的SessionID。
Nginx 充當 Proxy負責將訪問排程到後端tomcat,由memcached儲存session資訊,sticky模式。
nginx配置檔案:
[root@proxy ~]#cat /etc/nginx/nginx.conf
http {
......
upstream tomcat-server {
#ip_hash;
server t1.wang.org:8080;
server t2.wang.org:8080;
}
server {
......
location / {
}
location ~* \.(jsp|do)$ {
proxy_pass http://tomcat-server;
#proxy_set_header Host $http_host; #轉發主機頭至後端伺服器
}
本地主機解析
[root@proxy ~]#cat /etc/hosts
10.0.0.100 proxy.wang.org proxy
10.0.0.101 t1.wang.org t1
10.0.0.102 t2.wang.org t2
安裝memcached:
[root@t1 ~]#cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
#註釋下面行
#OPTIONS="-l 127.0.0.1,::1"
配置中追加:
conf/server.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:10.0.0.101:11211,n2:10.0.0.102:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFac
tory"
/>
#將相關包傳到lib/目錄下,共10個檔案
asm-5.2.jar
kryo-3.0.3.jar
kryo-serializers-0.45.jar
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc8-2.3.2.jar
minlog-1.3.1.jar
msm-kryo-serializer-2.3.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
spymemcached-2.12.3.jar
[root@t1 tomcat]#cat /data/webapps/ROOT/index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<h1> tomcat website </h1>
<div>On <%=request.getServerName() %></div>
<div><%=request.getLocalAddr() + ":" + request.getLocalPort() %></div>
<div>SessionID = <span style="color:blue"><%=session.getId() %></span></div>
<%=new Date()%>
</body>
</html>
同樣方法配置tomcat2: 配置檔案稍有不同
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:10.0.0.101:11211,n2:10.0.0.102:11211"
failoverNodes="n2" #只修改此行,和t1不同,其它都一樣
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFact
tory"
/>
與之相對的Non-Sticky 模式
相當於session資訊都交付給memcached,本地不儲存session;
Tomcat session為中轉Session,對每一個SessionID隨機選中後端的memcached節點n1(或者n2)為主
session,而另一個memcached節點n2(或者是n1)為備session。產生的新的Session會傳送給主、備
memcached,並清除本地Session。
對應配置檔案修改如下:sticky值為false
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:10.0.0.101:11211,n2:10.0.0.102:11211"
sticky="false" #下面三行和sticky模式不同
sessionBackupAsync="false"
lockingMode="uriPattern:/path1|/path2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFact
ory"
/>
總結 JVM垃圾回收演算法和分代
垃圾收集方式
按工作模式不同:指的是GC執行緒和工作執行緒是否一起執行
獨佔垃圾回收器:只有GC在工作,STW 一直進行到回收完畢,工作執行緒才能繼續執行
併發垃圾回收器:讓GC執行緒垃圾回收某些階段可以和工作執行緒一起進行,如:標記階段並行,回收階段
仍然序列
按回收執行緒數:指的是GC執行緒是否序列或並行執行
序列垃圾回收器:一個GC執行緒完成回收工作
並行垃圾回收器:多個GC執行緒同時一起完成回收工作,充分利用CPU資源