第九周作业
1、nginx实现全栈SSL。要求http rewrite到https协议。
1.1 自签名证书
[11:27:30 root@rocky pc]$ cd /apps/nginx/conf/conf.d/
[11:32:29 root@rocky conf.d]$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.yanlinux.org.key -x509 -days 3650 -out www.yanlinux.org.crt
Generating a RSA private key
...................................++++
.....................................++++
writing new private key to 'www.yanlinux.org.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:jiangsu
Locality Name (eg, city) [Default City]:nanjing
Organization Name (eg, company) [Default Company Ltd]:yanlinux.org
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:www.yanlinux.org
Email Address []:
[11:33:21 root@rocky conf.d]$ ll
total 16
-rw-r--r-- 1 root root 147 Nov 3 10:20 mobile.conf
-rw-r--r-- 1 root root 455 Nov 8 11:12 pc.conf
-rw-r--r-- 1 root root 2057 Nov 8 11:33 www.yanlinux.org.crt
-rw------- 1 root root 3272 Nov 8 11:32 www.yanlinux.org.key
1.2 第一个域名的https配置
[11:38:51 root@rocky conf.d]$ vi pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/conf/conf.d/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/conf/conf.d/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m; #共享缓存20兆
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
浏览器测试结果:
1.3 实现多域名
#制作第二个域名对应的key和csr文件
[14:20:25 root@rocky conf.d]$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout m.yanlinux.org.key -x509 -days 3650 -out m.yanlinux.org.crt
Generating a RSA private key
......................................................++++
...............++++
writing new private key to 'm.yanlinux.org.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:jiangsu
Locality Name (eg, city) [Default City]:najing
Organization Name (eg, company) [Default Company Ltd]:yanlinux.org
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:m.yanlinux.org
Email Address []:
[14:22:45 root@rocky nginx]$ ll ssl/
total 16
-rw-r--r-- 1 root root 2049 Nov 8 14:21 m.yanlinux.org.crt
-rw------- 1 root root 3272 Nov 8 14:20 m.yanlinux.org.key
-rw-r--r-- 1 root root 2057 Nov 8 11:33 www.yanlinux.org.crt
-rw------- 1 root root 3272 Nov 8 11:32 www.yanlinux.org.key
#配置第二个域名的配置文件
[14:24:09 root@rocky conf.d]$ vi mobile.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/m.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/m.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m
ssl_session_timeout 10m;
server_name m.yanlinux.org;
root /apps/nginx/html/mobile;
}
1.4 实现HSTS
[14:33:06 root@rocky conf.d]$ vi pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; #在首部加上HSTS
location / { #实现跳转
if ( $scheme = http ) {
rewrite ^/(.*)$ https://www.yanlinux.org/$1 redirect;
}
root /apps/nginx/html/pc;
}
}
2、nginx实现动静分离。
#实现静态资源访问10.0.0.28
[16:29:31 root@rocky8 ~]$ ll /usr/share/nginx/html/4.jpg
-rw-r--r-- 1 root root 308120 Aug 25 19:41 /usr/share/nginx/html/4.jpg
[16:30:33 root@rocky8 ~]$ ll /usr/share/nginx/html/1.png
-rw-r--r-- 1 root root 18000375 Aug 25 19:54 /usr/share/nginx/html/1.png
#实现动态资源访问10.0.0.38
[16:44:06 root@rocky8 ~]$ mkdir /usr/share/nginx/html/api
[16:48:23 root@rocky8 ~]$ echo /usr/share/nginx/html/api/index.html > /usr/share/nginx/html/api/index.html
#修改代理配置
[16:22:09 root@rocky conf.d]$ vi pc.conf
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location ~ \.(jpg|png|gif)$ {
proxy_pass http://10.0.0.28; #注意有后面的/, 表示置换;没有/,表示附加
proxy_connect_timeout 10s;
}
}
#测试动态资源
[16:34:39 root@rocky8 ~]$ curl www.yanlinux.org/api -L
/usr/share/nginx/html/api/index.html
#测试静态资源见下图
3、nginx实现防盗链功能。
[14:26:08 root@rocky ~]$ vi /apps/nginx/conf/conf.d/pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/m.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/m.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name m.yanlinux.org;
root /apps/nginx/html/mobile;
access_log /apps/nginx/logs/m.yanlinux.org-access.log access_json; valid_referers none blocked server_names *.yanlinux.com ~\.google\. ~\.baidu\. ~\.bing\. ~\.so\. ; #定义合法的referer
if ($invalid_referer) { #假如是使用其他的无效的referer访问,返回状态码403
return 403 "Forbidden Access";
}
}
#定义referer.html
[14:28:48 root@rocky ~]$ cat /apps/nginx/html/pc/referer.html
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.magedu.com/wp-content/uploads/2017/09/logo.png" >
</body>
</html>
#测试结果见下图
#查看日志文件
[14:30:08 root@rocky ~]$ cat /apps/nginx/logs/m.yanlinux.org-access.log|jq
{
"@timestamp": "2022-11-09T14:30:57+08:00",
"host": "10.0.0.8",
"clientip": "10.0.0.1",
"size": 16,
"responsetime": 0.000,
"upstreamtime": "-",
"upstreamhost": "-",
"http_host": "m.yanlinux.org",
"uri": "/logo.png",
"xff": "-",
"referer": "http://www.yanlinux.org/",
"tcp_xff": "-",
"http_user_agent": "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.35",
"status": "403" #403错误
}
4、解析nginx常见的负载均衡算法。
4.1 轮询算法(round robin)(默认)
轮询方式,依次将请求分配到各个后台服务器中,默认的负载均衡方式。
适用于后台机器性能一致的情况。
挂掉的机器可以自动从服务列表中剔除。
[20:58:40 root@proxy ~]$ vi /apps/nginx/conf/conf.d/pc.conf
upstream webserver { #标注两台后端web服务器的地址
server 10.0.0.28;
server 10.0.0.38;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver; #实现负载均衡,填写的是upstream配置块的名称
}
}
[20:59:11 root@proxy ~]$ nginx -s reload
#客户端10.0.0.18测试,是否实现负载均衡
[21:01:05 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.38
[21:01:05 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[21:01:06 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.38
[21:01:07 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
4.2 加权算法(weight)
根据权重来分发请求到不同的机器中,指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
[21:10:08 root@proxy ~]$ vi /apps/nginx/conf/conf.d/pc.conf
upstream webserver {
server 10.0.0.28 weight=3; #加上权重
server 10.0.0.38;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
}
}
[21:11:32 root@proxy ~]$ nginx -s reload
#测试
[21:12:08 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[21:12:09 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[21:12:10 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[21:12:11 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.38
4.3 ip_hash算法
根据请求者ip的hash值将请求发送到后台服务器中,可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题。
[22:05:57 root@proxy conf.d]$ vi pc.conf
upstream webserver {
ip_hash; #根据客户端ip调度
server 10.0.0.28;
server 10.0.0.38;
#server 127.0.0.1 backup;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
#proxy_connect_timeout 10s;
#proxy_cache off;
#proxy_cache_key $request_uri;
#proxy_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#proxy_set_header clientip $remote_addr;
}
}
[22:07:57 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[22:07:58 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[22:07:59 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[22:07:59 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
4.4 基于任意关键字实现 hash 算法的负载均衡:upstream_hash 模块
通过指定关键字作为 hash key,基于 hash 算法映射到特定的上游服务器中关键字可以含有变量、字符串可以使用 rr 算法的参数
4.4.1 基于源地址hash
[22:05:57 root@proxy conf.d]$ vi pc.conf
upstream webserver {
hash $remote_addr; #根据客户端ip调度
server 10.0.0.28;
server 10.0.0.38;
#server 127.0.0.1 backup;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
#proxy_connect_timeout 10s;
#proxy_cache off;
#proxy_cache_key $request_uri;
#proxy_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#proxy_set_header clientip $remote_addr;
}
}
[22:07:57 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[22:07:58 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[22:07:59 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
[22:07:59 root@rocky8 ~]$ curl www.yanlinux.org
10.0.0.28
4.4.2 基于cookie的hash
[22:07:54 root@proxy conf.d]$ vi pc.conf
upstream webserver {
hash $http_cookie;
#hash $remote_addr;
server 10.0.0.28;
server 10.0.0.38;
#server 127.0.0.1 backup;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
#proxy_connect_timeout 10s;
#proxy_cache off;
#proxy_cache_key $request_uri;
#proxy_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#proxy_set_header clientip $remote_addr;
}
}
[22:15:20 root@rocky8 ~]$ curl -b 'class=N68' www.yanlinux.org
10.0.0.38
[22:15:27 root@rocky8 ~]$ curl -b 'class=N67' www.yanlinux.org
10.0.0.28
4.4.3 url_hash
[22:14:26 root@proxy conf.d]$ vi pc.conf
upstream webserver {
hash $request_uri; #基于用户请求的uri
#hash $http_cookie;
#hash $remote_addr;
server 10.0.0.28;
server 10.0.0.38;
#server 127.0.0.1 backup;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
#proxy_connect_timeout 10s;
#proxy_cache off;
#proxy_cache_key $request_uri;
#proxy_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#proxy_set_header clientip $remote_addr;
}
}
[22:15:36 root@rocky8 ~]$ curl www.yanlinux.org/test1.html
test1.html on web02
[22:24:18 root@rocky8 ~]$ curl www.yanlinux.org/test1.html
test1.html on web02
[22:24:27 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web01
[22:24:30 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web01
4.5 最少连接数 least_conn
- 从所有上游服务器中,找出当前并发连接数最少的一个,将请求转发到它如果出现多个最少连接服务器的连接数都是一样的,使用 rr 算法。适用于客户端与后端服务器需要保持长连接的业务。
- 模块:
ngx_http_upstream_least_conn_module
,通过--without-http_upstream_ip_hash_module
禁用模块
[22:36:28 root@proxy conf.d]$ vi pc.conf
upstream webserver {
least_conn;
#ip_hash
#hash $request_uri;
#hash $http_cookie;
#hash $remote_addr;
server 10.0.0.28;
server 10.0.0.38;
#server 127.0.0.1 backup;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
#proxy_connect_timeout 10s;
#proxy_cache off;
#proxy_cache_key $request_uri;
#proxy_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#proxy_set_header clientip $remote_addr;
}
}
[22:38:28 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web02
[22:38:29 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web01
[22:38:29 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web02
4.6 一致性hash算法
将一个环分成了 2^32 个区间范围,四个节点将这个环划分成为了四个区间,每个区间的请求都由对应的节点去处理。来看看当扩容的时候会发生什么。
假设这时候发现 node4 负载过高,因此决定再添加一个节点进去分担压力,那么影响的也只是这个节点之后的请求,可能会缓存失效,而其他的三个节点是不会有任何影响的。
[22:48:05 root@proxy conf.d]$ vi pc.conf
upstream webserver {
#least_conn;
#ip_hash
hash $request_uri consistent ;
#hash $http_cookie;
#hash $remote_addr;
server 10.0.0.28;
server 10.0.0.38;
#server 127.0.0.1 backup;
}
server {
listen 443 ssl;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
}
server {
listen 80;
server_name www.yanlinux.org;
root /apps/nginx/html/pc;
access_log /apps/nginx/logs/www.yanlinux.org-access.log access_json;
location / {
proxy_pass http://webserver;
#proxy_connect_timeout 10s;
#proxy_cache off;
#proxy_cache_key $request_uri;
#proxy_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#proxy_set_header clientip $remote_addr;
}
}
[22:50:44 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web02
[22:50:44 root@rocky8 ~]$ curl www.yanlinux.org/test1.html
test1.html on web01
[22:50:47 root@rocky8 ~]$ curl www.yanlinux.org/test1.html
test1.html on web01
[22:50:48 root@rocky8 ~]$ curl www.yanlinux.org/test4.html
test4.html on web02
5、基于LNMP完成搭建任意一种应用。
5.1 利用 LNMP 实现WordPress站点搭建
LNMP项目实战环境说明
DNS服务器:centos7/10.0.0.7
nginx+php-fpm+wordpress服务器:rocky8/10.0.0.8
mysql服务器:10.0.0.18
5.1.1 部署DNS
[16:39:56 root@centos7 ~]$ cat install_dns.sh
DOMAIN=yanlinux.org
HOST=www
read -p "$(${COLOR}'请输入web服务器IP:'${END})" HOST_IP
#HOST_IP=10.0.0.100
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
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_dns () {
if [ $ID = 'centos' -o $ID = 'rocky' ];then
yum install -y bind bind-utils
elif [ $ID = 'ubuntu' ];then
color "不支持Ubuntu操作系统,退出!" 1
exit
#apt update
#apt install -y bind9 bind9-utils
else
color "不支持此操作系统,退出!" 1
exit
fi
}
config_dns () {
sed -i -e '/listen-on/s/127.0.0.1/localhost/' -e '/allow-query/s/localhost/any/' /etc/named.conf
cat >> /etc/named.rfc1912.zones <<EOF
zone "$DOMAIN" IN {
type master;
file "$DOMAIN.zone";
};
EOF
cat > /var/named/$DOMAIN.zone <<EOF
\$TTL 1D
@ IN SOA master admin.${DOMAIN} (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A `hostname -I`
$HOST A $HOST_IP
wordpress A $HOST_IP
EOF
chmod 640 /var/named/$DOMAIN.zone
chgrp named /var/named/$DOMAIN.zone
}
start_service () {
systemctl enable --now named
systemctl is-active named.service
if [ $? -eq 0 ] ;then
color "DNS 服务安装成功!" 0
else
color "DNS 服务安装失败!" 1
exit 1
fi
}
install_dns
config_dns
start_service
[16:40:16 root@centos7 ~]$ sh install_dns.sh
请输入web服务器IP:10.0.0.8
[16:41:55 root@centos7 ~]$ cat /var/named/yanlinux.org.zone
$TTL 1D
@ IN SOA master admin.yanlinux.org (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A 10.0.0.7
www A 10.0.0.8
wordpress A 10.0.0.8
5.1.2 部署数据库
#修改主机名
[16:42:33 root@rocky8 ~]$ hostnamectl set-hostname mysql-server.yanlinux.org
#yum安装mysql
[16:43:07 root@mysql-server ~]$ yum -y install mysql-server
[16:47:38 root@mysql-server ~]$ systemctl enable --now mysqld
#创建wordpress数据库,并创建用户及授权
[16:51:45 root@mysql-server ~]$ mysql -e 'create database wordpress;'
[16:53:17 root@mysql-server ~]$ mysql -e "create user wordpress@'10.0.0.%' identified by 'lgq123456';"
[16:53:45 root@mysql-server ~]$ mysql -e "grant all on wordpress.* to wordpress@'10.0.0.%';"
[16:54:43 root@mysql-server ~]$ mysql -uwordpress -h10.0.0.18 -p
Enter password:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
| wordpress |
+--------------------+
3 rows in set (0.00 sec)
5.1.3 部署PHP
[16:41:49 root@rocky ~]$ hostnamectl set-hostname proxy.yanlinux.org
[16:58:56 root@proxy ~]$ yum -y install php-fpm php-json php-mysqlnd
#修改php上传限制配置
[17:04:11 root@proxy ~]$ vi /etc/php.ini
post_max_size = 100M #将次行从8M修改为100M
upload_max_filesize = 100M #将此行从2M改为100M
#修改配置文件
[17:14:03 root@proxy ~]$ vi /etc/php-fpm.d/www.conf
user = nginx #修改为nginx
group = nginx #修改为nginx
;listen = /run/php-fpm/www.sock #注释此行
listen = 127.0.0.1:9000 #添加此行,监控本机的9000端口
pm.status_path = /fpm_status #取消此行的注释,并改为fpm_status,防止与nginx服务的status冲突
ping.path = /ping #取消此行的注释
ping.response = pong #取消此行的注释
#启动服务
[17:19:49 root@proxy ~]$ systemctl enable --now php-fpm.service
Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service → /usr/lib/systemd/system/php-fpm.service.
[17:21:59 root@proxy ~]$ ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 127.0.0.1:9000 0.0.0.0:* #监听端口开启
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 100 127.0.0.1:25 0.0.0.0:*
LISTEN 0 128 *:9090 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
[17:22:04 root@proxy ~]$ ps aux|grep php
root 5501 0.0 1.0 185340 19380 ? Ss 17:21 0:00 php-fpm: master process (/etc/php-fpm.conf)
nginx 5502 0.0 0.5 201688 10920 ? S 17:21 0:00 php-fpm: pool www
nginx 5503 0.0 0.5 201688 10924 ? S 17:21 0:00 php-fpm: pool www
nginx 5504 0.0 0.5 201688 10924 ? S 17:21 0:00 php-fpm: pool www
nginx 5505 0.0 0.5 201688 10924 ? S 17:21 0:00 php-fpm: pool www
nginx 5506 0.0 0.5 201688 10924 ? S 17:21 0:00 php-fpm: pool www
5.1.4 部署nginx
#编译安装
[17:24:38 root@proxy ~]$ cat /data/scripts/install_nginx.sh
#!/bin/bash
#
#***********************************************************
#Author: yanli
#Date: 2022-10-25
#FileName: install_nginx.sh
#Description:
#***********************************************************
OS_TYPE=`awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release`
OS_VERSION=`awk -F'[".]' '/^VERSION_ID/{print $2}' /etc/os-release`
CPU=`lscpu |awk '/^CPU\(s\)/{print $2}'`
SRC_DIR=/usr/local/src
read -p "$(echo -e '\033[1;32m请输入下载的版本号:\033[0m')" NUM
NGINX_FILE=nginx-${NUM}
NGINX_INSTALL_DIR=/apps/nginx
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
}
#下载源码
wget_package(){
[ -e ${NGINX_INSTALL_DIR} ] && { color "nginx 已安装,请卸载后再安装" 1; exit; }
cd ${SRC_DIR}
if [ -e ${NGINX_FILE}.tar.gz ];then
color "源码包已经准备好" 0
else
color "开始下载源码包" 0
wget http://nginx.org/download/${NGINX_FILE}.tar.gz
[ $? -ne 0 ] && { color "下载 ${NGINX_FILE}.tar.gz文件失败" 1; exit; }
fi
}
#编译安装
install_nginx(){
color "开始安装nginx" 0
if id nginx &> /dev/null;then
color "nginx用户已经存在" 1
else
useradd -s /sbin/nologin -r nginx
color "nginx用户账号创建完成" 0
fi
color "\n开始安装nginx依赖包\n" 0
if [ $OS_TYPE == "Centos" -a ${OS_VERSION} == '7' ];then
yum -y install make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Centos" -a ${OS_VERSION} == '8' ];then
yum -y install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Rocky" ];then
yum -y install make gcc libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Ubuntu" ];then
apt update
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev
else
color '不支持此系统!' 1
exit
fi
#开始编译安装
color "\n开始编译安装nginx\n" 0
cd $SRC_DIR
tar xf ${NGINX_FILE}.tar.gz
cd ${SRC_DIR}/${NGINX_FILE}
./configure --prefix=${NGINX_INSTALL_DIR} --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
make -j ${CPU} && make install
[ $? -eq 0 ] && color "nginx 编译安装成功" 0 || { color "nginx 编译安装失败,退出!" 1 ;exit; }
echo "PATH=${NGINX_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/nginx.sh
#创建service文件
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=/bin/rm -f ${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${NGINX_INSTALL_DIR}/sbin/nginx -t
ExecStart=${NGINX_INSTALL_DIR}/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
#启动服务
systemctl enable --now nginx &> /dev/null
systemctl is-active nginx &> /dev/null || { color "\nnginx 启动失败,退出!\n" 1 ; exit; }
color "\nnginx 安装完成\n" 0
}
wget_package
install_nginx
[17:27:39 root@proxy ~]$ sh /data/scripts/install_nginx.sh
请输入下载的版本号:1.22.1
[17:27:47 root@proxy ~]$ systemctl status nginx.service
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Drop-In: /usr/lib/systemd/system/nginx.service.d
└─php-fpm.conf
Active: active (running) since Wed 2022-11-02 09:44:09 CST; 1 weeks 1 days ago
Docs: http://nginx.org/en/docs/
Main PID: 4912 (nginx)
Tasks: 2 (limit: 11217)
Memory: 1.9M
CGroup: /system.slice/nginx.service
├─4912 nginx: master process /apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
└─4913 nginx: worker process
Nov 02 09:44:07 rocky.lgq.com systemd[1]: Starting nginx - high performance web server...
Nov 02 09:44:09 rocky.lgq.com systemd[1]: nginx.service: Can't open PID file /apps/nginx/run/nginx.pid>
Nov 02 09:44:09 rocky.lgq.com systemd[1]: Started nginx - high performance web server.
#配置nginx支持fastcgi
[17:28:52 root@proxy ~]$ mkdir /apps/nginx/conf/conf.d
[17:29:18 root@proxy ~]$ vi /apps/nginx/conf/nginx.conf
##在http配置块的最后加上下面一行信息
include /apps/nginx/conf/conf.d/*.conf;
[17:30:23 root@proxy ~]$ vi /apps/nginx/conf/conf.d/wordpress.conf
server {
listen 80;
server_name wordpress.yanlinux.org;
client_max_body_size 100M; #搭配5.3.4.2中修改的php.ini实现上传大文件
location / {
root /data/wordpress;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /data/wordpress;
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 SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[17:40:50 root@proxy ~]$ nginx -s reload
#测试php
#结果见下面图片
5.1.5 部署 WordPress
#下载wordpress
[17:58:00 root@proxy ~]$ wget https://cn.wordpress.org/latest-zh_CN.zip
[18:00:13 root@proxy ~]$ unzip latest-zh_CN.zip
[18:00:34 root@proxy ~]$ mkdir /data/wordpress -p
[18:01:06 root@proxy ~]$ mv wordpress/* /data/wordpress
[18:01:19 root@proxy ~]$ chown -R nginx.nginx /data/wordpress/
在浏览器中输入:wordpress.yanlinux.org
进行初始化web页面
#可以看到上传的图片
[18:07:14 root@proxy ~]$ tree /data/wordpress/wp-content/uploads/
/data/wordpress/wp-content/uploads/
└── 2022
└── 11
└── 1.png
2 directories, 1 file
5.1.6 安全加固以及开启opcache加速
[18:26:49 root@proxy ~]$ vi /apps/nginx/conf/conf.d/wordpress.conf
server {
listen 80;
server_name wordpress.yanlinux.org;
client_max_body_size 100M;
server_tokens off; #添加此行
location / {
root /data/wordpress;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /data/wordpress;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By; #添加此行
}
location ~ ^/(ping|fpm_status)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[18:27:05 root@proxy ~]$ nginx -s reload
#编辑php.ini开启opcache加速
[18:27:06 root@proxy ~]$ vi /etc/php.ini
[opcache]
; Determines if Zend OPCache is enabled
zend_extension=opcache.so
opcache.enable=1
5.2 项目实战:利用LNMP实现可道云私有云
5.2.1 部署DNS
#在5.1.1节中的结果中加上一行信息
[21:36:36 root@centos7 ~]$ vi /var/named/yanlinux.org.zone
$TTL 1D
@ IN SOA master admin.yanlinux.org (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A 10.0.0.7
www A 10.0.0.8
wordpress A 10.0.0.8
kodbox A 10.0.0.8 #加入这一行对应kodbox网址
[21:37:24 root@centos7 ~]$ rndc reload
server reload successful
5.2.2 部署数据库
#安装在5.1.2基础上另外创建kodbox对应数据库以及账号
[21:30:44 root@mysql-server ~]$ mysql -e 'create database kodbox;'
[21:41:39 root@mysql-server ~]$ mysql -e "create user kodbox@'10.0.0.%' identified by 'lgq123456';"
[21:43:25 root@mysql-server ~]$ mysql -e "grant all on kodbox.* to kodbox@'10.0.0.%';"
[21:44:14 root@mysql-server ~]$ mysql -e "show databases"
+--------------------+
| Database |
+--------------------+
| information_schema |
| kodbox |
| mysql |
| performance_schema |
| sys |
| wordpress |
+--------------------+
5.2.3 部署redis
[22:00:40 root@mysql-server ~]$ yum -y install redis
[22:01:19 root@mysql-server ~]$ vi /etc/redis.conf
bind 0.0.0.0 #将此行的127.0.0.1改为0.0.0.0,实现远程访问
[22:02:21 root@mysql-server ~]$ systemctl enable --now redis
5.2.4 部署PHP
#PHP大部分配置参照5.1.3小节,额外需要安装kodbox所需的依赖包
[22:17:15 root@proxy ~]$ yum -y install php-mbstring php-xml php-gd
#安装编译php-redis所依赖的相关包
[22:17:54 root@proxy ~]$ yum -y install php-cli php-devel
#官网下载php-redis,官网https://pecl.php.net/package/redis
[22:27:02 root@proxy ~]$ wget https://pecl.php.net/get/redis-5.3.7.tgz -P /usr/local/src/
[22:29:30 root@proxy src]$ cd /usr/local/src/
[22:29:52 root@proxy src]$ tar xf redis-5.3.7.tgz
[22:30:07 root@proxy src]$ cd redis-5.3.7/
[22:30:29 root@proxy redis-5.3.7]$ phpize
Configuring for:
PHP Api Version: 20170718
Zend Module Api No: 20170718
Zend Extension Api No: 320170718
[22:31:52 root@proxy redis-5.3.7]$ ./configure
[22:33:00 root@proxy redis-5.3.7]$ make -j 2 && make install
[22:33:53 root@proxy redis-5.3.7]$ ll /usr/lib64/php/modules/redis.so
-rwxr-xr-x 1 root root 3531032 Nov 10 22:33 /usr/lib64/php/modules/redis.so
[22:34:31 root@proxy redis-5.3.7]$ vi /etc/php.d/31-redis.ini
extension=redis #加入此行
#重启
[22:35:58 root@proxy redis-5.3.7]$ systemctl restart php-fpm.service
centos7部署php支持redis安装方法
[root@centos7 ~]$ yum install https://mirror.tuna.tsinghua.edu.cn/remi/enterprise/remi-release-7.rpm
#安装必要的包
[root@centos7 ~]$ yum -y install php74-php-fpm php74-php-mysqlnd php74-php-pecl-redis5 php74-php-mbstring php74-php-xml php74-php-gd
[root@centos7 ~]$ vim /etc/opt/remi/php74/php-fpm.d/www.conf
user = nginx
group = nginx
listen = 127.0.0.1:9000
#文件最后修改下面两行
php_value[session.save_handler] = redis
php_value[session.save_path] = "tcp://10.0.0.8:6379"
5.2.5 部署nginx
#安装配置nginx参照5.1.4小节,在此基础上配置kodbox对应的fastcgi配置
[21:52:26 root@proxy ~]$ vi /apps/nginx/conf/conf.d/kodbox.conf
server {
listen 80;
server_name kodbox.yanlinux.org;
client_max_body_size 100M;
server_tokens off;
location / {
root /data/kodbox/;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /data/kodbox/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
location ~ ^/(ping|fpm_status)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
5.2.6 部署kodbox
#下载kodbox
[22:06:01 root@proxy ~]$ wget https://static.kodcloud.com/update/download/kodbox.1.35.zip^C
[22:09:22 root@proxy ~]$ mkdir /data/kodbox
[22:10:08 root@proxy ~]$ unzip kodbox.1.35.zip -d /data/kodbox
[22:10:29 root@proxy ~]$ chown -R nginx.nginx /data/kodbox/
5.2.7 初始化和登录可道云
6、jumpserver 总结安装部署,添加用户授权,行为审计。
6.1 基于docker安装部署jumpserver
6.1.1 安装docker
[15:21:33 root@rocky ~]$ 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
[15:19:39 root@rocky ~]$ sh install_docker.sh
6.1.2 安装MySQL
#在宿主机准备MySQL配置文件
#准备相关目录
[15:24:07 root@rocky ~]$ mkdir -p /etc/mysql/mysql.conf.d
[15:26:12 root@rocky ~]$ mkdir -p /etc/mysql/conf.d
#生成服务器配置文件,指定字符集
[15:27:50 root@rocky ~]$ 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
#生成客户端配置文件,指定字符集
[15:28:51 root@rocky ~]$ tee /etc/mysql/conf.d/mysql.cnf <<EOF
> [mysql]
> default-character-set=utf8
> EOF
[15:31:04 root@rocky ~]$ tree /etc/mysql/
/etc/mysql/
├── conf.d
│ └── mysql.cnf
└── mysql.conf.d
└── mysqld.cnf
2 directories, 2 files
#启动 MySQL 容器
[15:36:02 root@rocky ~]$ docker run -d -p 3306:3306 --name mysql --restart always \
-e MYSQL_ROOT_PASSWORD=lgq123456 \
-e MYSQL_DATABASE=jumpserver \
-e MYSQL_USER=jumpserver \
-e MYSQL_PASSWORD=lgq123456 \
-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
#验证
[15:44:15 root@rocky8 ~]$ mysql -uroot -h10.0.0.8 -p
Enter password:
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)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jumpserver |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
6.1.3 安装redis服务
[15:54:38 root@rocky ~]$ docker run -d -p 6379:6379 --name redis --restart always redis
#验证
[15:57:39 root@rocky8 ~]$ redis-cli -h 10.0.0.8
10.0.0.8:6379> info
# Server
redis_version:6.2.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b61f37314a089f19
redis_mode:standalone
os:Linux 4.18.0-348.el8.0.2.x86_64 x86_64
6.1.4 部署Jumpserver
6.1.4.1 生成key和token
[16:02:15 root@rocky ~]$ cat 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
[16:02:01 root@rocky ~]$ sh key.sh
SECRET_KEY=aY8gq0orOcO6x2u2pm07UCiuo6hiqwMGBKIE0PRdkq57xJXIGW
BOOTSTRAP_TOKEN=IYkYOKl4Nmw3IgLS
6.1.4.2 运行容器
[16:08:51 root@rocky ~]$ 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=aY8gq0orOcO6x2u2pm07UCiuo6hiqwMGBKIE0PRdkq57xJXIGW \ #key.sh生成的key
-e BOOTSTRAP_TOKEN=IYkYOKl4Nmw3IgLS \ #key.sh生成的token
-e LOG_LEVEL=ERROR \
-e DB_HOST=10.0.0.8 \ #mysql服务器ip
-e DB_PORT=3306 \
-e DB_USER=jumpserver \ #创建的而账号
-e DB_PASSWORD=lgq123456 \
-e DB_NAME=jumpserver \
-e REDIS_HOST=10.0.0.8 \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD='' \
--privileged=true \
jumpserver/jms_all
6.1.4.3 验证
[16:14:20 root@rocky ~]$ docker logs -f jms_all
2022-11-11 16:14:03 Check database connection: 0
2022-11-11 16:14:03 Generating grammar tables from /usr/lib/python3.8/lib2to3/Grammar.txt
2022-11-11 16:14:03 Generating grammar tables from /usr/lib/python3.8/lib2to3/PatternGrammar.txt
2022-11-11 16:14:03 Database connect success
2022-11-11 16:14:03 Collect static files
2022-11-11 16:14:03 Collect static files done
2022-11-11 16:14:03 Check database structure change ...
2022-11-11 16:14:03 Migrate model change to database ...
System check identified no issues (0 silenced).
......
2022-11-11 16:14:20 Fri Nov 11 16:14:20 2022
2022-11-11 16:14:20 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
6.2 用户授权和行为审计
6.2.1 创建组
6.2.2 创建用户并加入组
登录xiaohong
6.2.3 创建系统审计员
6.2.4 创建管理用户
管理用户是jumpServer用来管理后端服务器或其它资产的管理员用户,此用户必须对后端服务器有管理
权限
6.2.5 创建资产并实现资产分类
创建可以被jumpServer用户访问的后端服务器和其它资产,比如:路由器,交换机等
6.2.6 创建系统用户
系统用户是分配给JumpServer用户,用来让JumpServer用户在连接后端服务器和其它资产,一般不会给管理权限
生产环境中,一般都会利用自动化运维工具提前在后端服务器创建好系统用户,在所有后端服务器统一用户ID信息,而非在jumpserver中创建
6.2.7 关联使用系统用户的资产
将前面创建的系统用户推送到后端服务器并自动创建
在系统用户中添加使用此用户的资产
6.2.8 创建授权规则
通过授权规则, 为JumpServer用户分配可以访问的资产及使用的系统用户
6.2.9 测试登录访问后端服务器
6.2.10 ssh连接jumpserver
[16:46:25 root@rocky ~]$ ssh -p2222 xiaoming@127.0.0.1
xiaoming@127.0.0.1's password:
xiaoming, JumpServer 开源堡垒机
1) 输入 部分IP,主机名,备注 进行搜索登录(如果唯一).
2) 输入 / + IP,主机名,备注 进行搜索,如:/192.168.
3) 输入 p 进行显示您有权限的主机.
4) 输入 g 进行显示您有权限的节点.
5) 输入 d 进行显示您有权限的数据库.
6) 输入 k 进行显示您有权限的Kubernetes.
7) 输入 r 进行刷新最新的机器和节点信息.
8) 输入 h 进行显示帮助.
9) 输入 q 进行退出.
Opt> p
ID | 主机名 | IP | 备注
+-------+--------------------------------------------------+-------------------------+----------------+
1 | centos7 | 10.0.0.7 |
2 | rocky8 | 10.0.0.18 |
页码:1,每页行数:33,总页数:1,总数量:2
提示:输入资产ID直接登录,二级搜索使用 // + 字段,如://192 上一页:b 下一页:n
搜索:
[18:20:44 root@rocky ~]$ ssh -p2222 xiaohong@127.0.0.1
xiaohong@127.0.0.1's password:
xiaohong, JumpServer 开源堡垒机
1) 输入 部分IP,主机名,备注 进行搜索登录(如果唯一).
2) 输入 / + IP,主机名,备注 进行搜索,如:/192.168.
3) 输入 p 进行显示您有权限的主机.
4) 输入 g 进行显示您有权限的节点.
5) 输入 d 进行显示您有权限的数据库.
6) 输入 k 进行显示您有权限的Kubernetes.
7) 输入 r 进行刷新最新的机器和节点信息.
8) 输入 h 进行显示帮助.
9) 输入 q 进行退出.
Opt> p
ID | 主机名 | IP | 备注
+-------+--------------------------------------------------+-------------------------+----------------+
1 | ubuntu2004 | 10.0.0.200 |
页码:1,每页行数:33,总页数:1,总数量:1
提示:输入资产ID直接登录,二级搜索使用 // + 字段,如://192 上一页:b 下一页:n
搜索:
[Host]> g
节点:[ ID.名称(资产数量) ].
├── 1.收藏夹(0)
└── 2.Default(1)
└── 3.test环境(1)
6.2.11 查看在线会话
6.2.12 在线回放历史会话
6.2.13 查看命令历史
7、JVM垃圾回收原理,JVM调优。
7.1 JVM垃圾回收原理
分代堆内存GC策略:对不同数据进行区分管理,不同分区对数据实施不同回收策略,分而治之
Heap堆内存分为
- 年轻代Young:Young Generation
- 伊甸园区eden: 只有一个,刚刚创建的对象
- 幸存(存活)区Servivor Space:有2个幸存区,一个是from区,一个是to区。大小相等、地位相同、可互换。
- from 指的是本次复制数据的源区
- to 指的是本次复制数据的目标区
- 老年代Tenured:Old Generation, 长时间存活的对象
- 永久代:JDK1.7之前使用, 即Method Area方法区,保存JVM自身的类和方法,存储JAVA运行时的环境信息,JDK1.8后 改名为 MetaSpace,此空间不存在垃圾回收,关闭JVM会释放此区域内存,此空间物理上不属于heap内存,但逻辑上存在于heap内存
7.1.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.1.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.2 JVM调优
对JVM调整策略应用极广
- 在WEB领域中Tomcat等
- 在大数据领域Hadoop生态各组件
- 在消息中间件领域的Kafka等
- 在搜索引擎领域的ElasticSearch、Solr等
注意: 在不同领域和场景对JVM需要不同的调整策略
- 减少 STW 时长,串行变并行
- 减少 GC 次数,要分配合适的内存大小
一般情况下,大概可以使用以下原则:
- 客户端或较小程序,内存使用量不大,可以使用串行回收
- 对于服务端大型计算,可以使用并行回收
- 大型WEB应用,用户端不愿意等待,尽量少的STW,可以使用并发回收
指定垃圾回收设置
[16:05:26 root@tomcat1 ~]$ vi /usr/local/tomcat/bin/catalina.sh
......
#添加下面一行
JAVA_OPTS="-server -Xmx512m -Xms128m -XX:NewSize=48m -XX:MaxNewSize=200m -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5"
#在这些行上面添加一行信息
# OS specific support. $var _must_ be set to either true or false.
cygwin=false
darwin=false
os400=false
hpux=false
......
[16:09:23 root@tomcat1 ~]$ systemctl restart tomcat.service
8、tomcat实现java应用发布。
8.1 部署基于JAVA的博客系统 JPress
官方网站: http://www.jpress.io/
#上官网下载war包,上传到服务器
[16:44:56 root@rocky ~]$ cp jpress-v4.0.7.war /usr/local/tomcat/webapps/jpress.war
[16:45:33 root@rocky ~]$ cd /usr/local/tomcat/webapps/
[16:45:42 root@rocky webapps]$ ls
app1 docs examples host-manager jpress jpress.war manager ROOT
#准备数据库和用户授权
[16:46:56 root@rocky ~]$ yum -y install mysql-server
[16:51:44 root@rocky ~]$ systemctl enable --now mysqld
[16:56:58 root@rocky ~]$ mysql -e "create user jpress@'10.0.0.%' identified by '123456';"
[16:57:40 root@rocky ~]$ mysql -e "create database jpress"
[16:58:12 root@rocky ~]$ mysql -e "grant all on jpress.* to jpress@'10.0.0.%';"
8.2 实战案例:部署博客系统zrlog
官网:ZrLog 博客程序
#官网下载,传到服务器上
[17:51:21 root@rocky ~]$ ls zrlog-2.2.1-efbe9f9-release.war
zrlog-2.2.1-efbe9f9-release.war
[17:53:30 root@rocky ~]$ cp zrlog-2.2.1-efbe9f9-release.war /usr/local/tomcat/webapps/zrlog.war
[17:53:49 root@rocky ~]$ ls /usr/local/tomcat/webapps/
app1 docs examples host-manager jpress jpress.war manager ROOT zrlog zrlog.war
[17:53:50 root@rocky ~]$ mysql -e "create database zrlog;"
[17:57:31 root@rocky ~]$ mysql -e "create user zrlog@'10.0.0.%' identified by 'lgq123456';"
[17:58:00 root@rocky ~]$ mysql -e "grant all on zrlog.* to zrlog@'10.0.0.%';"
9、实现tomcat session粘性,并验证过程。
9.1 负载均衡主机和网络地址规划
IP | 主机名 | 服务 | 软件 |
---|---|---|---|
10.0.0.7 | dns | DNS | bind bind-utils |
10.0.0.8 | 调度器 | nginx | |
10.0.0.38 | tomcat1 | tomcat1 | JDK8、tomcat9 |
10.0.0.28 | tomcat1 | tomcat2 | JDK8、tomcat9 |
9.2 搭建DNS
[17:12:57 root@dns ~]$ cat install_dns.sh
DOMAIN=yanlinux.org
HOST=www
read -p "$(${COLOR}'请输入web服务器IP:'${END})" HOST_IP
#HOST_IP=10.0.0.100
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
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_dns () {
if [ $ID = 'centos' -o $ID = 'rocky' ];then
yum install -y bind bind-utils
elif [ $ID = 'ubuntu' ];then
color "不支持Ubuntu操作系统,退出!" 1
exit
#apt update
#apt install -y bind9 bind9-utils
else
color "不支持此操作系统,退出!" 1
exit
fi
}
config_dns () {
sed -i -e '/listen-on/s/127.0.0.1/localhost/' -e '/allow-query/s/localhost/any/' /etc/named.conf
cat >> /etc/named.rfc1912.zones <<EOF
zone "$DOMAIN" IN {
type master;
file "$DOMAIN.zone";
};
EOF
cat > /var/named/$DOMAIN.zone <<EOF
\$TTL 1D
@ IN SOA master admin.${DOMAIN} (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A `hostname -I`
$HOST A $HOST_IP
EOF
chmod 640 /var/named/$DOMAIN.zone
chgrp named /var/named/$DOMAIN.zone
}
start_service () {
systemctl enable --now named
systemctl is-active named.service
if [ $? -eq 0 ] ;then
color "DNS 服务安装成功!" 0
else
color "DNS 服务安装失败!" 1
exit 1
fi
}
install_dns
config_dns
start_service
[17:13:37 root@dns ~]$ sh install_dns.sh
[17:30:20 root@dns ~]$ cat /var/named/yanlinux.org.zone
$TTL 1D
@ IN SOA master admin.yanlinux.org (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A 10.0.0.7
www A 10.0.0.8
9.3 负载均衡tomcat主机准备
- tomcat1主机准备
[16:37:10 root@tomcat1 ~]$ cat install_tomcat.sh
DIR=`pwd`
read -p "$(echo -e '\033[1;32m请输入JDK版本号:\033[0m')" JDK_VERSION
read -p "$(echo -e '\033[1;32m请输入Tomcat版本号:\033[0m')" TOMCAT_VERSION
JDK_FILE="jdk-${JDK_VERSION}-linux-x64.tar.gz"
TOMCAT_FILE="apache-tomcat-${TOMCAT_VERSION}.tar.gz"
INSTALL_DIR="/usr/local"
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 "$2" && $MOVE_TO_COL
echo -n "["
if [ $1 = "success" -o $1 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $1 = "failure" -o $1 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
install_jdk(){
if ! [ -f "${DIR}/${JDK_FILE}" ];then
color 1 "${JDK_FILE}不存在,请去官网下载"
exit;
elif [ -f ${INSTALL_DIR}/jdk ];then
color 1 "JDK已经安装"
exit;
else
[ -d "${INSTALL_DIR}" ] || mkdir -pv ${INSTALL_DIR}
fi
tar xf ${DIR}/${JDK_FILE} -C ${INSTALL_DIR}
cd ${INSTALL_DIR} && ln -s jdk* jdk
cat > /etc/profile.d/jdk.sh <<EOF
export JAVA_HOME=${INSTALL_DIR}/jdk
#export JRE_HOME=\$JAVA_HOME/jre
#export CLASSPATH=.:\$JAVA_HOME/lib/:\$JRE_HOME/lib/
export PATH=\$PATH:\$JAVA_HOME/bin
EOF
. /etc/profile.d/jdk.sh
java -version && color 0 "JDK安装完成" || { color 1 "JDK安装失败"; exit; }
}
install_tomcat(){
if ! [ -f "${DIR}/${TOMCAT_FILE}" ];then
color 1 "${TOMCAT_FILE}不存在,请去官网下载"
exit;
elif [ -f ${INSTALL_DIR}/tomcat ];then
color 1 "tomcat已经安装"
exit;
else
[ -d "${INSTALL_DIR}" ] || mkdir -pv ${INSTALL_DIR}
fi
tar xf ${DIR}/${TOMCAT_FILE} -C ${INSTALL_DIR}
cd ${INSTALL_DIR} && ln -s apache-tomcat-*/ tomcat
echo "PATH=${INSTALL_DIR}/tomcat/bin:"'$PATH' > /etc/profile.d/tomcat.sh
id tomcat &> /dev/null || useradd -r -s /sbin/nologin tomcat
cat > ${INSTALL_DIR}/tomcat/conf/tomcat.conf <<EOF
JAVA_HOME=${INSTALL_DIR}/jdk
EOF
chown -R tomcat.tomcat ${INSTALL_DIR}/tomcat/
cat > /lib/systemd/system/tomcat.service <<EOF
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=${INSTALL_DIR}/tomcat/conf/tomcat.conf
ExecStart=${INSTALL_DIR}/tomcat/bin/startup.sh
ExecStop=${INSTALL_DIR}/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now tomcat.service &> /dev/null
systemctl is-active tomcat.service &> /dev/null && color 0 "TOMCAT 安装完成" || { color 1 "TOMCAT 安装失败" ; exit; }
}
install_jdk
install_tomcat
[16:37:38 root@tomcat1 ~]$ sh install_tomcat.sh
请输入JDK版本号:8u351
请输入Tomcat版本号:9.0.69
[16:59:27 root@tomcat1 ~]$ systemctl status tomcat.service
● tomcat.service - Tomcat
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2022-11-16 16:59:21 CST; 16s ago
Process: 1680 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
Main PID: 1688 (java)
Tasks: 27 (limit: 11218)
Memory: 74.4M
CGroup: /system.slice/tomcat.service
└─1688 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/loggi>
Nov 16 16:59:21 rocky8.yanlinux.cn systemd[1]: Starting Tomcat...
Nov 16 16:59:21 rocky8.yanlinux.cn systemd[1]: Started Tomcat.
#准备数据目录
[17:41:49 root@tomcat1 ~]$ mkdir -p /data/tomcat/node1/ROOT
[17:42:49 root@tomcat1 ~]$ vi /data/tomcat/node1/ROOT/index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<h1> node1 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>
[17:44:15 root@tomcat1 ~]$ tree /data/tomcat/
/data/tomcat/
└── node1
└── ROOT
└── index.jsp
2 directories, 1 file
[17:44:33 root@tomcat1 ~]$ chown -R tomcat.tomcat /data/tomcat/
#创建tomcat虚拟主机
[17:44:47 root@tomcat1 ~]$ vi /usr/local/tomcat/conf/server.xml
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
#添加下面两行
<Host name="www.yanlinux.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 "%r" %s %b" />
</Host>
#上面两行时添加的
</Engine>
</Service>
</Server>
[17:49:05 root@tomcat1 ~]$ systemctl restart tomcat.service
- tomcat2主机准备呢
[18:00:38 root@tomcat1 ~]$ sh install_tomcat.sh
请输入JDK版本号:8u351
请输入Tomcat版本号:9.0.69
[18:02:13 root@tomcat2 ~]$ mkdir /data/tomcat/node2/ROOT -p
[18:02:21 root@tomcat2 ~]$ vi /data/tomcat/node2/ROOT/index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<h1> node2 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>
[18:03:54 root@tomcat2 ~]$ chown -R tomcat.tomcat /data/tomcat/
[18:07:05 root@tomcat2 ~]$ vi /usr/local/tomcat/conf/server.xml
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
#添加下面几行
<Host name="www.yanlinux.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 "%r" %s %b" />
</Host>
#添加上面几行
</Engine>
</Service>
</Server>
[18:14:33 root@tomcat2 ~]$ systemctl restart tomcat.service
9.4 nginx实现后端tomcat的负载均衡调度
[21:12:42 root@nginx-proxy ~]$ cat install_nginx.sh
OS_TYPE=`awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release`
OS_VERSION=`awk -F'[".]' '/^VERSION_ID/{print $2}' /etc/os-release`
CPU=`lscpu |awk '/^CPU\(s\)/{print $2}'`
SRC_DIR=/usr/local/src
read -p "$(echo -e '\033[1;32m请输入下载的版本号:\033[0m')" NUM
NGINX_FILE=nginx-${NUM}
NGINX_INSTALL_DIR=/apps/nginx
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
}
#下载源码
wget_package(){
[ -e ${NGINX_INSTALL_DIR} ] && { color "nginx 已安装,请卸载后再安装" 1; exit; }
cd ${SRC_DIR}
if [ -e ${NGINX_FILE}.tar.gz ];then
color "源码包已经准备好" 0
else
color "开始下载源码包" 0
wget http://nginx.org/download/${NGINX_FILE}.tar.gz
[ $? -ne 0 ] && { color "下载 ${NGINX_FILE}.tar.gz文件失败" 1; exit; }
fi
}
#编译安装
install_nginx(){
color "开始安装nginx" 0
if id nginx &> /dev/null;then
color "nginx用户已经存在" 1
else
useradd -s /sbin/nologin -r nginx
color "nginx用户账号创建完成" 0
fi
color "开始安装nginx依赖包" 0
if [ $OS_TYPE == "Centos" -a ${OS_VERSION} == '7' ];then
yum -y install make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Centos" -a ${OS_VERSION} == '8' ];then
yum -y install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Rocky" ];then
yum -y install make gcc libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Ubuntu" ];then
apt update
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev
else
color '不支持此系统!' 1
exit
fi
#开始编译安装
color "开始编译安装nginx" 0
cd $SRC_DIR
tar xf ${NGINX_FILE}.tar.gz
cd ${SRC_DIR}/${NGINX_FILE}
./configure --prefix=${NGINX_INSTALL_DIR} --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
make -j ${CPU} && make install
[ $? -eq 0 ] && color "nginx 编译安装成功" 0 || { color "nginx 编译安装失败,退出!" 1 ;exit; }
echo "PATH=${NGINX_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/nginx.sh
#创建service文件
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=/bin/rm -f ${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${NGINX_INSTALL_DIR}/sbin/nginx -t
ExecStart=${NGINX_INSTALL_DIR}/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
#启动服务
systemctl enable --now nginx &> /dev/null
systemctl is-active nginx &> /dev/null || { color "nginx 启动失败,退出!" 1 ; exit; }
color "nginx 安装完成" 0
}
wget_package
install_nginx
[21:13:02 root@nginx-proxy ~]$ sh install_nginx.sh
[21:19:28 root@nginx-proxy ~]$ vi /apps/nginx/conf/nginx.conf
#在最后一个}上面加入以下一行
include /apps/nginx/conf/conf.d/*.conf;
[21:21:45 root@nginx-proxy ~]$ cd /apps/nginx/conf/
[21:23:34 root@nginx-proxy conf]$ mkdir conf.d
[21:23:43 root@nginx-proxy conf.d]$ vi tomcat.conf
upstream tomcat-server {
hash $cookie_JSESSIONID; #基于cookie的hash,固定效果
server 10.0.0.38:8080;
server 10.0.0.28:8080;
}
server {
server_name www.yanlinux.org;
location / {
root html;
index index.html index.jsp;
proxy_pass http://tomcat-server;
proxy_set_header Host $http_host;
}
}
[21:37:51 root@nginx-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
[21:37:58 root@nginx-proxy conf.d]$ nginx -s reload
再次访问还是这个sessionid,和界面
换一个浏览器
10、实现tomcat会话复制集群
IP | 主机名 | 服务 | 软件 |
---|---|---|---|
10.0.0.7 | dns | DNS | bind bind-utils |
10.0.0.8 | 调度器 | nginx | |
10.0.0.38 | tomcat1 | tomcat1 | JDK8、tomcat9 |
10.0.0.28 | tomcat1 | tomcat2 | JDK8、tomcat9 |
10.1 搭建DNS
[17:12:57 root@dns ~]$ cat install_dns.sh
DOMAIN=yanlinux.org
HOST=www
read -p "$(${COLOR}'请输入web服务器IP:'${END})" HOST_IP
#HOST_IP=10.0.0.100
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
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_dns () {
if [ $ID = 'centos' -o $ID = 'rocky' ];then
yum install -y bind bind-utils
elif [ $ID = 'ubuntu' ];then
color "不支持Ubuntu操作系统,退出!" 1
exit
#apt update
#apt install -y bind9 bind9-utils
else
color "不支持此操作系统,退出!" 1
exit
fi
}
config_dns () {
sed -i -e '/listen-on/s/127.0.0.1/localhost/' -e '/allow-query/s/localhost/any/' /etc/named.conf
cat >> /etc/named.rfc1912.zones <<EOF
zone "$DOMAIN" IN {
type master;
file "$DOMAIN.zone";
};
EOF
cat > /var/named/$DOMAIN.zone <<EOF
\$TTL 1D
@ IN SOA master admin.${DOMAIN} (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A `hostname -I`
$HOST A $HOST_IP
EOF
chmod 640 /var/named/$DOMAIN.zone
chgrp named /var/named/$DOMAIN.zone
}
start_service () {
systemctl enable --now named
systemctl is-active named.service
if [ $? -eq 0 ] ;then
color "DNS 服务安装成功!" 0
else
color "DNS 服务安装失败!" 1
exit 1
fi
}
install_dns
config_dns
start_service
[17:13:37 root@dns ~]$ sh install_dns.sh
[17:30:20 root@dns ~]$ cat /var/named/yanlinux.org.zone
$TTL 1D
@ IN SOA master admin.yanlinux.org (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A 10.0.0.7
www A 10.0.0.8
10.2 负载均衡tomcat主机准备
10.2.1 tomcat1主机准备
[16:37:10 root@tomcat1 ~]$ cat install_tomcat.sh
DIR=`pwd`
read -p "$(echo -e '\033[1;32m请输入JDK版本号:\033[0m')" JDK_VERSION
read -p "$(echo -e '\033[1;32m请输入Tomcat版本号:\033[0m')" TOMCAT_VERSION
JDK_FILE="jdk-${JDK_VERSION}-linux-x64.tar.gz"
TOMCAT_FILE="apache-tomcat-${TOMCAT_VERSION}.tar.gz"
INSTALL_DIR="/usr/local"
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 "$2" && $MOVE_TO_COL
echo -n "["
if [ $1 = "success" -o $1 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $1 = "failure" -o $1 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
install_jdk(){
if ! [ -f "${DIR}/${JDK_FILE}" ];then
color 1 "${JDK_FILE}不存在,请去官网下载"
exit;
elif [ -f ${INSTALL_DIR}/jdk ];then
color 1 "JDK已经安装"
exit;
else
[ -d "${INSTALL_DIR}" ] || mkdir -pv ${INSTALL_DIR}
fi
tar xf ${DIR}/${JDK_FILE} -C ${INSTALL_DIR}
cd ${INSTALL_DIR} && ln -s jdk* jdk
cat > /etc/profile.d/jdk.sh <<EOF
export JAVA_HOME=${INSTALL_DIR}/jdk
#export JRE_HOME=\$JAVA_HOME/jre
#export CLASSPATH=.:\$JAVA_HOME/lib/:\$JRE_HOME/lib/
export PATH=\$PATH:\$JAVA_HOME/bin
EOF
. /etc/profile.d/jdk.sh
java -version && color 0 "JDK安装完成" || { color 1 "JDK安装失败"; exit; }
}
install_tomcat(){
if ! [ -f "${DIR}/${TOMCAT_FILE}" ];then
color 1 "${TOMCAT_FILE}不存在,请去官网下载"
exit;
elif [ -f ${INSTALL_DIR}/tomcat ];then
color 1 "tomcat已经安装"
exit;
else
[ -d "${INSTALL_DIR}" ] || mkdir -pv ${INSTALL_DIR}
fi
tar xf ${DIR}/${TOMCAT_FILE} -C ${INSTALL_DIR}
cd ${INSTALL_DIR} && ln -s apache-tomcat-*/ tomcat
echo "PATH=${INSTALL_DIR}/tomcat/bin:"'$PATH' > /etc/profile.d/tomcat.sh
id tomcat &> /dev/null || useradd -r -s /sbin/nologin tomcat
cat > ${INSTALL_DIR}/tomcat/conf/tomcat.conf <<EOF
JAVA_HOME=${INSTALL_DIR}/jdk
EOF
chown -R tomcat.tomcat ${INSTALL_DIR}/tomcat/
cat > /lib/systemd/system/tomcat.service <<EOF
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=${INSTALL_DIR}/tomcat/conf/tomcat.conf
ExecStart=${INSTALL_DIR}/tomcat/bin/startup.sh
ExecStop=${INSTALL_DIR}/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now tomcat.service &> /dev/null
systemctl is-active tomcat.service &> /dev/null && color 0 "TOMCAT 安装完成" || { color 1 "TOMCAT 安装失败" ; exit; }
}
install_jdk
install_tomcat
[16:37:38 root@tomcat1 ~]$ sh install_tomcat.sh
请输入JDK版本号:8u351
请输入Tomcat版本号:9.0.69
[16:59:27 root@tomcat1 ~]$ systemctl status tomcat.service
● tomcat.service - Tomcat
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2022-11-16 16:59:21 CST; 16s ago
Process: 1680 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
Main PID: 1688 (java)
Tasks: 27 (limit: 11218)
Memory: 74.4M
CGroup: /system.slice/tomcat.service
└─1688 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/loggi>
Nov 16 16:59:21 rocky8.yanlinux.cn systemd[1]: Starting Tomcat...
Nov 16 16:59:21 rocky8.yanlinux.cn systemd[1]: Started Tomcat.
#准备数据目录
[17:41:49 root@tomcat1 ~]$ mkdir -p /data/tomcat/node1/ROOT
[17:42:49 root@tomcat1 ~]$ vi /data/tomcat/node1/ROOT/index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<h1> node1 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>
[17:44:15 root@tomcat1 ~]$ tree /data/tomcat/
/data/tomcat/
└── node1
└── ROOT
└── index.jsp
2 directories, 1 file
[17:44:33 root@tomcat1 ~]$ chown -R tomcat.tomcat /data/tomcat/
#创建tomcat虚拟主机
[17:44:47 root@tomcat1 ~]$ vi /usr/local/tomcat/conf/server.xml
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
#添加下面两行
<Host name="www.yanlinux.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 "%r" %s %b" />
</Host>
#上面两行时添加的
</Engine>
</Service>
</Server>
[17:49:05 root@tomcat1 ~]$ systemctl restart tomcat.service
10.2.2 tomcat2主机准备呢
[18:00:38 root@tomcat1 ~]$ sh install_tomcat.sh
请输入JDK版本号:8u351
请输入Tomcat版本号:9.0.69
[18:02:13 root@tomcat2 ~]$ mkdir /data/tomcat/node2/ROOT -p
[18:02:21 root@tomcat2 ~]$ vi /data/tomcat/node2/ROOT/index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<h1> node2 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>
[18:03:54 root@tomcat2 ~]$ chown -R tomcat.tomcat /data/tomcat/
[18:07:05 root@tomcat2 ~]$ vi /usr/local/tomcat/conf/server.xml
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
#添加下面几行
<Host name="www.yanlinux.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 "%r" %s %b" />
</Host>
#添加上面几行
</Engine>
</Service>
</Server>
[18:14:33 root@tomcat2 ~]$ systemctl restart tomcat.service
10.3 nginx实现后端tomcat的负载均衡调度
[21:12:42 root@nginx-proxy ~]$ cat install_nginx.sh
OS_TYPE=`awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release`
OS_VERSION=`awk -F'[".]' '/^VERSION_ID/{print $2}' /etc/os-release`
CPU=`lscpu |awk '/^CPU\(s\)/{print $2}'`
SRC_DIR=/usr/local/src
read -p "$(echo -e '\033[1;32m请输入下载的版本号:\033[0m')" NUM
NGINX_FILE=nginx-${NUM}
NGINX_INSTALL_DIR=/apps/nginx
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
}
#下载源码
wget_package(){
[ -e ${NGINX_INSTALL_DIR} ] && { color "nginx 已安装,请卸载后再安装" 1; exit; }
cd ${SRC_DIR}
if [ -e ${NGINX_FILE}.tar.gz ];then
color "源码包已经准备好" 0
else
color "开始下载源码包" 0
wget http://nginx.org/download/${NGINX_FILE}.tar.gz
[ $? -ne 0 ] && { color "下载 ${NGINX_FILE}.tar.gz文件失败" 1; exit; }
fi
}
#编译安装
install_nginx(){
color "开始安装nginx" 0
if id nginx &> /dev/null;then
color "nginx用户已经存在" 1
else
useradd -s /sbin/nologin -r nginx
color "nginx用户账号创建完成" 0
fi
color "开始安装nginx依赖包" 0
if [ $OS_TYPE == "Centos" -a ${OS_VERSION} == '7' ];then
yum -y install make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Centos" -a ${OS_VERSION} == '8' ];then
yum -y install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Rocky" ];then
yum -y install make gcc libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ $OS_TYPE == "Ubuntu" ];then
apt update
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev
else
color '不支持此系统!' 1
exit
fi
#开始编译安装
color "开始编译安装nginx" 0
cd $SRC_DIR
tar xf ${NGINX_FILE}.tar.gz
cd ${SRC_DIR}/${NGINX_FILE}
./configure --prefix=${NGINX_INSTALL_DIR} --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
make -j ${CPU} && make install
[ $? -eq 0 ] && color "nginx 编译安装成功" 0 || { color "nginx 编译安装失败,退出!" 1 ;exit; }
echo "PATH=${NGINX_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/nginx.sh
#创建service文件
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=/bin/rm -f ${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${NGINX_INSTALL_DIR}/sbin/nginx -t
ExecStart=${NGINX_INSTALL_DIR}/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
#启动服务
systemctl enable --now nginx &> /dev/null
systemctl is-active nginx &> /dev/null || { color "nginx 启动失败,退出!" 1 ; exit; }
color "nginx 安装完成" 0
}
wget_package
install_nginx
[21:13:02 root@nginx-proxy ~]$ sh install_nginx.sh
#生成自签名文件
[21:13:58 root@nginx-proxy ~]$ mkdir /apps/nginx/ssl
[21:14:08 root@nginx-proxy ~]$ cd /apps/nginx/ssl
[21:14:25 root@nginx-proxy ssl]$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout m.yanlinux.org.key -x509 -days 3650 -out m.yanlinux.org.crt
Generating a RSA private key
......................................................++++
...............++++
writing new private key to 'm.yanlinux.org.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:jiangsu
Locality Name (eg, city) [Default City]:najing
Organization Name (eg, company) [Default Company Ltd]:yanlinux.org
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:www.yanlinux.org
Email Address []:
[21:16:45 root@nginx-proxy ssl]$ ll
-rw-r--r-- 1 root root 2057 Nov 8 21:16 www.yanlinux.org.crt
-rw------- 1 root root 3272 Nov 8 21:16 www.yanlinux.org.key
#创建tomcat对应配置文件
[21:19:28 root@nginx-proxy ~]$ vi /apps/nginx/conf/nginx.conf
#在最后一个}上面加入以下一行
include /apps/nginx/conf/conf.d/*.conf;
[21:21:45 root@nginx-proxy ssl]$ cd /apps/nginx/conf/
[21:23:34 root@nginx-proxy conf]$ mkdir conf.d
[21:23:43 root@nginx-proxy conf.d]$ vi tomcat.conf
upstream tomcat-server {
server 10.0.0.38:8080;
server 10.0.0.28:8080;
}
server {
listen 80;
server_name www.yanlinux.org;
return 302 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name www.yanlinux.org;
ssl_certificate /apps/nginx/ssl/www.yanlinux.org.crt;
ssl_certificate_key /apps/nginx/ssl/www.yanlinux.org.key;
client_max_body_size 20m;
location / {
proxy_pass http://tomcat-server;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[21:37:51 root@nginx-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
[21:37:58 root@nginx-proxy conf.d]$ nginx -s reload
10.4 在所有后端tomcat主机上修改conf/server.xml
本次把多播复制的配置放到虚拟主机里面, 即Host块中。
特别注意修改Receiver
的address
属性为一个本机可对外的IP地址。
10.4.1 修改 tomcat1 主机的 conf/server.xml
[15:47:22 root@tomcat1 ~]$ vi /usr/local/tomcat/conf/server.xml
<Host name="www.yanlinux.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 "%r" %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.38"#指定网卡的ip,不然的话默认127.0.0.1
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>
[15:54:03 root@tomcat1 ~]$ systemctl restart tomcat.service
[15:54:22 root@tomcat1 ~]$ 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 50 [::ffff:10.0.0.38]:4000 #监听端口 *:*
LISTEN 0 1 [::ffff:127.0.0.1]:8005 *:*
LISTEN 0 100 *:8080 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
10.4.2 修改 tomcat2 主机的 conf/server.xml
[16:02:04 root@tomcat2 ~]$ vi /usr/local/tomcat/conf/server.xml
<Host name="www.yanlinux.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 "%r" %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.28"
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>
[16:03:13 root@tomcat2 ~]$ systemctl restart tomcat.service
[16:03:20 root@tomcat2 ~]$ 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 100 *:8080 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 50 [::ffff:10.0.0.28]:4000 #监听端口 *:*
10.5 修改应用的web.xml文件开启该应用程序的分布式
参考官方说明: https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html
Make sure your web.xml has the <distributable/> element
为所有tomcat主机应用web.xml
的 <web-app>
标签增加子标签 <distributable/>
来开启该应用程序的分布式。
10.5.1 修改tomcat1主机的应用的web.xml文件
[16:07:49 root@tomcat1 ~]$ cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/tomcat/node1/ROOT/
[16:07:58 root@tomcat1 ~]$ ll /data/tomcat/node1/ROOT/
total 4
-rw-r--r-- 1 tomcat tomcat 396 Nov 16 19:09 index.jsp
drwxr-x--- 2 tomcat tomcat 21 Nov 16 18:49 WEB-INF
[16:08:01 root@tomcat1 ~]$ vi /data/tomcat/node1/ROOT/WEB-INF/web.xml
......
<description>
Welcome to Tomcat
</description>
<distributable/> #添加此行
</web-app>
[16:09:26 root@tomcat1 ~]$ systemctl restart tomcat.service
10.5.2 修改tomcat2主机的应用的web.xml文件
[16:11:54 root@tomcat2 ~]$ cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/tomcat/node2/ROOT/
[16:12:06 root@tomcat2 ~]$ ll /data/tomcat/node2/ROOT/
total 4
-rw-r--r-- 1 tomcat tomcat 396 Nov 16 18:03 index.jsp
drwxr-x--- 2 tomcat tomcat 21 Nov 16 17:00 WEB-INF
[16:12:11 root@tomcat2 ~]$ vi /data/tomcat/node2/ROOT/WEB-INF/web.xml
......
<description>
Welcome to Tomcat
</description>
<distributable/> #添加此行
</web-app>
[16:12:49 root@tomcat2 ~]$ systemctl restart tomcat.service
10.6 测试访问
重启全部Tomcat,通过负载均衡调度到不同节点,返回的SessionID不变了。
用浏览器访问,并刷新多次,发现SessionID 不变,但后端主机在轮询
但此方式当后端tomcat主机较多时,会重复占用大量的内存,并不适合后端服务器众多的场景
10.7 故障模拟
#停掉tomcat2节点,模拟故障
[16:18:35 root@tomcat2 ~]$ systemctl stop tomcat.service
浏览器访问多次,sessionid不发生变化