第九周作业

[TOC]

一、nginx实现全栈SSL。要求http rewrite到https协议。

1.1、自签名证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@server ~]#cd /apps/nginx
[root@server nginx]#mkdir certs #创建存放证书路径
[root@server nginx]#cd certs/
[root@server certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.magedu.org.key -x509 -days 3650 -out www.magedu.org.crt
Country Name (2 letter code) [XX]:CN #国家
State or Province Name (full name) []:beijing #省
Locality Name (eg, city) [Default City]:beijing #市
Organization Name (eg, company) [Default Company Ltd]:magedu #公司
Organizational Unit Name (eg, section) []:it #部门
Common Name (eg, your name or your server's hostname) []:*.magedu.org #网站
Email Address []:
#*.magedu.org使用的是泛域名,也可以指定具体网站
[root@server certs]#ls
www.magedu.org.crt www.magedu.org.key

#查看证书文件
[root@server certs]#openssl x509 -in www.magedu.org.crt -noout -text
#或者下载到windows上查看
[root@server certs]#sz www.magedu.org.crt

image-20221129100238035

1.2、https配置

nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数

ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编

译安装的nginx需要指定编译参数–with-http_ssl_module开启

1
https://nginx.org/en/docs/http/ngx_http_ssl_module.html

配置参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ssl on | off;   
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
listen 443 ssl;

ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存
  off: #关闭缓存
none:  #通知客户端支持ssl session cache,但实际不支持
builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称

ssl_session_timeout time;
#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#查看编译安装时是否安装此模块,已安装
[root@server certs]#nginx -V
nginx version: nginx/1.20.2
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-10) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/usr/local/src/echo-nginx-module-0.63
[root@server certs]#cd ..
[root@server nginx]#cd conf.d
[root@server conf.d]#vim pc.conf
server {
......
listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.magedu.org.crt;
ssl_certificate_key /apps/nginx/certs/www.magedu.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
......
}
:wq
[root@server conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@server conf.d]#nginx -s reload
[root@server conf.d]#ss -ntl #443端口已打开
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 0.0.0.0:443 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*

image-20221129102221700

1.3、实现HSTS

官方文档:

1
https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/

注意:配置rewrite才能实现http跳转到https

Nginx服务器利用 ngx_http_rewrite_module 模块(属于标准模块,系统默认安装)解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,另外还可以在一定程度上提高网站的安全性。

rewrite官方文档:

1
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
1.3.1、利用return实现http跳转到https

return适用于server、location、if

1.3.1.1、用两个虚拟主机分开实现跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@server conf.d]#vim pc.conf
server {
listen 80;
server_name www.magedu.org;
root /data/nginx/html/pc;
return 302 https://www.magedu.org/;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.magedu.org.crt;
ssl_certificate_key /apps/nginx/certs/www.magedu.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.magedu.org;
root /data/nginx/html/pc;
.....
}
:wq
[root@server conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@server conf.d]#nginx -s reload

image-20221129113103417

1.3.1.2、用一个虚拟主机实现跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@server conf.d]#vim pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.magedu.org.crt;
ssl_certificate_key /apps/nginx/certs/www.magedu.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.magedu.org;
root /data/nginx/html/pc;
if($scheme = http) {
return 302 https://www.magedu.org/;
}
:wq
[root@server conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@server conf.d]#nginx -s reload

image-20221129113829880

1.3.2、利用rewrite实现http跳转到https

rewrite 格式

1
2
3
Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if

flag 说明

1
2
3
4
5
6
7
8
9
10
11
12
13
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;
使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后
的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,
不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
1.3.2.1、用两个虚拟主机分开实现跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@server conf.d]#vim pc.conf
server {
listen 80;
server_name www.magedu.org;
root /data/nginx/html/pc;
rewrite ^(.*)$ https://$host$1 redirect;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.magedu.org.crt;
ssl_certificate_key /apps/nginx/certs/www.magedu.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.magedu.org;
root /data/nginx/html/pc;
.....
}
:wq
[root@server conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@server conf.d]#nginx -s reload

image-20221129121035588

1.3.1.2、用一个虚拟主机实现跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@server conf.d]#vim pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.magedu.org.crt;
ssl_certificate_key /apps/nginx/certs/www.magedu.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.magedu.org;
root /data/nginx/html/pc;
if ($scheme = http) {
rewrite ^(.*)$ https://$host$1 redirect;
} #针对全网站跳转
.....
}
:wq

#实现网站里面只有各别页面http转换为https
location /about {
alias /opt/pc/about;
if ($scheme = http) {
rewrite / https://$host/about redirect;
}
}

[root@server conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@server conf.d]#nginx -s reload

image-20221129122222689

二、nginx实现动静分离。

image-20221129152150302

2.1、架构组成

1
2
3
反向代理服务器:10.0.0.184   proxy
后端服务器:10.0.0.185 server01 存放静态资源
后端服务器:10.0.0.186 server02 存放动态资源

2.2、反向代理服务器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@proxy conf.d]#vim pc.conf
server {
listen 80;
server_name www.magedu.org;
access_log /apps/nginx/logs/access-json-www.magedu.org.log access_json;
root /data/nginx/html/pc;
location ~ \.(jpg|png|gif)$ {
proxy_pass http://10.0.0.185;
}
location /api {
proxy_pass http://10.0.0.186;
}
}
:wq
[root@proxy conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@proxy conf.d]#nginx -s reload

2.3、后端服务器配置

1
2
[root@server01 ~]#cd /apps/nginx/html
[root@server01 html]#wget -O 1.jpg "https://t7.baidu.com/it/u=4141604674,3317329080&fm=193&f=GIF" #下载图片并命名1.jpg

image-20221129155214696

1
2
3
4
5
6
[root@server02 ~]#cd /apps/nginx/html
[root@server02 html]#mkdir api
[root@server02 html]#cd api
[root@server02 api]#vim index.html
<h1> 10.0.0.186 </h1>
:wq

image-20221129155953866

三、nginx实现防盗链功能。

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标

记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗

链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

1
2
3
4
5
none:#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:#请求报文有referer首部,但无有效值,比如为空。
server_names:#referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string:#自定义指定字符串,但可使用*作通配符。示例: *.magedu.org www.magedu.*
regular expression:#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.magedu\.com

3.1、实现盗链

