马哥SRE第九周课程作业

nginx、jumpserver、tomcat

  • 一. nginx实现全栈SSL。要求http rewrite到https协议。
    • 1.1 实现HSTS
    • 1.2 rewrite重定向
    • 1.3 另外补充return重定向跳转的案例
  • 二. nginx实现动静分离。
    • 2.1 实现动静分离
      • 2.1.1 配置 nginx 实现反向代理的动静分离
      • 2.1.2 准备后端 httpd 服务器
  • 三. nginx实现防盗链功能。
    • 3.1 实现盗链
    • 3.2 实现防盗链
  • 四. 解析nginx常见的负载均衡算法。
    • 4.1 介绍
  • 五. 基于LNMP完成搭建任意一种应用。
    • 5.1 项目实战:利用LNMP实现可道云私有云
      • 5.1.1 环境说明
      • 5.1.2 准备 MySQL 数据库
      • 5.1.3 准备 Redis 服务
      • 5.1.4 准备 Nginx 服务
      • 5.1.5 CentOS8 php 支持 redis
      • 5.1.6 准备可道云程序
  • 六. jumpserver 总结安装部署,添加用户授权,行为审计。
    • 6.1 安装 JumpServer
    • 6.2 安装要求
    • 6.3 安装方法介绍
    • 6.4 基于容器部署
    • 6.5 环境说明
    • 6.6 安装 MySQL 服务
      • 6.6.1 下载 MySQL 镜像查看默认配置
      • 6.6.2 在宿主机准备MySQL配置文件
      • 6.6.4 启动 MySQL 容器
    • 6.7 安装 Redis 服务
    • 6.8 部署 JumpServer
      • 6.8.1 运行容器
  • 七. JVM垃圾回收原理,JVM调优。
  • 八. tomcat实现java应用发布。
  • 九. 实现tomcat session粘性,并验证过程。
  • 十. 实现tomcat会话复制集群。

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

1.1 实现HSTS

官方文档:

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

京东一小时内访问网站请求在浏览器直接就跳转,一小时后还是发送http请求到了服务器返回https

马哥SRE第九周课程作业_第1张图片

范例: (浏览器内部就跳转https)

server {
   listen 443 ssl;
   server_name www.magedu.org;
   add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"
always;
   location / {
       if ( $scheme = http ) {
         rewrite ^/(.*)$ https://www.magedu.org/$1 redirect;                   
                            
       }
   .....
   }
}

范例:

[root@centos8 ~]#vim /apps/nginx/conf/conf.d/pc.conf
server {
 listen 80;
 listen 443 ssl;
 ssl_certificate /apps/nginx/conf/conf.d/www.magedu.org.crt;
 ssl_certificate_key /apps/nginx/conf/conf.d/www.magedu.org.key;
 ssl_session_cache shared:sslcache:20m;
 ssl_session_timeout 10m;
 server_name www.magedu.org;
 error_log /apps/nginx/logs/magedu.org_error.log notice;  
 access_log /apps/nginx/logs/magedu.org_access.log main;
 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"
always;
 location / {
   root /data/nginx/html/pc;
   if ( $scheme = http ) {
         rewrite ^/(.*)$ https://www.magedu.org/$1 redirect;                   
                            
   }
 }
[root@centos8 ~]#systemctl restart nginx
[root@centos7 ~]#curl -ikL https://www.magedu.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:29:56 GMT
Content-Type: text/html
Content-Length: 7
Last-Modified: Sat, 26 Sep 2020 01:18:32 GMT
Connection: keep-alive
ETag: "5f6e96e8-7"
Strict-Transport-Security: max-age=31536000; includeSubDomains
Accept-Ranges: bytes
pc web

1.2 rewrite重定向

案例:基于通信安全考虑公司网站要求全站 https,因此要求将在不影响用户请求的情况下将http请求全
部自动跳转至 https,另外也可以实现部分 location 跳转
也可以用两个虚拟主机分开写listen

马哥SRE第九周课程作业_第2张图片
马哥SRE第九周课程作业_第3张图片

[root@centos8 ~]#vim /apps/nginx/conf.d/pc.conf
server {
 listen 443 ssl;
 listen 80;
 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;
 location / {    #针对全站跳转
   root /data/nginx/html/pc;
   index index.html;
    if ($scheme = http ){  #如果没有加条件判断,会导致死循环
   rewrite ^/(.*)$ https://$host/$1 redirect;
   }  
 }
 location /login {     #针对特定的URL进行跳转https 
 if ($scheme = http ){  #如果没有加条件判断,会导致死循环
   rewrite / https://$host/login redirect;
   } 
 }
}
#重启Nginx并访问测试
[root@centos7 ~]#curl -ikL www.magedu.org
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:23:48 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://www.magedu.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:23:48 GMT
Content-Type: text/html
Content-Length: 7
Last-Modified: Sat, 26 Sep 2020 01:18:32 GMT
Connection: keep-alive
ETag: "5f6e96e8-7"
Accept-Ranges: bytes
pc web

1.3 另外补充return重定向跳转的案例

方法0:死循环

server {
 listen 80;
 listen 443 ssl;
 server_name www.magedu.org;
 ssl_certificate   /etc/nginx/ssl/www.magedu.org.crt;
 ssl_certificate_key /etc/nginx/ssl/www.magedu.org.key;
 root /data/www/html; 
return 302 https://$server_name$request_uri;
}

方法1:

server {
 listen 80;
 server_name www.magedu.org;
 return 302 https://$server_name$request_uri;
}
server {
 listen 443 ssl;
 server_name www.magedu.org;
 ssl_certificate   /etc/nginx/ssl/www.magedu.org.crt;
 ssl_certificate_key /etc/nginx/ssl/www.magedu.org.key;
 location / {
 root /data/www/html; 
 }
}

方法2:

server {
 listen 80;
 listen 443 ssl;
 server_name www.magedu.org;
 ssl_certificate   /etc/nginx/ssl/www.magedu.org.crt;
 ssl_certificate_key /etc/nginx/ssl/www.magedu.org.key;
 if ( $scheme = http ){
       return 302 https://$server_name$request_uri;
     }
 location / {
 root /data/www/html; 
 }
}

二. nginx实现动静分离。

2.1 实现动静分离

要求:将客户端对除php以外的资源的访问转发至后端服务器 10.0.0.28上

2.1.1 配置 nginx 实现反向代理的动静分离

[root@centos8 ~]#vi /apps/nginx/conf/conf.d/pc.conf 
 location / {
   proxy_pass http://10.0.0.28;
   index index.html;
 }
 location ~ \.php$ {
   root /data/php;
   fastcgi_pass   10.0.0.18:9000;
   fastcgi_index index.php;
    #fastcgi_param SCRIPT_FILENAME /data/php$fastcgi_script_name;
   fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include       fastcgi_params;
 } 

2.1.2 准备后端 httpd 服务器

#在后端服务器10.0.0.28上安装httpd服务
[root@centos8 ~]#dnf -y install httpd
[root@centos8 ~]#systemctl enable --now httpd
[root@centos8 ~]#mkdir /var/www/html/images
[root@centos8 ~]#wget -O /var/www/html/images/magedu.jpg 
http://www.magedu.com/wp-content/uploads/2019/05/2019052306372726.jpg

三. nginx实现防盗链功能。

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标
记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

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

正常通过搜索引擎搜索web 网站并访问该网站的referer信息如下:

[root@centos8 ~]#tail -f /apps/nginx/logs/magedu.org_access.log
10.0.0.1 - - [11/Oct/2020:09:28:10 +0800] "GET /images/logo.png HTTP/1.1" 302
145 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, 
like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38" "-"
10.0.0.1 - - [11/Oct/2020:09:30:39 +0800] "GET /images/logo.png HTTP/1.1" 200
5934 "http://10.0.0.18/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 
Edg/86.0.622.38" "-"
10.0.0.1 - - [11/Oct/2020:09:32:20 +0800] "GET /images/logo.png HTTP/1.1" 200
5934 "http://www.mageedu.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 
Edg/86.0.622.38" "-"

json格式日志

#通过搜索引擎访问web网站的referer信息:
==> /apps/nginx/logs/access_json.log <==
{"@timestamp":"2019-02-
28T13:58:46+08:00","host":"10.0.0.100","clientip":"10.0.0.1","siz
e":0,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-
","http_host":"www.magedu.org","uri":"/index.html","domain":"www.magedu.org","xf
f":"-","referer":"https://www.baidu.com/s?ie=utf-
8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=www.magedu.org&oq=www.mageedu.net&rsv_pq=d6
3060680002eb69&rsv_t=de01TWnmyTdcJqph7SfI1hXgXLJxSSfUPcQ3QkWdJk%2FLNrN95ih3XOhbR
s4&rqlang=cn&rsv_enter=1&inputT=321&rsv_sug3=41&rsv_sug2=0&rsv_sug4=1626","tcp_x
ff":"","http_user_agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 
Safari/537.36","status":"304"}

3.1 实现盗链

在一个web 站点盗链另一个站点的资源信息,比如:图片、视频等

#新建一个主机www.mageedu.org,盗取另一台主机www.magedu.org的图片
[root@centos8 conf.d]# pwd
/apps/nginx/conf/conf.d
[root@centos8 conf.d]# cat mageedu.org.conf 
server {
 listen 80;
 server_name www.mageedu.org;
 location / {
   index index.html;
   root "/data/nginx/html/magedu";
   access_log /apps/nginx/logs/magedu.org_access.log main;
 }
}
#准备盗链web页面:
[root@centos8 conf.d]# mkdir /data/nginx/html/magedu
[root@centos8 conf.d]# cat /data/nginx/html/magedu/daolian.html 
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.magedu.org/images/logo.png" >
<h1 style="color:red">欢迎大家</h1>
<p><a href=http://www.magedu.org>马哥教育</a>欢迎你</p>
</body>
</html>
#重启Nginx并访问http://www.mageedu.org/daolian.html 测试
#验证两个域名的日志,是否会在被盗连的web站点的日志中出现以下盗链日志信息:
[root@centos8 ~]#tail /apps/nginx/logs/magedu.org_access.log
10.0.0.1 - - [11/Oct/2020:09:50:07 +0800] "GET /images/logo.png HTTP/1.1" 200
5934 "http://www.mageedu.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 
Edg/86.0.622.38" "-"

3.2 实现防盗链

基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有
效实现防盗链功能
官方文档:

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

语法格式:

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;
   }

范例: 定义防盗链:

[root@centos8 ~]# vim /apps/nginx/conf/conf.d/pc.conf
server {
   index index.html;
   valid_referers none blocked server_names *.magedu.com *.magedu.org   
~\.google\. ~\.baidu\. ~\.bing\. ~\.so\. ~\.dogedoge\. ; #定义有效的
referer
    if ($invalid_referer) { #假如是使用其他的无效的referer访问
     return 403 "Forbidden Access"; #返回状态码403
   }
......
}
#重启Nginx并访问测试
#指定referer为http://www.baidu.com进行访问
[root@centos7 ~]# curl -e 'http://www.baidu.com' www.magedu.org
#指定referer为http://www.xxx.com进行访问,被拒绝
[root@centos7 ~]# curl -e 'http://www.xxx.com' www.magedu.org
#不加http的referer不会拒绝
[root@centos7 ~]# curl -e 'www.xxx.com' www.magedu.org

在被盗链的nginx服务器查看日志

[root@centos8 ~]#tail /apps/nginx/logs/magedu.org_access.log 
10.0.0.1 - - [11/Oct/2020:09:55:26 +0800] "GET /images/logo.png HTTP/1.1" 403 16
"http://www.mageedu.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 
Edg/86.0.622.38" "-"

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

4.1 介绍

轮询(默认)
weight (轮询权值)
ip_hash
fair
url_hash(第三方)

hash KEY [consistent];

#基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性
hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一
致性hash基于取模运算
#示例
hash $request_uri consistent; #基于用户请求的uri做hash

ip_hash;

#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计
算,以实现会话保持
#hash $remote_addr 则是对全部32bit的IPv4进行hash计算

least_conn;

#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC

基于 hash 的调度算法

马哥SRE第九周课程作业_第4张图片
添加节点后,会导致很多的调度的缓存信息失效

马哥SRE第九周课程作业_第5张图片
一致性hash 算法
大球是服务端hash取模后地址,小球是客户端hash取模后地址,客户端小球顺时针找到离他最近的大球
环节点不均匀哈希偏斜情况也是会出现的,但是可以把后端地址进行权重*1w计算,添加1w个随机数字对
1w个数字进行hash计算,每个节点都这么计算,4w个大圈就不会很偏斜
马哥SRE第九周课程作业_第6张图片
马哥SRE第九周课程作业_第7张图片

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

5.1 项目实战:利用LNMP实现可道云私有云

可道云,原名芒果云,是基于Web技术的私有云在线文档管理解决方案。Kod,读音通code,意为“代
码,编码”,中文名为“可道”。
官网: http://kodcloud.com/

5.1.1 环境说明

#部署规划:
10.0.0.100:CentOS8,Nginx,php-fpm,kodbox
10.0.0.8:CentOS8,MySQL8.0,Redis5.0

马哥SRE第九周课程作业_第8张图片

5.1.2 准备 MySQL 数据库

[root@centos8 ~]#yum -y install mysql-server
[root@centos8 ~]#systemctl enable --now mysqld
[root@centos8 ~]#mysql
mysql> create database kodbox;
Query OK, 1 row affected (0.00 sec)
mysql> create user kodbox@'10.0.0.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on kodbox.* to kodbox@'10.0.0.%';
Query OK, 0 rows affected (0.00 sec)

5.1.3 准备 Redis 服务

[root@centos8 ~]#yum -y install redis
[root@centos8 ~]#vim /etc/redis.conf
bind 0.0.0.0 #修改此行
[root@centos8 ~]#systemctl enable --now redis

5.1.4 准备 Nginx 服务

[root@centos7 ~]#yum -y install nginx
[root@centos7 ~]#mkdir -pv /data/html 
#创建配置文件
[root@centos7 ~]#vim /etc/nginx/conf.d/kod.conf
server {
   listen 80;
   server_name cloud.magedu.org;
   root /data/html;
   location / {
       index index.php index.html;
   }
   location ~ \.php$ {
       fastcgi_pass   127.0.0.1:9000;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
       include       fastcgi_params;
   }
}
[root@centos7 ~]#systemctl --now enabled nginx

5.1.5 CentOS8 php 支持 redis

#安装php相关包
[root@rocky8 ~]#yum -y install php-fpm php-mbstring php-json php-xml php-gd php
mysqlnd 
#修改fpm配置文件
[root@rocky8 ~]#vim /etc/php-fpm.d/www.conf
user = nginx
group = nginx
listen = 127.0.0.1:9000
#安装编译相关包
[root@rocky8 ~]#yum -y install php-cli php-devel
#编译redis模块
[root@rocky8 ~]#wget https://pecl.php.net/get/redis-5.3.7.tgz
[root@rocky8 ~]#tar xf redis-5.3.7.tgz
[root@rocky8 ~]#cd redis-5.3.7/
[root@rocky8 redis-5.3.7]#cat INSTALL
[root@rocky8 redis-5.3.7]#phpize
[root@rocky8 redis-5.3.7]#./configure
[root@rocky8 redis-5.3.7]#make -j 2 && make install
......
----------------------------------------------------------------------
Build complete.
Don't forget to run 'make test'.
Installing shared extensions:     /usr/lib64/php/modules/
[root@rocky8 ~]#ll /usr/lib64/php/modules/redis.so 
-rwxr-xr-x 1 root root 3530824 Feb 26 10:21 /usr/lib64/php/modules/redis.so
[root@rocky8 ~]#vim /etc/php.d/31-redis.ini
extension=redis
[root@rocky8 ~]#systemctl enable --now php-fpm
#测试连接
[root@rocky8 ~]#vim /data/html/redis.php 
connect('127.0.0.1', 6379);
   //$redis->auth('123456');
   echo "Connection to Redis sucessfully! ";
   //查看服务是否运行
   echo "Server is running: " . $redis->ping();
[root@rocky8 ~]#curl http://10.0.0.8/redis.php
Connection to server sucessfully! Server is running: 1

5.1.6 准备可道云程序

[root@centos7 ~]#wget 
https://static.kodcloud.com/update/download/kodbox.1.20.zip
[root@centos7 ~]#unzip kodbox.1.20.zip -d /data/html
[root@centos7 ~]#chown -R nginx.nginx /data/html

初始化和登录可道云

验证数据库和 session 信息

[root@centos8 ~]#redis-cli 
127.0.0.1:6379> keys *
1) "32b4b_UserModel_getInfoFull_ID_1"
2) "32b4b_SystemOption_System.taskList"
3) "32b4b_SystemOption_System.autoTask"
4) "32b4b_UserOption_User.noticeList_1"
5) "32b4b_UserFavModel_listData_ID_1"
6) "32b4b_UserOption_User.tagList_1"
....

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