在一个web 站点盗链另一个站点的资源信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#在www.magedu.org站点盗取m.magedu.org的图片
[root@proxy ~]#cd /data/nginx/html/pc
[root@proxy pc]#vim daolian.html
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://m.magedu.org/1.jpg" >
</body>
</html>
:wq

#查看m.magedu.org的日志可以看见www.magedu.org的盗图
[root@proxy conf.d]#tail /apps/nginx/logs/access.log
10.0.0.1 - - [29/Nov/2022:16:30:07 +0800] "GET /1.jpg HTTP/1.1" 304 0 "http://www.magedu.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.56"

image-20221129162918630

image-20221129162949414

image-20221129163014899

3.2、实现防盗链

基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有

效实现防盗链功能

官方文档:

1
https://nginx.org/en/docs/http/ngx_http_referer_module.html

语法格式:

1
2
3
4
5
6
7
8
9
10
location   /images {
  root /data/nginx/html/pc;
  index index.html;
  valid_referers none blocked server_names
        *.example.com example.* www.example.org/galleries/
        ~\.google\.;
         
   if ($invalid_referer) {
    return 403;
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@proxy conf.d]#vim mobile.conf
server {
listen 80;
server_name m.magedu.org;
location / {
root /data/nginx/html/mobile;
} #添加下面几行
valid_referers none blocked server_names ~\.google\. ~\.baidu\. ~\.bing\. ~\.so\. ;
if ($invalid_referer) {
return 403 "Forbidden Access";
}
}
:wq
[root@proxy conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@proxy conf.d]#nginx -s reload

#查看m.magedu.org的日志可以看见403拒绝www.magedu.org的盗图
[root@proxy conf.d]#tail /apps/nginx/logs/access.log #出现403提示
10.0.0.1 - - [29/Nov/2022:16:49:52 +0800] "GET /1.jpg HTTP/1.1" 403 16 "http://www.magedu.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.56"

image-20221129165521812

四、解析nginx常见的负载均衡算法。

Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能

官方文档: https://nginx.org/en/docs/http/ngx_http_upstream_module.html

4.1、负载均衡五种算法

①轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。

②weight(轮询权值)

weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

③ip_hash

每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

④fair(第三方)

比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。

按后端服务器的响应时间来分配请求,响应时间短的优先分配。
⑤url_hash(第三方)

按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

1
2
3
4
5
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致性hash基于取模运算
#示例
hash $request_uri consistent; #基于用户请求的uri做hash
hash $cookie_sessionid  #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
1
2
3
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持
#hash $remote_addr 则是对全部32bit的IPv4进行hash计算
1
2
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC

五、基于LNMP完成搭建任意一种应用。

image-20221130154931353

5.1、准备数据库

1
2
3
4
5
6
7
8
9
10
11
[root@Rocky ~]#yum -y install mysql-server redis
[root@Rocky ~]#systemctl enable --now mysqld redis
[root@Rocky ~]#mysql
mysql> create database kodbox;
mysql> create user kodbox@'10.0.0.%' identified by '123456';
mysql> grant all on kodbox.* to kodbox@'10.0.0.%';

#修改redis配置文件
[root@Rocky ~]#vim /etc/redis.conf
bind 0.0.0.0 #将127.0.0.1改为0.0.0.0
[root@Rocky ~]#systemctl restart redis

5.2、nginx的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#nginx的配置
[root@proxy ~]#yum -y install nginx #前期已编译安装nginx了,不再执行此步
[root@proxy ~]#vim /apps/nginx/conf/nginx.conf
include /apps/nginx/conf.d/*.conf; #在倒数第二行添加此命令
[root@proxy ~]#cd /apps/nginx/conf.d
[root@proxy ~]#mkdir -p /data/nginx/kodbox #创建文件存放路径
[root@proxy conf.d]#vim kodbox.conf
server {
listen 80;
server_name kodbox.magedu.org;
root /data/nginx/kodbox; #文件存放路径
client_max_body_size 200M; #文件上传大小限制
index index.php;
location ~ \.php$ {
root /data/nginx/kodbox;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ ^/(ping|fpm_status)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
:wq
[root@proxy conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@proxy conf.d]#nginx -s reload

5.3、安装和配置php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#安装PHP相关软件包
[root@proxy ~]#yum -y install php-fpm php-json php-mysqlnd php-mbstring php-xml php-gd
[root@proxy ~]#vim /etc/php.ini
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 200M #由2改为200,调大上传限制
; http://php.net/post-max-size
post_max_size = 200M #由8改为200,调大上传限制
:wq
[root@proxy ~]#vim /etc/php-fpm.d/www.conf
; RPM: apache user chosen to provide access to the same directories as httpd
user = nginx #将Apache改为nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx #将Apache改为nginx
; listen = /run/php-fpm/www.sock #将此行注释
listen = 127.0.0.1:9000 #添加此行
.....
; Default Value: not set
pm.status_path = /fpm_status #取消此行注释,且便于区分,将status改为fpm_status
.....
; Default Value: not set
ping.path = /ping #取消此行注释
....
; Default Value: pong
ping.response = pong #取消此行注释
:wq
[root@proxy ~]#systemctl restart php-fpm

5.4、在DNS里添加解析(以前搭建的DNS)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#DNS主机:10.0.0.128
[root@DNS ~]#vim /var/named/magedu.org.zone
$TTL 1D
@ IN SOA master admin.magedu.org ( 6 1D 10M 1D 6H )
NS master
NS slave1
master A 10.0.0.128
slave1 A 10.0.0.184
kodbox A 10.0.0.184
:wq
[root@DNS ~]#rndc reload #重新加载
server reload successful

#将10.0.0.184的DNS指向10.0.0.128
[root@proxy ~]#vim /etc/sysconfig/network-scripts/ifcfg-eth0
DNS1=10.0.0.128
:wq
[root@proxy ~]#nmcli connection reload
[root@proxy ~]#nmcli connection up eth0

5.5、可道云下载

1
2
3
4
5
6
7
8
9
10
11
12
[root@proxy ~]#wget https://static.kodcloud.com/update/download/kodbox.1.35.zip
[root@proxy ~]#unzip kodbox.1.35.zip -d /data/nginx/kodbox
[root@proxy ~]#ll /data/nginx/kodbox
total 172
drwxr-xr-x 8 root root 110 Oct 31 18:31 app
-rw-r--r-- 1 root root 168291 Oct 31 18:31 Changelog.md
drwxr-xr-x 3 root root 91 Oct 31 18:31 config
drwxr-xr-x 3 root root 20 Oct 31 18:31 data
-rw-r--r-- 1 root root 157 Oct 31 18:31 index.php
drwxr-xr-x 18 root root 260 Oct 31 18:31 plugins
drwxr-xr-x 6 root root 58 Oct 31 18:31 static
[root@proxy ~]#chown -R nginx.nginx /data/nginx/kodbox

image-20221130173134603

下一步:

image-20221130173336671

此时发现仍缺少redis的相关组件

5.6、编译安装redis相关组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[root@proxy ~]#wget https://pecl.php.net/get/redis-5.3.7.tgz
[root@proxy ~]#mv redis-5.3.7.tgz /usr/local/src
[root@proxy ~]#cd /usr/local/src
[root@proxy src]#tar xf redis-5.3.7.tgz
[root@proxy src]#ls
echo-nginx-module-0.63 nginx-1.20.2.tar.gz package.xml redis-5.3.7.tgz v0.63.tar.gz nginx-1.20.2 nginx-module-vts-0.2.1 redis-5.3.7 v0.2.1.tar.gz
[root@proxy src]#cd redis-5.3.7/
#进入目录后发现没有./configure
[root@proxy redis-5.3.7]#less README.markdown #查看如何编译安装
## Installation
For everything you should need to install PhpRedis on your system,
see the [INSTALL.markdown](./INSTALL.markdown) page. #提示让看INSTALL.markdown
[root@proxy redis-5.3.7]#less INSTALL.markdown
cd phpredis
phpize #执行此命令后会生成phpize
./configure [--enable-redis-igbinary] [--enable-redis-msgpack] [--enable-redis-lzf [--with-liblzf[=DIR]]] [--enable-redis-zstd]
make && make install
[root@proxy redis-5.3.7]#phpize
-bash: phpize: command not found
[root@proxy redis-5.3.7]#yum provides phpize #查找phpize在哪个包里,在php-cli这个包里
Last metadata expiration check: 1:56:31 ago on Wed 30 Nov 2022 04:13:44 PM CST.
php-cli-7.2.24-1.module+el8.4.0+413+c9202dda.x86_64 : Command-line interface for PHP
Repo : AppStream
Matched from:
Filename : /usr/bin/phpize
[root@proxy redis-5.3.7]#yum -y install php-cli
[root@proxy redis-5.3.7]#phpize #显示少php-devel包
Can't find PHP headers in /usr/include/php
The php-devel package is required for use of this command.
[root@proxy redis-5.3.7]#yum -y install php-devel
[root@proxy redis-5.3.7]#./configure
[root@proxy redis-5.3.7]#make && make install
Installing shared extensions: /usr/lib64/php/modules/ #提示模块安装的路径
[root@proxy redis-5.3.7]#ls /usr/lib64/php/modules/
bz2.so dom.so gd.so mbstring.so pdo.so simplexml.so wddx.so calendar.so exif.so gettext.so mysqli.so pdo_sqlite.so sockets.so xmlreader.so ctype.so fileinfo.so iconv.so mysqlnd.so phar.so sqlite3.so xml.so curl.so ftp.so json.so pdo_mysql.so redis.so tokenizer.so xmlwriter.so xsl.so
#但此时PHP程序不知道有redis模块,需人为进行添加
[root@proxy redis-5.3.7]#vim /etc/php.d/
20-bz2.ini 20-fileinfo.ini 20-mbstring.ini 20-sqlite3.ini
20-calendar.ini 20-ftp.ini 20-mysqlnd.ini 20-tokenizer.ini
20-ctype.ini 20-gd.ini 20-pdo.ini 20-xml.ini
20-curl.ini 20-gettext.ini 20-phar.ini 20-xmlwriter.ini
20-dom.ini 20-iconv.ini 20-simplexml.ini 20-xsl.ini
20-exif.ini 20-json.ini 20-sockets.ini 30-mysqli.ini
30-pdo_mysql.ini 30-pdo_sqlite.ini 30-wddx.ini 30-xmlreader.ini
[root@proxy redis-5.3.7]#vim /etc/php.d/31-redis.ini
extension=redis #添加此行
:wq
[root@proxy redis-5.3.7]#systemctl restart php-fpm

image-20221130183021629

image-20221130183130306

image-20221130183154802

六、jumpserver 总结安装部署,添加用户授权,行为审计。

官方文档:

1
https://docs.jumpserver.org/zh/master/install/setup_by_fast/

6.1、安装要求

JumpServer 环境要求:

①硬件配置: 2个CPU核心, 4G 内存, 50G 硬盘(最低)

②操作系统: Linux 发行版 x86_64

③Python = 3.6.x

④MySQL Server ≥ 5.6 或者 Mariadb Server ≥ 5.5.56 数据库编码要求 uft8,新版要求5.7以上

⑤Redis: 新版要求6.0以上

6.2、安装方法

官方提供了多种安装方法

①手动部署: 一步一步实现

②极速部署: 资产数量不多,或者测试体验的用户请使用本脚本快速部署

③容器部署: 基于docker 实现

④分布式部署: 适用大型环境

6.3、基于容器部署

官方文档:

1
2
https://github.com/jumpserver/Dockerfile/tree/master/allinone
https://docs.jumpserver.org/zh/master/install/docker_install/
6.3.1、环境说明
1
https://github.com/jumpserver/Dockerfile/tree/master/allinone

使用外置 MySQL 数据库和 Redis:

1
2
3
4
5
6
7
8
9
10
11
12
- 外置数据库要求 MySQL 版本大于等于 5.7
- 外置 Redis 要求 Redis 版本大于等于 6.0
# 自行部署 MySQL 可以参考
(https://docs.jumpserver.org/zh/master/install/setup_by_lb/#mysql)
# mysql 创建用户并赋予权限, 请自行替换 nu4x599Wq7u0Bn8EABh3J91G 为自己的密码
mysql -u root -p
create database jumpserver default charset 'utf8';
create user 'jumpserver'@'%' identified by 'nu4x599Wq7u0Bn8EABh3J91G';
grant all on jumpserver.* to 'jumpserver'@'%';
flush privileges;
# 自行部署 Redis 可以参考
(https://docs.jumpserver.org/zh/master/install/setup_by_lb/#redis)

基于容器,安装完毕后可以通过以下方式访问

①浏览器访问: http://<容器所在服务器IP>

②默认管理员账户 admin 密码 admin

③SSH 访问: ssh -p 2222 <容器所在服务器IP>

④XShell 等工具请添加 connection 连接, 默认 ssh 端口 2222

容器docker安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
[root@docker ~]#cat install_docker.sh 
#!/bin/bash

DOCKER_VERSION="20.10.10"
UBUNTU_DOCKER_VERSION="5:${DOCKER_VERSION}~3-0~`lsb_release -si`-`lsb_release -cs`"
#UBUNTU_DOCKER_VERSION="5:20.10.9~3-0~`lsb_release -si`-`lsb_release -cs`"
#UBUNTU_DOCKER_VERSION="5:19.03.14~3-0~lsb_release -si-`lsb_release -cs`"

COLOR_SUCCESS="echo -e \\033[1;32m"
COLOR_FAILURE="echo -e \\033[1;31m"
END="\033[m"

. /etc/os-release

color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}


install_docker(){
if [ $ID = "centos" -o $ID = "rocky" ];then
if [ $VERSION_ID = "7" ];then
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/
EOF
else
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/8/x86_64/stable/
EOF
fi
yum clean all
${COLOR_FAILURE} "Docker有以下版本"${END}
yum list docker-ce --showduplicates
${COLOR_FAILURE}"5秒后即将安装: docker-"${DOCKER_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 5
yum -y install docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION \
|| { color "Base,Extras的yum源失败,请检查yum源配置" 1;exit; }
else
dpkg -s docker-ce &> /dev/null && $COLOR"Docker已安装,退出" 1 && exit
apt update || { color "更新包索引失败" 1 ; exit 1; }
apt -y install apt-transport-https ca-certificates curl software-properties-common || \
{ color "安装相关包失败" 1 ; exit 2; }
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt update
${COLOR_FAILURE} "Docker有以下版本"${END}
apt-cache madison docker-ce
${COLOR_FAILURE}"5秒后即将安装: docker-"${UBUNTU_DOCKER_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 5
apt -y install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION}
fi
if [ $? -eq 0 ];then
color "安装软件包成功" 0
else
color "安装软件包失败,请检查网络配置" 1
exit
fi

}

config_docker (){
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
"insecure-registries":["harbor.magedu.org:80"]
}
EOF
systemctl daemon-reload
systemctl enable docker
systemctl restart docker
docker version && color "Docker 安装成功" 0 || color "Docker 安装失败" 1
}


set_alias (){
echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
}


install_docker
config_docker
set_alias

6.3.2、安装MySQL服务

官方说明:

1
https://docs.jumpserver.org/zh/master/install/prod/distributed_03/

MYSQL要求

1
2
3
4
create database jumpserver default charset 'utf8';
create user 'jumpserver'@'%' identified by 'nu4x599Wq7u0Bn8EABh3J91G';
grant all on jumpserver.* to 'jumpserver'@'%';
flush privileges;
6.3.2.1、在宿主机准备MySQL配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#准备相关目录
[root@docker ~]#mkdir -p /etc/mysql/mysql.conf.d/
[root@docker ~]#mkdir -p /etc/mysql/conf.d/

#生成服务器配置文件,指定字符集
[root@docker ~]#tee /etc/mysql/mysql.conf.d/mysqld.cnf <<EOF
[mysqld]
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
datadir= /var/lib/mysql
symbolic-links=0
character-set-server=utf8   #添加此行,指定字符集
EOF

#生成客户端配置文件,指定字符集
[root@docker ~]#tee /etc/mysql/conf.d/mysql.cnf <<EOF
[mysql]
default-character-set=utf8
EOF

#查看配置文件列表
[root@docker ~]#tree /etc/mysql/
/etc/mysql/
├── conf.d
│   └── mysql.cnf
└── mysql.conf.d
└── mysqld.cnf

2 directories, 2 files
6.3.2.2、启动MySQL容器

将上面宿主机的设置好的配置文件挂载至MySQL容器

1
2
3
4
5
6
7
8
[root@docker ~]#docker run -d -p 3306:3306 --name mysql --restart always \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=jumpserver \
-e MYSQL_USER=jumpserver \
-e MYSQL_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
-v /etc/mysql/mysql.conf.d/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
-v /etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf mysql:5.7.30
6.3.2.3、查看验证mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@docker ~]#docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7.30 9cfcce23593a 2 years ago 448MB
[root@docker ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 0.0.0.0:3306 0.0.0.0:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::]:3306 [::]:*

#在其他机器上连接docker安装的mysql
[root@client ~]#mysql -uroot -p123456 -h10.0.0.186
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.30 MySQL Community Server (GPL)
[root@client ~]#mysql -ujumpserver -p123456 -h10.0.0.186
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jumpserver |
+--------------------+

6.3.3、安装Redis服务

官方说明:

1
https://docs.jumpserver.org/zh/master/install/prod/distributed_04/

新版要求:

1
外置 Redis 要求 Redis 版本大于等于 6.0
6.3.3.1、启动redis
1
[root@docker ~]#docker run -d -p 6379:6379 --name redis --restart always redis
6.3.3.2、验证Redis连接
1
2
3
4
5
6
[root@client ~]#yum -y install redis
[root@client ~]#redis-cli -h 10.0.0.186
10.0.0.186:6379> info
# Server
redis_version:6.2.6

6.3.4、部署JumpServer
6.3.4.1、生成key和token

官方说明

1
2
https://github.com/jumpserver/Dockerfile/tree/master/allinone
https://docs.jumpserver.org/zh/master/install/docker_install/

需要先生成key和token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@docker ~]#vim key.sh
#!/bin/bash
if [ ! "$SECRET_KEY" ];
then SECRET_KEY=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 50`;
echo "SECRET_KEY=$SECRET_KEY" >> ~/.bashrc; echo SECRET_KEY=$SECRET_KEY;
else echo SECRET_KEY=$SECRET_KEY;
fi
if [ ! "$BOOTSTRAP_TOKEN" ];
then BOOTSTRAP_TOKEN=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16`;
echo "BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN" >> ~/.bashrc;
echo BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN;
else echo BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN;
fi
:wq
[root@docker ~]#bash key.sh
SECRET_KEY=GkYTTfwge2HpQDiqjQ7hGqR7vEsSACM4rjgAlRbPE4gM7UKw7J
BOOTSTRAP_TOKEN=gdqRJc1By36Rq9pc
[root@docker ~]#tail -n2 .bashrc
SECRET_KEY=GkYTTfwge2HpQDiqjQ7hGqR7vEsSACM4rjgAlRbPE4gM7UKw7J
BOOTSTRAP_TOKEN=gdqRJc1By36Rq9pc
6.3.4.2、运行容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-----------------------------------------------------------------------------------
#在执行前须确保80端口未被启用,如果之前已经启用会报以下错误
docker: Error response from daemon: driver failed programming external connectivity on endpoint jms_all (6e30f944775bad02dad4865998908f432c97b740bc2f3f211cbb4f6d1adabf63): Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use.
-----------------------------------------------------------------------------------

[root@docker ~]#docker run --name jms_all -d \
-v /opt/jumpserver/core/data:/opt/jumpserver/data \
-v /opt/jumpserver/koko/data:/opt/koko/data \
-v /opt/jumpserver/lion/data:/opt/lion/data \
-p 80:80 \
-p 2222:2222 \
-e SECRET_KEY=GkYTTfwge2HpQDiqjQ7hGqR7vEsSACM4rjgAlRbPE4gM7UKw7J \
-e BOOTSTRAP_TOKEN=gdqRJc1By36Rq9pc \
-e LOG_LEVEL=ERROR \
-e DB_HOST=10.0.0.186 \
-e DB_PORT=3306 \
-e DB_USER=jumpserver \
-e DB_PASSWORD=123456 \
-e DB_NAME=jumpserver \
-e REDIS_HOST=10.0.0.186 \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD='' \
--privileged=true \
jumpserver/jms_all

-----------------------------------------------------------------------------------
#如果报以下错误:说明jms_all被占用,需要删除或者重命名
docker: Error response from daemon: Conflict. The container name "/jms_all" is already in use by container "10aecc51ec5bfd5a8121480a49bfdba40c6218868f1ac2f4e76ce685e3ef4412". You have to remove (or rename) that container to be able to reuse that name.
#删除方法:
[root@docker ~]#docker ps -a #先查看现在运行的程序
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
10aecc51ec5b jumpserver/jms_all "./entrypoint.sh" 17 minutes ago Created jms_all
ea0fcb85ce50 redis "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
26371d0aad4b mysql:5.7.30 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
[root@docker ~]#docker rm jms_all #删除jms_all
jms_all
-----------------------------------------------------------------------------------
6.3.4.3、验证是否成功
1
2
3
4
5
6
7
8
9
10
11
[root@docker ~]#docker logs -f jms_all
......
2022-12-01 12:51:29 JumpServer version v2.17.2, more see https://www.jumpserver.org
Migrate model org id: UserGroupStarting supervisor: supervisord.
Jumpserver ALL v2.17.2
官网 http://www.jumpserver.org
文档 http://docs.jumpserver.org

进入容器命令 docker exec -it jms_all /bin/bash

#下面就可以在浏览器里直接输入ip地址访问了

image-20221201130318586

注意:首次登录的初始账号和密码均为admin

登录进去后,会立刻让更改密码

image-20221201130505437

更改密码后重新登录

image-20221201170207670

6.4、用户授权和行为审计

6.4.1、创建组

创建开发组和测试组

image-20221201173556242

image-20221201173734350

6.4.2、创建用户并加入组

创建用户:xiaoming并加入开发组

image-20221202090518852

image-20221201180305733

创建用户:xiaohong并加入测试组

image-20221201180521002

登录账户:xiaoming,首次登录需要完善个人信息

image-20221201181249048

6.4.3、创建系统审计员

创建系统审计员:mage

image-20221201181034200

登录账户:mage,左侧管理向与普通用户不同

image-20221201181526636

6.4.4、创建管理用户

管理用户是jumpServer用来管理后端服务器或其它资产的管理员用户,此用户必须对后端服务器有管理权限

管理用户特点:

①通常是后端服务器的root或者是具备root权限的超级用户

②用于推送或者是创建系统用户

③用于获取被管理的硬件资产信息

image-20221201181844951

image-20221201182211875

6.4.5、创建资产并实现资产分类

创建可以被jumpServer用户访问的后端服务器和其它资产,比如:路由器,交换机等

image-20221201182544795

image-20221201182843812

image-20221201183120445

开发环境和测试环境各加入一台服务器

image-20221201183341015

6.4.6、创建系统用户

系统用户是分配给JumpServer用户,用来让JumpServer用户在连接后端服务器和其它资产,一般不会给管理权限

生产环境中,一般都会利用自动化运维工具提前在后端服务器创建好系统用户,在所有后端服务器统一用户ID信息,而非在jumpserver中创建

image-20221201183910518

image-20221201184417858

创建ceshi和kaifa用户

image-20221201184535208

6.4.7、关联使用系统用户的资产

将前面创建的系统用户推送到后端服务器并自动创建

在系统用户中添加使用此用户的资产

image-20221201184718588

image-20221201184932906

6.4.8、创建授权规则

通过授权规则, 为JumpServer用户分配可以访问的资产及使用的系统用户

image-20221201185653371

开发组授权

image-20221201185502685

测试组授权

image-20221201185607673

6.4.9、测试登录访问后端服务器

image-20221201185948662

开发组xiaoming登录后端

image-20221201190140452

6.4.9、ssh连接jumpserver

JumpServer 还支持用户通过ssh连接其2222/tcp端口进行访问

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@Rocky ~]#ssh -p2222 xiaoming@10.0.0.186    #10.0.0.186是搭建jumpserver的服务器 
xiaoming, JumpServer 开源堡垒机

1) 输入 部分IP,主机名,备注 进行搜索登录(如果唯一).
2) 输入 / + IP,主机名,备注 进行搜索,如:/192.168.
3) 输入 p 进行显示您有权限的主机.
4) 输入 g 进行显示您有权限的节点.
5) 输入 d 进行显示您有权限的数据库.
6) 输入 k 进行显示您有权限的Kubernetes.
7) 输入 r 进行刷新最新的机器和节点信息.
8) 输入 h 进行显示帮助.
9) 输入 q 进行退出.
Opt>
6.4.10、数据库授权
6.4.10.1、在后端服务器创建数据库
1
2
3
4
5
6
7
[root@mysql ~]#yum -y install mysql-server
[root@mysql ~]#systemctl enable --now mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mys
[root@mysql ~]#mysql
mysql> create database wordpress;
mysql> create user wordpress@'10.0.0.%' identified by '123456';
mysql> grant all on wordpress.* to wordpress@'10.0.0.%';
6.4.10.2、创建数据库应用

应用管理–数据库–创建

image-20221201193905625

6.4.10.3、创建数据库的系统用户

创建针对数据库的专用系统用户

注意:协议选择mysql

image-20221201194235233

image-20221201194506992

6.4.10.4、创建数据库授权规则

权限管理–应用授权

image-20221201194825919

数据库授权给测试组使用

image-20221201195123403

6.4.10.5、测试数据库连接

image-20221201195449263

6.4.11、会话管理

会话管理-命令记录、历史会话里面可以看到用户操作过并且已经退出的录像记录

在线会话

image-20221201195827167

历史会话

image-20221201200002381

七、JVM垃圾回收原理,JVM调优。

对于垃圾回收,需要解决三个问题

①哪些是垃圾要回收

②怎么回收垃圾

③什么时候回收垃圾

7.1、确定垃圾的方法

①引用计数: 每一个堆内对象上都与一个私有引用计数器,记录着被引用的次数,引用计数清零,该对象所占用堆内存就可以被回收。循环引用的对象都无法将引用计数归零,就无法清除。Python中即使用此种方式

②根搜索(可达)算法 Root Searching

image-20221202091339692

7.2、垃圾回收基本算法

方法一:标记-清除 Mark-Sweep

分垃圾标记阶段和内存释放两个阶段。

①标记阶段,找到所有可访问对象打个标记。清理阶段,遍历整个堆

②对未标记对象(即不再使用的对象)逐一进行清理。

特点:

优点:算法简单

缺点:标记-清除最大的问题会造成内存碎片,但是不浪费空间,效率较高(如果对象较多时,逐一删除效率也会受到影响)

方法二:标记-压缩 (压实)Mark-Compact

分垃圾标记阶段和内存整理两个阶段。

①标记阶段,找到所有可访问对象打个标记。

②内存清理阶段时,整理时将对象向内存一端移动,整理后存活对象连续的集中在内存一端。

特点:

标记-压缩算法好处是整理后内存空间连续分配,有大段的连续内存可分配,没有内存碎片。

缺点是内存整理过程有消耗,效率相对低下

方法三:复制Copying

先将可用内存分为大小相同两块区域A和B,每次只用其中一块,比如A。当A用完后,则将A中存活的对象复制到B。复制到B的时候连续的使用内存,最后将A一次性清除干净。

特点

好处是没有碎片,复制过程中保证对象使用连续空间,且一次性清除所有垃圾,所以即使对象很多,收回效率也很高

缺点是比较浪费内存,只能使用原来一半内存,因为内存对半划分了,复制过程毕竟也是有代价。

总结:

没有最好的算法,在不同场景选择最合适的算法

①效率: 复制算法>标记清除算法> 标记压缩算法

②内存整齐度: 复制算法=标记压缩算法> 标记清除算法

③内存利用率: 标记压缩算法=标记清除算法>复制算法

7.3、垃圾回收的原理

分代堆内存GC策略:对不同数据进行区分管理,不同分区对数据实施不同回收策略,分而治之。

堆内存分代将heap内存空间分为三个不同类别: 年轻代、老年代、持久代

年轻代Young:Young Generation

​ ——伊甸园区eden: 只有一个,刚刚创建的对象

​ ——幸存(存活)区Servivor Space:有2个幸存区,一个是from区,一个是to区。大小相等、地位相同、可互换

​ ——from 指的是本次复制数据的源区

​ ——to 指的是本次复制数据的目标区

老年代Tenured:Old Generation, 长时间存活的对象

**默认空间大小比例:**默认JVM试图分配最大内存的总内存的1/4,初始化默认总内存为总内存的1/64,年青代中heap的1/3,老年代占2/3

image-20221202093100290

永久代:JDK1.7之前使用, 即Method Area方法区,保存JVM自身的类和方法,存储JAVA运行时的环境信息,JDK1.8后 改名为 MetaSpace,此空间不存在垃圾回收,关闭JVM会释放此区域内存,此空间物理上不属于heap内存,但逻辑上存在于heap内存

​ ——永久代必须指定大小限制,字符串常量JDK1.7存放在永久代,1.8后存放在heap中

​ ——MetaSpace 可以设置,也可不设置,无上限

规律: 一般情况99%的对象都是临时对象

7.3.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完成

以后就重复上面的步骤。

通常场景下,大多数对象都不会存活很久,而且创建活动非常多,新生代就需要频繁垃圾回收。

但是,如果一个对象一直存活,它最后就在from、to来回复制,如果from区中对象复制次数达到阈值

(默认15次,CMS为6次,可通过java的选项 -XX:MaxTenuringThreshold=N 指定),就直接复制到老年

代。

7.3.2、老年代回收Major GC

进入老年代的数据较少,所以老年代区被占满的速度较慢,所以垃圾回收也不频繁。

如果老年代也满了,会触发老年代GC,称为Old GC或者 Major GC

由于老年代对象一般来说存活次数较长,所以较常采用标记-压缩算法。

当老年代满时,会触发 Full GC,即对所有”代”的内存进行垃圾回收

Minor GC比较频繁,Major GC较少。但一般Major GC时,由于老年代对象也可以引用新生代对象,所

以先进行一次Minor GC,然后在Major GC会提高效率。可以认为回收老年代的时候完成了一次Full GC。

所以可以认为 MajorGC = FullGC

7.4、JVM参数的选项分类

Java 命令行参考文档: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

选项分类

-选项名称 此为标准选项,所有HotSpot都支持

-X选项名称 此为稳定的非标准选项

-XX:选项名称 非标准的不稳定选项,下一个版本可能会取消

7.5、jvm调优

注意: 在不同领域和场景对JVM需要不同的调整策略

减少 STW 时长,串行变并行

减少 GC 次数,要分配合适的内存大小

一般情况下,大概可以使用以下原则:

客户端或较小程序,内存使用量不大,可以使用串行回收

对于服务端大型计算,可以使用并行回收

大型WEB应用,用户端不愿意等待,尽量少的STW,可以使用并发回收

①调整-Xms值和-Xmx值

将-Xms值和-Xmx值设置为一样大小,避免内存不够用时来回申请

​ -Xms:设置应用程序初始使用的堆内存大小(年轻代+老年代)

​ -Xmx:设置应用程序能获得的最大堆内存;早期JVM不建议超过32G,内存管理效率下降

1
2
3
4
5
6
7
8
9
10
11
12
#导入一个显示虚拟机(JVM)heap空间的java程序
[root@tomcat1 ~]#ls
Heap.java
[root@tomcat1 ~]#javac Heap.java
[root@tomcat1 ~]#ls
Heap.class Heap.java
[root@tomcat1 ~]#java Heap
max=478150656字节 456.0MB #heap最大可使用空间
total=31457280字节 30.0MB #初始设置的heap空间
[root@tomcat1 ~]#java -Xmx1g -Xms1g Heap
max=1073741824字节 1024.0MB
total=1073741824字节 1024.0MB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#更改Tomcat的heap空间大小
[root@tomcat2 tomcat]#vim bin/catalina.sh
JAVA_OPTS="-Xms4g -Xmx4g"
:wq
[root@tomcat2 tomcat]#systemctl restart tomcat

*************************************************************************

JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= -XX:MaxNewSize= "
-server:服务器模式
-Xms:堆内存初始化大小
-Xmx:堆内存空间上限
-XX:NewSize=:新生代空间初始化大小
-XX:MaxNewSize=:新生代空间最大值

更改前heap大小

image-20221203124240190

更改后heap大小

image-20221203124653941

②指定垃圾回收器的种类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#查看java的垃圾回收器的种类
[root@tomcat1 tomcat]#java -XX:+PrintCommandLineFlags -version
-XX:G1ConcRefinementThreads=2 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=29808512 -XX:MaxHeapSize=476936192 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC
#-XX:+UseG1GC这是新版本的垃圾回收器,已经不分代了

#JVM 1.8 默认的垃圾回收器:PS + ParallelOld(高吞吐量,但交互式体验差),所以大多数都是针对此进行调优,改成-XX:+UseConcMarkSweepGC垃圾回收器(交互式体验好)
#更改Tomcat的垃圾回收器
[root@tomcat2 tomcat]#vim bin/catalina.sh
JAVA_OPTS="-Xms4g -Xmx4g -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5"
:wq
[root@tomcat2 tomcat]#systemctl restart tomcat

**************************************************************************
-XX:+UseConcMarkSweepGC
新生代使用ParNew, 老年代优先使用CMS,备选方式为Serial Old
响应时间要短,停顿短使用这个垃圾收集器
-XX:CMSInitiatingOccupancyFraction=N,N为0-100整数表示达到老年代的大小的百分比多少触发回收默认68
-XX:+UseCMSCompactAtFullCollection 开启此值,在CMS收集后,进行内存碎片整理
-XX:CMSFullGCsBeforeCompaction=N 设定多少次CMS后,进行一次内存碎片整理
-XX:+CMSParallelRemarkEnabled 降低标记停顿

③线程池调整

常用属性:

​ ①connectionTimeout :连接超时时长,单位ms

​ ②maxThreads:最大线程数,默认200

​ ③minSpareThreads:最小空闲线程数

​ ④maxSpareThreads:最大空闲线程数

​ ⑤acceptCount:当启动线程满了之后,等待队列的最大长度,默认100

​ ⑥URIEncoding:URI 地址编码格式,建议使用 UTF-8

​ ⑦enableLookups:是否启用客户端主机名的DNS反向解析,缺省禁用,建议禁用,就使用客户端IP就行

​ ⑧compression:是否启用传输压缩机制,建议 “on”,CPU和流量的平衡

​ —compressionMinSize:启用压缩传输的数据流最小值,单位是字节

​ —compressableMimeType:定义启用压缩功能的MIME类型text/html, text/xml, text/css,text/javascript

1
2
3
4
5
6
7
8
#增大最大线程数,即增加可连接的客户数
[root@tomcat1 tomcat]#vim /usr/local/tomcat/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" maxThreads="2000" />
#增加maxThreads="2000"
:wq
[root@tomcat1 tomcat]#systemctl restart tomcat

image-20221203133648027

八、tomcat实现java应用发布。

8.1、部署基于JAVA的博客系统JPress

官方网站:http://www.jpress.io/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@Rocky ~]#cd /usr/local/tomcat/webapps
#将jpress-v4.0.7.war放入此目录下自动解压缩生成jpress-v4.0.7(注意:需要在Tomcat启动下)
[root@Rocky webapps]#ls
docs examples host-manager jpress-v4.0.7 jpress-v4.0.7.war manager ROOT
#包的名字非常重要,此时访问ip:8080/jpress-v4.0.7非常不方便。所以最好在将war包放到此目录前更改名称,比如博客blog

#先将jpress-v4.0.7.war移走,jpress-v4.0.7自动消失
[root@Rocky webapps]#mv jpress-v4.0.7.war /opt
[root@Rocky webapps]#ls
docs examples host-manager manager ROOT
[root@Rocky webapps]#cd /opt
[root@Rocky opt]#mv jpress-v4.0.7.war /usr/local/tomcat/webapps/blog.war
[root@Rocky opt]#cd -
/usr/local/tomcat/webapps
[root@Rocky webapps]#ls
blog blog.war docs examples host-manager manager ROOT
#此时只需要输入ip:8080/blog即可访问了

image-20221202143633554

1
2
3
4
5
6
#准备数据库和用户授权
[root@Rocky webapps]#yum -y install mysql-server ; systemctl enable --now mysqld
[root@Rocky webapps]#mysql
mysql> create database jpress;
mysql> create user jpress@'localhost' identified by '123456'; #因数据库安在本机,所以是localhost
mysql> grant all on jpress.* to jpress@'localhost';

image-20221202144619511

image-20221202144804984

image-20221202144839440

image-20221202144901645

此后输入10.0.0.186:8080/blog即可登录网页,但不是网站后端

image-20221202145157542

此后输入10.0.0.186:8080/blog/用户名即可登录网站后端

image-20221202145536310

九、实现tomcat session粘性,并验证过程。

image-20221202184926676

9.1、Tomcat配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
[root@tomcat1 ~]#cd /usr/local/tomcat
[root@tomcat1 tomcat]#vim conf/server.xml
<Host name="www.magedu.org" appBase="/data/tomcat/node1/"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="node1_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
:wq
[root@tomcat1 ~]#mkdir -p /data/tomcat/node1/ROOT
[root@tomcat1 ~]#cd /data/tomcat/node1/ROOT
[root@tomcat1 ROOT]#vim index.jsp
[root@tomcat1 ROOT]#cat 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 node1 </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>
[root@tomcat1 ~]#chown -R tomcat. /data/tomcat/node1/
[root@tomcat1 ROOT]#systemctl restart tomcat
-----------------------------------------------------------------------------------
[root@tomcat2 ~]#cd /usr/local/tomcat
[root@tomcat2 tomcat]#vim conf/server.xml
<Host name="www.magedu.org" appBase="/data/tomcat/node2/"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="node2_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
:wq
[root@tomcat2 ~]#mkdir -p /data/tomcat/node2/ROOT
[root@tomcat2 ~]#cd /data/tomcat/node2/ROOT
[root@tomcat2 ROOT]#vim index.jsp
[root@tomcat2 ROOT]#cat 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 node2 </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>
[root@tomcat2 ~]#chown -R tomcat. /data/tomcat/node2/
[root@tomcat2 ROOT]#systemctl restart tomcat

9.2、DNS解析

1
2
3
4
5
6
7
8
9
10
11
[root@DNS ~]#vim /var/named/magedu.org.zone 
$TTL 1D
@ IN SOA master admin.magedu.org ( 6 1D 10M 1D 6H )
NS master
NS slave1
master A 10.0.0.128
slave1 A 10.0.0.184
node1 A 10.0.0.216
node2 A 10.0.0.217
:wq
[root@DNS ~]#rndc reload

9.3、nginx的配置(反向代理与负载均衡)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@nginx ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream tomcat { #添加此模块
server 10.0.0.216:8080;
server 10.0.0.217:8080;
}

server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_pass http://tomcat; #添加以下两行
proxy_set_header Host $http_host;
}
}
}
:wq
[root@nginx ~]#systemctl restart nginx
#此时访问方式是轮询,但session一直发生变化
9.3.1、保持session不发生变化
1
2
3
4
5
6
7
8
[root@nginx ~]#vim /apps/nginx/conf/nginx.conf
upstream tomcat {
hash $cookie_JSESSIONID; #添加此行,当jsession相同时,就往同一台机器上调度
server 10.0.0.216:8080;
server 10.0.0.217:8080;
}
:wq
[root@nginx ~]#systemctl restart nginx

image-20221202185333822

image-20221202185406445

十、实现tomcat会话复制集群。

Tomcat 官方实现了 Session 的复制集群,将每个Tomcat的Session进行相互的复制同步,从而保证所有Tomcat都有相同的Session信息.

10.1、配置说明

官方文档:

1
https://tomcat.apache.org/tomcat-10.0-doc/cluster-howto.html https://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html

说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">

<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4" #每个集群的多播地址不同,范围224-239.x.x.x
port="45564" #45564/UDP
frequency="500" #间隔500ms发送
dropTime="3000"/> #故障阈值3s
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto" #监听地址,此项建议修改为当前主机的IP
port="4000" #监听端口
autoBind="100" #如果端口冲突,自动绑定其它端口,范围是4000- 4100
selectorTimeout="5000" #自动绑定超时时长5s
maxThreads="6"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender>
<Interceptor
className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchIntercep tor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>

<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

image-20221202192222020

10.1、Tomcat配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
[root@tomcat1 ~]#cd /usr/local/tomcat
[root@tomcat1 tomcat]#vim conf/server.xml
<Host name="www.magedu.org" appBase="/data/tomcat/node1/"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="node1_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
#下面的可以直接在官网了复制
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">

<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="10.0.0.216"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>

<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
#官网复制的截止到上面一行
</Host>
:wq
[root@tomcat1 ~]#mkdir -p /data/tomcat/node1/ROOT
[root@tomcat1 ~]#cd /data/tomcat/node1/ROOT
[root@tomcat1 ROOT]#vim index.jsp
[root@tomcat1 ROOT]#cat 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 node1 </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>
[root@tomcat1 ~]#chown -R tomcat. /data/tomcat/node1/
[root@tomcat1 ~]#cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/tomcat/node1/ROOT
[root@tomcat1 ~]#vim /data/tomcat/node1/ROOT/WEB-INF/web.xml
<distributable/> #在倒数第二行添加此行
:wq
[root@tomcat1 ROOT]#systemctl restart tomcat
-----------------------------------------------------------------------------------
[root@tomcat2 ~]#cd /usr/local/tomcat
[root@tomcat2 tomcat]#vim conf/server.xml
<Host name="www.magedu.org" appBase="/data/tomcat/node2/"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="node2_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
#下面的可以直接在官网了复制
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">

<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="10.0.0.216"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>

<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
#官网复制的截止到上面一行
</Host>
:wq
[root@tomcat2 ~]#mkdir -p /data/tomcat/node2/ROOT
[root@tomcat2 ~]#cd /data/tomcat/node2/ROOT
[root@tomcat2 ROOT]#vim index.jsp
[root@tomcat2 ROOT]#cat 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 node2 </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>
[root@tomcat2 ~]#chown -R tomcat. /data/tomcat/node2/
[root@tomcat2 ~]#cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/tomcat/node2/ROOT
[root@tomcat2 ~]#vim /data/tomcat/node2/ROOT/WEB-INF/web.xml
<distributable/> #在倒数第二行添加此行
:wq
[root@tomcat2 ROOT]#systemctl restart tomcat

10.2、DNS解析

和上面9.2、DNS解析相同

10.3、nginx的配置(反向代理与负载均衡)

和上面9.3、nginx的配置(反向代理与负载均衡)相同

image-20221202194512169

image-20221202194551409


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!