6.1 安装 JumpServer

官方说明

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

6.2 安装要求

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.3 安装方法介绍

官方提供了多种安装方法
手动部署: 一步一步实现
极速部署: 资产数量不多,或者测试体验的用户请使用本脚本快速部署
容器部署: 基于docker 实现
分布式部署: 适用大型环境

6.4 基于容器部署

官方文档:

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

6.5 环境说明

https://github.com/jumpserver/Dockerfile/tree/master/allinone

使用外置 MySQL 数据库和 Redis:

- 外置数据库要求 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

6.6 安装 MySQL 服务

官方说明:

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

MySQL要求

create database jumpserver default charset 'utf8';
create user 'jumpserver'@'%' identified by 'nu4x599Wq7u0Bn8EABh3J91G';
grant all on jumpserver.* to 'jumpserver'@'%';
flush privileges; 

6.6.1 下载 MySQL 镜像查看默认配置

下载MySQL镜像并运行, 查看当前默认配置不符合JumpServer安装要求

#下载MySQL镜像并启动
[root@centos8 ~]#docker run --rm --name mysql -e MYSQL_ROOT_PASSWORD=123456 -e 
MYSQL_DATABASE=jumpserver -e MYSQL_USER=jumpserver -e MYSQL_PASSWORD=123456 -d -p 
3306:3306 mysql:5.7.30
#查看默认的MySQL容器配置不符合jumpserver要求
[root@centos8 ~]#docker exec -it mysql bash
root@f44e1c85f088:/# mysql -uroot -p123456
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)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
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 create database jumpserver;
+------------+------------------------------------------------------------------
-----+
| Database   | Create Database                                                   
    |
+------------+------------------------------------------------------------------
-----+
| jumpserver | CREATE DATABASE `jumpserver` /*!40100 DEFAULT CHARACTER SET 
latin1 */ |
+------------+------------------------------------------------------------------
-----+ 
1 row in set (0.01 sec)
mysql> select user,host from mysql.user;
+---------------+-----------+
| user         | host     |
+---------------+-----------+
| jumpserver   | %         |
| root         | %         |
| mysql.session | localhost |
| mysql.sys     | localhost |
| root         | localhost |
+---------------+-----------+ 
5 rows in set (0.00 sec)
mysql> exit
Bye
#查看配置文件路径
root@f44e1c85f088:/# cat /etc/mysql/mysql.cnf
......
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
#默认配置文件
root@f44e1c85f088:/# tree /etc/mysql/
/etc/mysql/
|-- conf.d
|   |-- docker.cnf
|   |-- mysql.cnf
|   `-- mysqldump.cnf
|-- my.cnf -> /etc/alternatives/my.cnf
|-- my.cnf.fallback
|-- mysql.cnf
`-- mysql.conf.d
    `-- mysqld.cnf
2 directories, 7 files
root@f44e1c85f088:/# ls -R /etc/mysql
/etc/mysql:
conf.d my.cnf my.cnf.fallback mysql.cnf mysql.conf.d
/etc/mysql/conf.d:
docker.cnf mysql.cnf mysqldump.cnf
/etc/mysql/mysql.conf.d:
mysqld.cnf
#默认配置文件
root@f44e1c85f088:/# grep '^[^#]' /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
symbolic-links=0 
#默认配置文件
root@f44e1c85f088:/# cat /etc/mysql/conf.d/mysql.cnf 
[mysql]
root@f44e1c85f088:/# exit
exit
[root@centos8 ~]#docker stop mysql

6.6.2 在宿主机准备MySQL配置文件

#准备相关目录
[root@centos8 ~]#mkdir -p /etc/mysql/mysql.conf.d/
[root@centos8 ~]#mkdir -p /etc/mysql/conf.d/
#生成服务器配置文件,指定字符集
[root@centos8 ~]#tee /etc/mysql/mysql.conf.d/mysqld.cnf <
[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@centos8 ~]#tee /etc/mysql/conf.d/mysql.cnf <
[mysql]
default-character-set=utf8  #添加此行,指定字符集
EOF
#查看配置文件列表
[root@centos8 ~]#tree /etc/mysql/
/etc/mysql/
├── conf.d
│   └── mysql.cnf
└── mysql.conf.d
   └── mysqld.cnf
2 directories, 2 files

6.6.4 启动 MySQL 容器

将上面宿主机的设置好的配置文件挂载至MySQL容器
[root@centos8 ~]#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.7 安装 Redis 服务

官方说明

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

新版要求:

外置 Redis 要求 Redis 版本大于等于 6.0

启动 Redis

[root@centos8 ~]#docker run -d -p 6379:6379 --name redis --restart always 
redis:5.0.9
2b75e77aa35b79dcb0e4cffb41d124c10124cdfda959e3131f7927e8808f9417

6.8 部署 JumpServer

生成 key 和 token
参考官方说明:

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

需要先生成 key 和 token

[root@centos8 ~]#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
[root@centos8 ~]#bash key.sh 
[root@centos8 ~]#tail -n2 .bashrc
SECRET_KEY=9RTRBg3AjHjvUUNCUpHUH5LirSFazRozk1UyOQcoKkwMExeUEm
BOOTSTRAP_TOKEN=1OlaSdCoUpSQPjH6

6.8.1 运行容器

范例: jumpserver 2.5.3版

[root@centos8 ~]#docker run --name jms_all -d \
  -v /opt/jumpserver/data:/opt/jumpserver/data \
  -p 80:80 \
  -p 2222:2222 \
  --restart always \
  -e SECRET_KEY=9RTRBg3AjHjvUUNCUpHUH5LirSFazRozk1UyOQcoKkwMExeUEm \
  -e BOOTSTRAP_TOKEN=1OlaSdCoUpSQPjH6 \
  -e DB_HOST=10.0.0.18 \ #不支持127.0.0.1
  -e DB_PORT=3306 \
  -e DB_USER=root \
  -e DB_PASSWORD=123456 \
  -e DB_NAME=jumpserver \
  -e REDIS_HOST=127.0.0.1 \
  -e REDIS_PORT=6379 \
  -e REDIS_PASSWORD='' \
  --privileged=true \
 jumpserver/jms_all:v2.5.3
#初次启动容器需要等待一会儿才能完成

关于用户授权、审计我这有现成的模板就省略页面的配置了

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

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

  • 哪些是垃圾要回收
  • 怎么回收垃圾
  • 什么时候回收垃圾

标记-清除 Mark-Sweep
标记-压缩 (压实)Mark-Compact
复制 Copying

上述垃圾回收算法都有优缺点,能不能对不同数据进行区分管理,不同分区对数据实施不同回收策略,
分而治之。
堆内存分代
将heap内存空间分为三个不同类别: 年轻代、老年代、持久代

内存空间优化

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

生产案例:(提前给4G,防止一点点申请带来额外的开销)

[root@centos8 ~]#vim /usr/local/tomcat/bin/catalina.sh
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g -
XX:CMSInitiatingOccupancyFraction=65 -XX:+AggressiveOpts -XX:+UseBiasedLocking -
XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -
XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -
XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -
XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -
XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods"
#一台tomcat服务器并发连接数不高,生产建议分配物理内存通常4G到8G较多,如果需要更多连接,一般会利用
虚拟化技术实现多台tomcat

线程池调整

[root@centos8 ~]#vim /usr/local/tomcat/conf/server.xml
......
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" />

常用属性:

  • 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

八. tomcat实现java应用发布。

利用nginx实现动静分离代理

vim nginx.conf
root /usr/share/nginx/html;
#下面行可不加
#location / {
# root /data/webapps/ROOT;
# index index.html;
#}
# ~* 不区分大小写
location ~* \.jsp$ {
proxy_pass http://node1.magedu.com:8080;://node1.magedu.com:8080; #注
改 /etc/hosts
}

以上设置,可以将jsp的请求反向代理到tomcat,而其它文件仍由nginx处理,从而实现所谓动静分离。但由于jsp文件中实际上是由静态资源和动态组成,所以无法彻底实现动静分离。实际上Tomcat不太适合做动静分离,用它来管理程序的图片不好做动静分离部署

实战案例
#准备三个不同的资源文件
[root@centos8 ~]#echo /usr/local/tomcat/webapps/ROOT/test.html >
/usr/local/tomcat/webapps/ROOT/test.html
[root@centos8 ~]#echo /usr/local/tomcat/webapps/ROOT/test.jsp >
/usr/local/tomcat/webapps/ROOT/test.jsp
[root@centos8 ~]#echo /usr/share/nginx/html/test.html >
/usr/share/nginx/html/test.html
[root@centos8 ~]#vim /etc/nginx/nginx.conf
......
root /usr/share/nginx/html;
#location / {
#
#}
location ~* \.jsp$ {
proxy_pass http://127.0.0.1:8080;
}
......
[root@centos8 ~]#systemctl restart nginx
#访问test.html,观察结果都一样访问的是nginx自身的资源
[root@centos8 ~]#curl http://node1.magedu.org/test.html
[root@centos8 ~]#curl http://node2.magedu.org/test.html
[root@centos8 ~]#curl http://127.0.0.1/test.html
[root@centos8 ~]#curl http://10.0.0.8/test.html
/usr/share/nginx/html/test.html
#访问test.jsp,观察结果都一样访问的是tomcat的默认主机资源
[root@centos8 ~]#curl http://node1.magedu.org/test.jsp
[root@centos8 ~]#curl http://node2.magedu.org/test.jsp
[root@centos8 ~]#curl http://127.0.0.1/test.jsp
[root@centos8 ~]#curl http://10.0.0.8/test.jsp
/usr/local/tomcat/webapps/ROOT/test.jsp

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

ticky 模式工作原理
sticky 模式即前端tomcat和后端memcached有关联(粘性)关系

参考文档:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

马哥SRE第九周课程作业_第9张图片
t1和m1部署可以在一台主机上,t2和m2部署也可以在同一台。
当新用户发请求到Tomcat1时, Tomcat1生成session返回给用户的同时,也会同时发给memcached2备份。即Tomcat1 session为主session,memcached2 session为备用session,使memcached相当于备份了一份Session
如果Tomcat1发现memcached2 失败,无法备份Session到memcached2,则将Sessoin备份存放在
memcached1中

下载相关jar包
下载相关jar包,参考下面官方说明的下载链接

https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

tomcat和memcached相关包
马哥SRE第九周课程作业_第10张图片
马哥SRE第九周课程作业_第11张图片

#以下是sticky的配置
<Context>
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:10.0.0.101:11211,n2:10.0.0.102:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFac
tory"
/>
</Context>

配置说明
memcachedNodes=“n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211”
memcached的节点: n1、n2只是别名,可以重新命名。
failoverNodes 为故障转移节点,n1是备用节点,n2是主存储节点。另一台Tomcat将此处的n1改为n2,其主节点是n1,备用节点是n2。

如果配置成功,可以在logs/catalina.out中看到下面的内容

12-APR-2020 16:24:08.975 INFO [t1.magedu.com-startStop-1]
de.javakaffee.web.msm.MemcachedSessionService.startInternal --------
- finished initialization:
- sticky: true
- operation timeout: 1000
- node ids: [n2]
- failover node ids: [n1]
- storage key prefix: null
- locking mode: null (expiration: 5s)

配置成功后,网页访问以下,页面中看到了Session。然后运行下面的Python程序,就可以看到是否存
储到了memcached中了。

准备测试msm的python脚本

安装python环境准备python程序查看memcached中的SessionID
[root@centos8 ~]#yum -y install python3 python3-memcached
#或者执行下面两步
[root@centos8 ~]#dnf install python3 -y
[root@centos8 ~]#pip3 install python-memcached
#脚本内容
[root@centos8 ~]#cat showmemcached.py
#!/usr/bin/python3
import memcache
mc = memcache.Client(['10.0.0.101:11211'], debug=True)
stats = mc.get_stats()[0]
print(stats)
for k,v in stats[1].items():
print(k, v)
print('-' * 30)
# 查看全部key
print(mc.get_stats('items')) # stats items 返回 items:5:number 1
print('-' * 30)
print(mc.get_stats('cachedump 5 0')) # stats cachedump 5 0 # 5和上面的items返回的值
有关;0表示全部

t1、t2、n1、n2依次启动成功,分别使用http://t1.magedu.org:8080/ 和http://t2.magedu.org:8080/
观察。
开启负载均衡调度器,通过http://proxy.magedu.com来访问看看效果

On tomcats
10.0.0.102:8080
SessionID = 2A19B1EB6D9649C9FED3E7277FDFD470-n2.Tomcat1
Wed Jun 26 16:32:11 CST 2019
On tomcats
10.0.0.101:8080
SessionID = 2A19B1EB6D9649C9FED3E7277FDFD470-n1.Tomcat2
Wed Jun 26 16:32:36 CST 2019

可以看到浏览器端被调度到不同Tomcat上,但是都获得了同样的SessionID。
停止t2、n2看看效果,恢复看看效果。
范例:访问tomcat,查看memcached中SessionID信息
马哥SRE第九周课程作业_第12张图片

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

Redis session manager 是一个插件。 它将会话存储到 Redis 中,以便在 Tomcat 服务器集群中轻松分
发 HTTP 请求。
在这里,会话被实现为非粘性(意味着,每个请求都可以转到集群中的任何服务器,这与 Apache 提供的 Tomcat 集群设置不同。)
请求Sessions会立即存入Redis(Session属性必须是Serializable),供其他服务器使用。 当 tomcat 收到客户端的请求时,Sessions 直接从 Redis 加载。从而无需在负载均衡器中启用粘性会话(JSESSIONID)。
支持Redis默认、哨兵和集群模式,基于配置。
参考文档

https://github.com/ran-jit/tomcat-cluster-redis-session-manager

#下载相关文件并解压缩
wget https://github.com/ran-jit/tomcat-cluster-redis-session
manager/releases/download/3.0.1.1/tomcat-cluster-redis-session-manager.zip
unzip /opt/tomcat-cluster-redis-session-manager.zip -d /opt
#复制jar包到tomcat/lib目录中
cp /opt/tomcat-cluster-redis-session-manager/lib/* /usr/local/tomcat/lib/
chown -R tomcat.tomcat /usr/local/tomcat/lib
#复制redis配置文件到tomcat/conf目录中
cp /opt/tomcat-cluster-redis-session-manager/conf/redis-data-cache.properties
/usr/local/tomcat/conf/
#修改redis配置信息
vim /usr/local/tomcat/conf/redis-data-cache.properties
#修改下面两行
redis.hosts=10.0.0.100:6379 #指向redis服务器地址
redis.password=123456
#添加两行配置文件在 tomcat/conf/context.xml
vim /usr/local/tomcat/conf/context.xml
#在最后一行前加下两行
<Valve className="tomcat.request.session.redis.SessionHandlerValve" />
<Manager className="tomcat.request.session.redis.SessionManager" />
</Context> #此是最后一行
#修改session过期时间为60m,默认30m,此步可选
vim /usr/local/tomcat/conf/web.xml
<session-config>
<session-timeout>60</session-timeout>
</session-config>
#重启服务
systemctl restart tomcat
#nginx配置反向代理和均衡负载
vim /etc/nginx/conf.d/session.conf
upstream tomcat-server {
server t1.magedu.org:8080;
server t2.magedu.org:8080;
}
server {
listen 80;
server_name www.magedu.org;
location / {
proxy_pass http://tomcat-server;
proxy_set_header Host $http_host;
}
}
#tomcat测试页面
cat /data/webapps/ROOT/test.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<h1> Tomcat1 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>

你可能感兴趣的:(linux,马哥SRE作业,tomcat,nginx,java)