第九周作业
-
-
nginx实现动静分离。
-
nginx实现防盗链功能。
-
解析nginx常见的负载均衡算法。
-
基于LNMP完成搭建任意一种应用。
-
jumpserver 总结安装部署,添加用户授权,行为审计。
-
JVM垃圾回收原理,JVM调优。
-
tomcat实现java应用发布。
-
实现tomcat session粘性,并验证过程。
1、配置nginx https
server { listen 80; listen 443 ssl; root /var/www/; server_name localhost; ssl_certificate 证书文件.crt; ssl_certificate_key 证书文件.key; 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; } }
2、开启https
killall nginx
nginx
3、nginx强制http跳转到https的配置文件
#先监听80端口,为http请求,然后强制转发到https监听的443端口上面 server { listen 80; root path; server_name www.exp.com; rewrite ^(.*) https://$server_name$1 permanent; } #监听443端口,https请求 server { listen 443 ssl; root path; server_name www.exp.com; ssl_certificate 证书文件.crt; ssl_certificate_key 证书文件.key; #此段代码为rapidPHP单一入库配置,不是rapidPHP框架请忽略 #location / { # if (!-e $request_filename){ # rewrite ^(.*)$ /index.php?__ROUTE__=$1 last; # } #} 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; } }
配置完成重启nginx即可
1.1 动态页面与静态页面区别
- 静态资源: 当用户多次访问这个资源,资源的源代码永远不会改变的资源。
- 动态资源:当用户多次访问这个资源,资源的源代码可能会发送改变。
1.2 什么是动静分离
- 动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路
- 动静分离简单的概括是:动态文件与静态文件的分离。
- 伪静态:网站如果想被搜索引擎搜素到,动态页面静态技术freemarker等模版引擎技术
1.3 为什么要用动静分离
- 在我们的软件开发中,有些请求是需要后台处理的(如:.jsp,.do等等),有些请求是不需要经过后台处理的(如:css、html、jpg、js等等文件),这些不需要经过后台处理的文件称为静态文件,否则动态文件。因此我们后台处理忽略静态文件。这会有人又说那我后台忽略静态文件不就完了吗。当然这是可以的,但是这样后台的请求次数就明显增多了。在我们对资源的响应速度有要求的时候,我们应该使用这种动静分离的策略去解决。
- 动静分离将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问。这里我们将静态资源放到nginx中,动态资源转发到tomcat服务器中。
- 因此,动态资源转发到tomcat服务器我们就使用到了前面讲到的反向代理了。
2.1 架构分析

2.2 配置
动静分离的原理很简单,通过location对请求url进行匹配即可,在/Users/Hao/Desktop/Test(任意目录)下创建 /static/imgs 配置如下:
###静态资源访问 server { listen 80; server_name static.haoworld.com; location /static/imgs { root /Users/Hao/Desktop/Test; index index.html index.htm; } } ###动态资源访问 server { listen 80; server_name www.haoworld.com; location / { proxy_pass http://127.0.0.1:8080; index index.html index.htm; } }
3.动静分离与前后分离区别:
- 动静分离动态资源与静态资源分离,不会部署在同一台服务器上。
- 前后分离:网站架构模式,微服务开发基于
SOA面向于服务器开发,后台和前端都采用调用接口方式。将一个项目拆分成一个控制Web(前端)和接口(后端),最终使用rpc远程调用技术。视图层和业务逻辑层拆分,中间采用RPC远程调用技术
一:一般的防盗链如下: location ~* \.(gif|jpg|png|swf|flv)$ { valid_referers none blocked www.jzxue.com jzxue.com ; if ($invalid_referer) { rewrite ^/ http://www.jzxue.com/retrun.html; #return 403; } } 第一行:gif|jpg|png|swf|flv 表示对gif、jpg、png、swf、flv后缀的文件实行防盗链 第二行: 表示对www.ingnix.com这2个来路进行判断 if{}里面内容的意思是,如果来路不是指定来思是,如果来路不是指定来路就跳转到http://www.jzxue.com/retrun.html页面,当然直接返回403也是可以的。 二:针对图片目录防止盗链 location /images/ { alias /data/images/; valid_referers none blocked server_names *.xok.la xok.la ; if ($invalid_referer) {return 403;} } 三:使用第三方模块ngx_http_accesskey_module实现Nginx防盗链 实现方法如下: 1. 下载NginxHttpAccessKeyModule模块文件:http://wiki.nginx.org/File:Nginx-accesskey-2.0.3.tar.gz; 2. 解压此文件后,找到nginx-accesskey-2.0.3下的config文件。编辑此文件:替换其中的”$HTTP_ACCESSKEY_MODULE”为”ngx_http_accesskey_module”; 3. 用一下参数重新编译nginx: ./configure --add-module=path/to/nginx-accesskey <<pestd add 上面需要加上原有到编译参数,然后执行: make && make install 修改nginx的conf文件,添加以下几行: location /download { accesskey on; accesskey_hashmethod md5; accesskey_arg "key"; accesskey_signature "mypass$remote_addr"; } 其中: accesskey为模块开关; accesskey_hashmethod为加密方式MD5或者SHA-1; accesskey_arg为url中的关键字参数; accesskey_signature为加密值,此处为mypass和访问IP构成的字符串。 访问测试脚本download.php: <? $ipkey= md5("mypass".$_SERVER['REMOTE_ADDR']); $output_add_key="<a href=http://www.jzxue.com/download/G3200507120520LM.rar?key=".$ipkey.">download_add_key</a><br />"; $output_org_url="<a href=http://www.jzxue.com/download/G3200507120520LM.rar>download_org_path</a><br />"; echo $output_add_key; echo $output_org_url; ?> 访问第一个download_add_key链接可以正常下载,第二个链接download_org_path会返回403 Forbidden错误。
Nginx负载均衡算法 1、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。 例如: upstream bakend { server 192.168.0.1; server 192.168.0.2; } 2、weight(轮询权值) weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如: upstream bakend { server 192.168.0.1 weight=10; server 192.168.0.2 weight=10; } 3、ip_hash 每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 例如: upstream bakend { ip_hash; server 192.168.0.1:88; server 192.168.0.2:80; } 4、fair(第三方) 比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。 按后端服务器的响应时间来分配请求,响应时间短的优先分配。 例如: upstream backend { server 192.168.0.1:88; server 192.168.0.2:80; fair; } 5、url_hash(第三方) 按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 注意:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。 例如: upstream backend { server 192.168.0.1:88; server 192.168.0.2:80; hash $request_uri; hash_method crc32; }
LNMP平台搭建与应用
1.LNMP架构概述
LNMP就是Linux+Nginx+MySQL+PHP,Linux作为服务器的操作系统、Nginx作为web服务器、PHP作为解析动态脚本语言、MySQL即为数据库
Linux作为服务器的操作系统
Nginx作为WebServer服务器
PHP作为动态解析服务,也不只是php还有python、perl
MySQL作为后端存储数据库服务
Nginx服务本身不能处理PHP请求,那么当用户发起PHP动态请求,PHP是这样处理的
用户—>http协议—>nginx—>fastcgi协议—>php-fpm
注意fastcgi是nginx连接php-fpm之间的协议
Nginx解析php的方法
1.将PHP页面的解析请求通过代理方式转发给Apache进行处理
将PHP页面的解析请求转发给php-fpm模块
1.1.LNMP架构图
1.2.Nginx与Fast_CGI详细工作流程

1.用户通过http协议发起请求,请求会先抵达LNMP架构中的Nginx 2.Nginx会根据用户的请求进行判断,这个判断会通过定义的location完成,例如图片、文件会去找ftp服务,php会去找php-fpm 3.判断用户请求的是否是静态页面,如果是静态页面Nginx会直接处理 4.判断用户请求的是否是动态页面,如果是动态页面,Nginx会将该请求交给fastcgi协议进行下发 5.fastcgi会将请求交给php-fpm管理进程,php-fpm管理进程接收到后调用具体的工作线程wrapper,类似于工单,每当工作来临时,php-fpm就会进行分配 6.wapper线程会调用php进行解析,如果只是解析代码,PHP解析完会自动返回 7.如果有查询数据库操作,则由php连接数据库(通过用户、密码、IP)进行连接然后发起查询操作 8.最终数据由mysql--->php--->php-fpm--->fastcgi--->nginx--->http--->user
2.安装LNMP架构
2.1.安装Nginx
使用官方提供的rpm包 [root@localhost ~]# cat /etc/yum.repos.d/nginx.repo [nginx] name=nginx baseurl=http://nginx.org/packages/centos/7/$basearch enabled=1 gpgcheck=0 yum安装 [root@localhost ~]# yum -y install nginx 启动 [root@localhost ~]# systemctl start nginx [root@localhost ~]# systemctl enable nginx 扩展 1.仅下载rpm包不进行安装,如果想安装并下载那么就把--downloadonly去掉 [root@localhost ~]# yum -y install nginx --downloadonly --downloaddir=/soft 在使用rpm安装,可以留着等下次做实例的时候用 [root@localhost soft]# rpm -ivh nginx-1.16.1-1.el7.ngx.x86_64.rpm 2.我们在官网系在了nginx的rpm包可能会存在依赖关系 [root@localhost ~]# yum -y localinstall nginx-1.16.1-1.el7.ngx.x86_64.rpm
2.2.安装MySQL
- mysql有两个版本可以选择一个5.6一个是5.7我们都来做一遍
- mysql所有功能都是修改配置文件实现的
2.2.1.安装MySQL5.7
1.下载MySQL官方扩展源 [root@localhost ~]# rpm -ivh http://repo.mysql.com/yum/mysql-5.7-community/el/7/x86_64/mysql57-community-release-el7-10.noarch.rpm 也可以使用wget下载下来方便以后使用 [root@localhost ~]# wgt http://repo.mysql.com/yum/mysql-5.7-community/el/7/x86_64/mysql57-community-release-el7-10.noarch.rpm 2.安装完mysqlrpm后会在/etc/yum.repos.d中生成两个文件 root@localhost ~]# ls /etc/yum.repos.d/my* /etc/yum.repos.d/mysql-community.repo /etc/yum.repos.d/mysql-community-source.repo 3.安装mysql5.7 把mysql5.7包下载下来,然后方便下次使用 首先配置yum,开启缓存,不然安装好后就会自动删除 [root@localhost conf.d]# vim /etc/yum.conf keepcache=1 [root@localhost ~]# yum install mysql-community-server --downloaddir=/root/soft/ --downloadonly 在使用localinstall安装(也可以用rpm直接装) [root@localhost soft]# yum -y localinstall mysql-community-server-5.7.29-1.el7.x86_64.rpm 4.启动 [root@localhost soft]# systemctl start mysqld [root@localhost soft]# systemctl enable mysqld 5.由于mysql5.7默认配置了密码,需要在日志中过滤temporary password获取默认密码 [root@localhost soft]# grep "temporary password" /var/log/mysqld.log 2020-04-10T04:01:09.027390Z 1 [Note] A temporary password is generated for root@localhost: *2cNf4-Gh:oe 6.登录 [root@localhost ~]# mysql -u root -p*2cNf4-Gh:oe [root@localhost ~]# mysql -uroot -p$(awk '/temporary password/{print $NF}' /var/log/mysqld.log) 7.修改密码,密码必须是8位以上包含数字大小写字母 mysql> alter user 'root'@'localhost' identified by '1234.COm';
2.2.2.安装MySQL5.6
1.下载MySQL官方扩展源 [root@localhost ~]# rpm -ivh http://repo.mysql.com/yum/mysql-5.6-community/el/7/x86_64/mysql-community-release-el7-5.noarch.rpm 2.安装完mysqlrpm后会在/etc/yum.repos.d中生成两个文件 root@localhost ~]# ls /etc/yum.repos.d/my* /etc/yum.repos.d/mysql-community.repo /etc/yum.repos.d/mysql-community-source.repo 3.安装mysql5.6 把mysql5.6包下载下来,然后方便下次使用(有条件的可以直接yum装) 首先配置yum,开启缓存,不然安装好后就会自动删除 [root@localhost conf.d]# vim /etc/yum.conf keepcache=1 [root@localhost ~]# yum install mysql-community-server --downloaddir=/root/soft/ --downloadonly [root@localhost ~]# ls soft/ mysql-community-client-5.6.47-2.el7.x86_64.rpm mysql-community-libs-5.6.47-2.el7.x86_64.rpm mysql-community-common-5.6.47-2.el7.x86_64.rpm mysql-community-server-5.6.47-2.el7.x86_64.rpm 在使用localinstall安装 [root@localhost soft]# yum -y localinstall *.rpm 或者 [root@localhost soft]# yum -y localinstall mysql-community-server-5.7.29-1.el7.x86_64.rpm 如果网速不好则用rpm安装,安装顺序如下 [root@localhost soft]# rpm -ivh mysql-community-common-5.6.47-2.el7.x86_64.rpm [root@localhost soft]# rpm -ivh mysql-community-libs-5.6.47-2.el7.x86_64.rpm [root@localhost soft]# rpm -ivh mysql-community-client-5.6.47-2.el7.x86_64.rpm [root@localhost soft]# rpm -ivh mysql-community-server-5.6.47-2.el7.x86_64.rpm 4.启动 [root@localhost soft]# systemctl start mysqld [root@localhost soft]# systemctl enable mysqld 5.登录 [root@localhost ~]# mysql 6.修改密码 [root@localhost ~]# mysqladmin -u root password 123 Warning: Using a password on the command line interface can be insecure. //这个提示表示密码太短 如果想改密码可以这样操作 [root@localhost ~]# mysqladmin -u root -p123 password 1234 上条没有没有加-p表示mysql没有密码因为是首次安装 下面这条加了-p表示指定之前的密码 7.其他服务器远程连接mysql 首先在mysql服务器执行: mysql> grant all privileges on *.* to 'root'@'%' identified by '123' with grant option; mysql> flush privileges; 远程主机 mysql -uroot -p123 -h 192.168.81.210
2.3.安装PHP
- 使用第三方扩展源安装php7.1
1.删除之前系统安装的php [root@localhost php]# yum remove php-mysql-5.4 php php-fpm php-common 2.安装扩展源 [root@localhost php]# wget http://mirror.webtatic.com/yum/el7/webtatic-release.rpm [root@localhost php]# yum -y localinstall webtatic-release.rpm 3.安装php7.1 如果https访问不到那么久在安装之前把/etc/yum.repos.d/webtatic.repo,把里面的https改成http,例如:mirrorlist=http://mirror.webtatic.com/yum/el7/SRPMS/mirrorlist 把rpm包下载到指定目录,方便下次使用,共计25个包 首先配置yum,开启缓存,不然安装好后就会自动删除 [root@localhost conf.d]# vim /etc/yum.conf keepcache=1 [root@localhost soft]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb --downloaddir=/root/soft/ --downloadonly [root@localhost soft]# yum -y localinstall *.rpm 4.启动 [root@localhost soft]# systemctl start php-fpm [root@localhost soft]# systemctl enable php-fpm Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service. 5.查看端口,到此完成 [root@localhost soft]# ss -lnptu | grep nginx tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=7375,fd=12),("nginx",pid=7374,fd=12)) [root@localhost soft]# ss -lnptu | grep mysql tcp LISTEN 0 80 :::3306 :::* users:(("mysqld",pid=20862,fd=10)) [root@localhost soft]# ss -lnptu | grep php tcp LISTEN 0 128 127.0.0.1:9000 *:* users:(("php-fpm",pid=23602,fd=9),("php-fpm",pid=23601,fd=9),("php-fpm",pid=23600,fd=9),("php-fpm",pid=23599,fd=9),("php-fpm",pid=23598,fd=9),("php-fpm",pid=23595,fd=7)) 没有网络的情况下,把所有的PHP的rpm包拷到服务器,执行php_install.sh即可
3.验证LNMP是否可用
3.1.Nginx解析php页面
- 验证nginx是否能正常解析php动态请求,以及php程序是否正常连接数据库
- 小技巧:location /{}中配置内容可以直接写在server中
1.配置server [root@localhost conf.d]# vim php.conf server { listen 80; server_name phptest.com; root /web/phptest; index index.php index.html; location ~ \.php$ { root /web/phptest; fastcgi_pass 127.0.0.1:9000; //fastcgi调用php-fpm fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; //$document_root表示/etc/nginx也就是nginx安装目录 include fastcgi_params; //引入fastcgi脚本,这个include表示上级目录也可以写绝对路径 } } 2.写入php页面 [root@localhost conf.d]# vim /web/phptest/index.php <?php phpinfo(); ?> 3.重载nginx [root@localhost conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@localhost conf.d]# systemctl reload nginx

3.2.PHP连接MySQL
直接在站点目录下面写一个php文件即可,不需要重载 [root@bogon phptest]# vim mysqltest.php <?php $servername = "localhost"; $username = "root"; $password = "123"; //创建链接 $conn = mysqli_connect($servername, $username, $password); //检测连接 if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } echo "连接成功" ?>

3.3.扩展方式加主机头访问
- 不写全网站根目录即可
server { listen 80; server_name php.com; location / { root /web; index index.php; } location ~ \.php$ { root /web; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
4.部署WordPress博客站点
4.1.配置WordPress站点
[root@localhost conf.d]# vim wordpress.conf #wordpress server { listen 80; server_name jiangxl.wordpress.com; location / { root /web/wordpress; index index.php index.html; } location ~ \.php$ { root /web/wordpress; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILRNAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } } [root@localhost conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@localhost conf.d]# systemctl reload nginx
4.2.部署WordPress源码
wget https://cn.wordpress.org/wordpress-4.9.4-zh——CN.tar.gz 由于网站登录失败,因此我从第三方下载了wordpress-5.2.3-zh_CN.zip,上传到/web目录 解包 [root@bogon web]# mkdir /web [root@bogon web]# cd /web [root@bogon web]# unzip wordpress-5.2.3-zh_CN.zip
到此WordPress站点可以访问到安装界面

4.3.配置MySQL
-
wordpress会用到后台数据库,因为博客肯定是需要上传文章附件等等,不配置数据库页面显示如下

需要手动创建数据库,开始配置mysql
[root@localhost conf.d]# mysql -uroot -p123 mysql> create database wordpress; Query OK, 1 row affected (0.00 sec) mysql> exit
4.4.配置网站属主
- 默认nginx的所属用户时nginx,nginx用户对/web/wordpress没有写入权限,因此会无法生成wp-config.php文件,因此我们需要修改网站属主

- nginx也要修改程序用户,让通过nginx访问页面的用户具有写权限
- 同样php-fpm也要修改程序用户,让通过访问php页面的用户具有写权限
- 小技巧,搞架构记得程序所属用户设置成一样的,开始配置
[root@localhost conf.d]# groupadd -g 888 www [root@localhost conf.d]# useradd -u 888 -g 888 www [root@localhost conf.d]# chown -R www.www /web/wordpress 修改nginx所属用户 [root@localhost conf.d]# sed -ri '/^user/c user www;' ../nginx.conf 重载让日志生效 [root@localhost conf.d]# systemctl reload nginx 修改php-fpm所属用户 www.conf是他的模板文件,主配置文件是php-fpm.conf、php.ini [root@localhost conf.d]# sed -ri '/^user/c user = www' /etc/php-fpm.d/www.conf [root@localhost conf.d]# sed -ri '/^group/c group = www' /etc/php-fpm.d/www.conf 重启让日志生效 [root@localhost conf.d]# systemctl restart php-fpm
4.5.页面安装
4.5.1.开始安装

4.5.2.填写数据库信息

4.5.3.确认安装
- 这一步就生成了wp-config.php文件


4.5.4.配置后台
4.5.5.安装完成

5.部署wecenter知乎系统
5.1.配置wecenter站点
[root@localhost conf.d]# vim wecenter.conf #wecenter server { listen 80; server_name jxl.wecenter.com; root /web/wecenter; index index.php index.html; location ~ \.php$ { root /web/wecenter; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } [root@localhost conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@localhost conf.d]# systemctl reload nginx
5.2.部署wecenter源码
[root@jxl web]# unzip -d wecenter WeCenter_3-3-4.zip [root@jxl web]# chown -R www:www /web/
5.3.配置数据库
创建wecenter数据库就行 [root@localhost web]# mysql -uroot -p123 mysql> create database wecenter; Query OK, 1 row affected (0.00 sec) mysql> exit Bye
5.4.页面安装
5.4.1.服务器环境检测

6.4.2.配置数据库

6.4.3.添加后台管理员

6.4.4.安装完成

6.4.5.网站首页

6.4.6.登录后台

一、介绍 Jumpserver 是全球首款完全开源的堡垒机, 使用 GNU GPL v2.0 开源协议, 是符合 4A 的专业运维审计系统。 Jumpserver 使用 Python / Django 进行开发, 遵循 Web 2.0 规范, 配备了业界领先的 Web Terminal 解决方案, 交互界面美观、用户体验好。 Jumpserver 采纳分布式架构, 支持多机房跨区域部署, 中心节点提供 API, 各机房部署登录节点, 可横向扩展、无并发访问限制。 Jumpserver 现已支持管理 SSH、 Telnet、 RDP、 VNC 协议资产。 二、主要功能 用户管理:用户管理模块,负责添加修改删除用户,把用户划分不同的用户组,方便将来授权主机. 资产管理:资产管理模块,负责管理各类资产,采纳资产数方便组织和授权. 授权管理:授权管理模块,以资产树方式授权资产,效率高 日志审计:日志审计模块,监控用户操作,统计用户操作记录,可中断用户不良危险操作. 三、安装方法 1、环境准备 CPU: 64位双核处理器 内存: 4G DDR3 数据库:mysql 版本大于等于 5.6 mariadb 版本大于等于 5.5.6 系统: CentOS 7 IP:192.168.100.144 2、设置防火墙和Selinux $ firewall-cmd --zone=public --add-port=80/tcp --permanent # nginx 端口 $ firewall-cmd --zone=public --add-port=2222/tcp --permanent # 用户SSH登录端口 coco $ firewall-cmd --reload # 重新载入规则 $ setenforce 0 $ sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # 修改字符集, 否则可能报 input/output error的问题, 因为日志里打印了中文 $ localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 $ export LC_ALL=zh_CN.UTF-8 $ echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf 3、准备python3和python虚拟环境 3.1、安装依赖包 $ yum -y install wget gcc epel-release git 3.2、安装Python3.6 $ yum -y install python36 python36-devel # 如果下载速度很慢, 可以换国内源 $ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo $ yum -y install python36 python36-devel 3.3 建立python虚拟环境 $ cd /opt $ python3.6 -m venv py3 $ source /opt/py3/bin/activate # 看到下面的提示符代表成功, 以后运行 Jumpserver 都要先运行以上 source 命令, 以下所有命令均在该虚拟环境中运行 (py3) [root@localhost py3] 4、安装Jumpserver 4.1、项目提交较多 git clone 时较大, 你可以选择去 Github 项目页面直接下载zip包。 $ cd /opt/ $ git clone --depth=1 https://github.com/jumpserver/jumpserver.git 4.2、安装依赖RPM包 $ cd /opt/jumpserver/requirements $ yum -y install $(cat rpm_requirements.txt) # 如果没有任何报错请继续 4.3、安装Python库依赖 $ yum instatll python-pip $ pip install --upgrade pip setuptools $ pip install -r requirements.txt # 如果下载速度很慢, 可以换国内源 $ pip install --upgrade pip setuptools -i https://mirrors.aliyun.com/pypi/simple/ $ pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ 5、安装Redis,用来做cache和celery broke $ yum -y install redis $ systemctl enable redis $ systemctl start redis 6、安装Mysql,创建Jumpserver数据库 $ yum -y install mariadb mariadb-devel mariadb-server # centos7下安装的是mariadb $ systemctl enable mariadb $ systemctl start mariadb 创建Jumpserver数据库并授权 $ DB_PASSWORD=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 24` # 生成随机数据库密码 $ echo -e "\033[31m 你的数据库密码是 $DB_PASSWORD \033[0m" 你的数据库密码是 1uqXf7Ve79gDTdUEFhURgKLe $ mysql -uroot -e "create database jumpserver default charset 'utf8'; grant all on jumpserver.* to 'jumpserver'@'127.0.0.1' identified by '$DB_PASSWORD'; flush privileges;" 7、修改Jumpserver的配置文件 $ cd /opt/jumpserver $ cp config_example.yml config.yml $ SECRET_KEY=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 50` # 生成随机SECRET_KEY $ echo "SECRET_KEY=$SECRET_KEY" >> ~/.bashrc $ BOOTSTRAP_TOKEN=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16` # 生成随机BOOTSTRAP_TOKEN $ echo "BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN" >> ~/.bashrc $ sed -i "s/SECRET_KEY:/SECRET_KEY: $SECRET_KEY/g" /opt/jumpserver/config.yml $ sed -i "s/BOOTSTRAP_TOKEN:/BOOTSTRAP_TOKEN: $BOOTSTRAP_TOKEN/g" /opt/jumpserver/config.yml $ sed -i "s/# DEBUG: true/DEBUG: false/g" /opt/jumpserver/config.yml $ sed -i "s/# LOG_LEVEL: DEBUG/LOG_LEVEL: ERROR/g" /opt/jumpserver/config.yml $ sed -i "s/# SESSION_EXPIRE_AT_BROWSER_CLOSE: false/SESSION_EXPIRE_AT_BROWSER_CLOSE: true/g" /opt/jumpserver/config.yml $ sed -i "s/DB_PASSWORD: /DB_PASSWORD: $DB_PASSWORD/g" /opt/jumpserver/config.yml $ echo -e "\033[31m 你的SECRET_KEY是 $SECRET_KEY \033[0m" 你的SECRET_KEY是 dkQB4KN48GSy1vPv0vQZq5PIghGkewE169IliSALjLxO0dosUl $ echo -e "\033[31m 你的BOOTSTRAP_TOKEN是 $BOOTSTRAP_TOKEN \033[0m" 你的BOOTSTRAP_TOKEN是 ElwLcfEzFoeMpy1F $ vi config.yml # 确认内容有没有错误 # SECURITY WARNING: keep the secret key used in production secret! # 加密秘钥 生产环境中请修改为随机字符串, 请勿外泄 SECRET_KEY: # SECURITY WARNING: keep the bootstrap token used in production secret! # 预共享Token coco和guacamole用来注册服务账号, 不在使用原来的注册接受机制 BOOTSTRAP_TOKEN: # Development env open this, when error occur display the full process track, Production disable it # DEBUG 模式 开启DEBUG后遇到错误时可以看到更多日志 DEBUG: false # DEBUG, INFO, WARNING, ERROR, CRITICAL can set. See https://docs.djangoproject.com/en/1.10/topics/logging/ # 日志级别 LOG_LEVEL: ERROR # LOG_DIR: # Session expiration setting, Default 24 hour, Also set expired on on browser close # 浏览器Session过期时间, 默认24小时, 也可以设置浏览器关闭则过期 # SESSION_COOKIE_AGE: 86400 SESSION_EXPIRE_AT_BROWSER_CLOSE: true # Database setting, Support sqlite3, mysql, postgres .... # 数据库设置 # See https://docs.djangoproject.com/en/1.10/ref/settings/#databases # SQLite setting: # 使用单文件sqlite数据库 # DB_ENGINE: sqlite3 # DB_NAME: # MySQL or postgres setting like: # 使用Mysql作为数据库 DB_ENGINE: mysql DB_HOST: 127.0.0.1 DB_PORT: 3306 DB_USER: jumpserver DB_PASSWORD: DB_NAME: jumpserver # When Django start it will bind this host and port # ./manage.py runserver 127.0.0.1:8080 # 运行时绑定端口 HTTP_BIND_HOST: 0.0.0.0 HTTP_LISTEN_PORT: 8080 # Use Redis as broker for celery and web socket # Redis配置 REDIS_HOST: 127.0.0.1 REDIS_PORT: 6379 # REDIS_PASSWORD: # REDIS_DB_CELERY: 3 # REDIS_DB_CACHE: 4 # Use OpenID authorization # 使用OpenID 来进行认证设置 # BASE_SITE_URL: http://localhost:8080 # AUTH_OPENID: false # True or False # AUTH_OPENID_SERVER_URL: https://openid-auth-server.com/ # AUTH_OPENID_REALM_NAME: realm-name # AUTH_OPENID_CLIENT_ID: client-id # AUTH_OPENID_CLIENT_SECRET: client-secret # OTP settings # OTP/MFA 配置 # OTP_VALID_WINDOW: 0 # OTP_ISSUER_NAME: Jumpserver 8、运行Jumpserver $ cd /opt/jumpserver $ ./jms start all -d # 后台运行使用 -d 参数./jms start all -d # 新版本更新了运行脚本, 使用方式./jms start|stop|status all 后台运行请添加 -d 参数
对JVM有了一定的认识以后,我们自然而然的就会知道两个异常,一个叫栈溢出(StackOverFlowError),一个叫堆溢出(OutOfMemory)或者说是内存泄漏;在Java内存模型中,栈是每一个线程私有的,随着线程的创建而创建,当栈的内存不足时,就会导致栈溢出的情况;而堆溢出则是指JVM在无法为对象申请到足够的内存空间时而抛出的异常;当我们的程序中出现这两个问题时,此时我们就需要对JVM进行一个调优处理。
调优的核心参数
在Java8以后,内存模型中的永久代已经被移除,取而代之的是元空间;永久代和元空间最大的不同在于前者使用的是JVM的堆内存,但是后者却已经不在JVM中了,它使用的是物理内存,因此在Java8以后,关于JVM的调优我们只需要关注堆中的新生区和养老区,如下图所示

常见配置汇总
垃圾回收机制
当类加载器把新的对象放到堆中时会触发JVM的GC,但JVM在进行GC时,并非每次都对堆内存中的三个区域一起回收的,大部分时候的回收其实都只是针对新生代,因此GC按照回收区域划分可以分为两种,一种是普通GC(Minor GC),一种是全局GC(Full GC);普通GC只针对新生代区域进行垃圾收集操作,因为大多数的Java对象存活率不高,因此普通GC非常频繁,速度也较快;全局GC只针对老年代进行垃圾收集操作,因为老年区的内存空间较大,所以全局GC相对于普通GC的频率较低,速度慢10以上,且全局GC一旦触发,也就意味着系统要考虑内存优化的问题了;JVM垃圾回收机制大致如下图所示

四种垃圾回收算法简介
引用计数法

复制算法
应用在年轻代中的GC算法,该算法的基本思想就是将内存分成两块,每次只用其中一块,当这一块内存用完,就会进行GC,未被回收的对象则复制到另一块区域,依次类推,大致原理如下

标记清除法
用通俗的话来说,标记清除算法就是程序运行期间,当内存快要被耗尽时,GC就会被触发并将程序暂停,随后将要回收的对象标记一遍,最终统一回收这些对象,完成标记清理共作然后让程序恢复运行

标记压缩法
该算法与上标记清除法唯一的区别就是在它的基础上增加了一个压缩的操作,这样就能解决内存碎片的问题,但是却带来来效率不高的问题,其原理大致如下图所示:

总结
对于上述四种算法,单从效率上来说,复制算法无疑是最快的,但是却浪费来较多的内存,标记清除和标记整理方法虽然兼顾了内存碎片这一个问题,但其效率较慢,所以我们无法从绝对意义上说这四种算法谁优谁劣。只是在实际应用中,我们发现复制算法在新生区效果更好一些,而标记清除或者标记整理在养老区则更强劲,因此我们把JVM的垃圾回收称作分代收集算法。
客户端安装xshell访问云端Linux
https://www.netsarang.com/download/down_form.html?code=622
(选择家庭学校版本,除邮箱以外,其他空行任意填)
Linx安装java环境
安装默认版本 yum install java 安装指定版本 yum install java-1.8.0-openjdk* -y

选择 y 即可开始下载 Linx安装tomcat yum install tomcat 启动tomcat ./startup.sh 相关启动命令:启动,重启,停止 systemctl start tomcat systemctl restart tomcat systemctl stop tomcat 查看tomcat状态 ps -aux | grep tomcat

上图表示tomcat在运行状态
windows上传war包到webapp目录下
可以用支持sftp的软件上传,如FlashFXP、FileZilla

也可以访问 localhost:8080/manager/ (默认账号和密码都是 tomcat)

Linux环境下上传war,直接使用scp命令 查看项目是否发布成功 curl http://localhost:8080 得到请求页面(即欢迎页面)的源码,说明搭建成功

输入ip:8080/war包名称/ 即可进入发布的项目的首页

方案:
1、基于request的负载均衡
该种方式下,负载均衡器 (load balancer)会根据各个node的状况,把每个 http request进行分发。使用这样的均衡策略,就必须在多个node之间复制用户的session,实时保持整个cluster的用户状态同步,这种操作被称为session复制(session replication)。Jboss的实现原理是使用拦截器(interceptor),根据用户的同步策略拦截request,做同步处理后再交给server产生响应。
优点是客户不会被绑定都具体的node,只要还有一个node存活,用户状态都不会丢失,cluster都能够继续工作。
缺点是node之间通信频繁,响应速度有影响,多并发、高频操作的情况下性能下降比较厉害。
2、 基于用户的负载均衡
该种方式下,当用户发出第一个request后,负载均衡器动态的把该用户分配到某个节点,并记录该节点的jvm路由,以后该用户的所有request都会被绑定这个jvm路由,用户只会与该server发生交互,这种策略被称为粘性session(session sticky)。
优点是响应速度快,多个节点之间无须通信。
缺点也很明显,某个node死掉以后,它负责的所有用户都会丢失session。
采取方案:
目前采用第二种,也就是session stiky (1小时)
文件服务器的配置 (1天)
Tomcat参数优化 (1天)
集群的配置
首先在apache 的conf目录下找到httpd.conf(apache 的配置文件)文件
在该文件里找到
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
并且把上面的#号去掉
然后找到
Include conf/extra/httpd-vhosts.conf
把上面的#号去掉
在最后一行加上
ProxyRequests Off
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8010 loadfactor=1 route=tomcat3(与该tomcat里德jvmRote名字一样)
BalancerMember ajp://127.0.0.1:8020 loadfactor=1 route=tomcat2
</proxy>
第二步找到\conf\extra包下面的httpd-vhosts.conf
在下面加上
<VirtualHost *:80>
ServerAdmin yancheng100088@163.com
ServerName localhost
ServerAlias localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On
ProxyPassReverse / balancer://cluster/
ErrorLog "logs/dummy-host2.163.com-error.log"
CustomLog "logs/dummy-host2.163.com-access.log" common
</VirtualHost>
第三步找到解压后的tomcat在不同的tomcat里修改server.xml里的端口参数使之不重复
(大家都知道就不详细说了)
这里改几个比较重要的参数
一个是<Engine name="Catalina" defaultHost="localhost">
改成<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
另一个后面改成tomcat3
然后加上
<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"
mcastBindAddress="127.0.0.1"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
tcpListenAddress="127.0.0.1"
address="auto"
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.MessageDispatch15Interceptor"/>
</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.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
这个是session复制用的不需要session复制的可以不用
最后一步
在需要session复制的程序里面的web.xml里加上
<distributable />
Session粘性,一般用到粘性就不用sesssion复制了
只需要在httpd.conf里最后一段加上
ProxyRequests Off
ProxyPass / balancer://cluster/ lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3
ProxyPassReverse / balancer://cluster/
【www.sufms.com】
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8010 loadfactor=1 route=tomcat3
BalancerMember ajp://127.0.0.1:8020 loadfactor=1 route=tomcat2
</proxy>
就行了。
(1)Manager:定义了关联到某一个容器的用来管理session池的基本接口。 (2)ManagerBase:实现了Manager接口,该类提供了Session管理器的常见功能的实现。 (3)StandardManager:继承自ManagerBase,tomcat的默认Session管理器(不指定配置,默认使用这个),是tomcat处理session的非集群实现(也就说是单机版的),tomcat关闭时,内存session信息会持久化到磁盘保存为SESSION.ser,再次启动时恢复。 (4)PersistentManagerBase:继承自ManagerBase,实现了和定义了session管理器持久化的基础功能。 (5)PersistentManager:继承自PersistentManagerBase,主要实现的功能是会把空闲的会话对象(通过设定超时时间)交换到磁盘上。 (6)ClusterManager:实现了Manager接口,通过类名应该能猜到,这个就是管理集群session的管理器和上面那个StandardManager单机版的session管理器是相对的概念。这个类定义类集群间session的复制共享接口。 (7)ClusterManagerBase:实现了ClusterManager接口,继承自ManagerBase。该类实现了session复制的基本操作。 (8)BackupManager:继承自ClusterManagerBase,集群间session复制策略的一种实现,会话数据只有一个备份节点,这个备份节点的位置集群中所有节点都可见。这种设计使它有个优势就是支持异构部署。 (9)DeltaManager:继承自ClusterManagerBase,集群建session复制策略的一种实现,和BackupManager不同的是,会话数据会复制到集群中所有的成员节点,这也就要求集群中所有节点必须同构,必须部署相同的应用。
- <Manager className="org.apache.catalina.session.StandardManager" maxInactiveInterval="7200"/>
maxActiveSessions:最多允许的活动会话数量,默认为-1,表示不限制; maxInactiveInterval:非活动的会话超时时长,默认为60s; pathname:会话文件的保存目录;
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
<Store className="org.apache.catalina.session.FileStore" directory="/session/tomcat"/>
</Manager>
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true"> <Store className="org.apache.catalina.session.JDBCStore" driverName="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mydb?user=jb;password=pw"/> </Manager>
1.跟集群相关的组件(摘自马哥笔记)
Stores:PersistentManager必须包含一个Store元素以指定将会话数据存储至何处。这通常有两种实现方式:FileStore和JDBCStore。
Resources:经常用于实现在Context中指定需要装载的但不在Tomcat本地磁盘上的应用资源如Java类,HTML页面,JSP文件等。
Cluster:专用于配置Tomcat集群的元素,可用于Engine和Host容器中。在用于Engine容器中时,Engine中的所有Host均支持集群功能。在Cluster元素中,需要直接定义一个Manager元素,这个Manager元素有一个其值为org.apache.catalina.ha.session.DeltaManager或org.apache.catalina.ha.session.BackupManager的className属性。同时,Cluster中还需要分别定义一个Channel和ClusterListener元素。
Channel:用于Cluster中给集群中同一组中的节点定义通信“信道”。Channel中需要至少定义Membership、Receiver和Sender三个元素,此外还有一个可选元素Interceptor。
Membership:用于Channel中配置同一通信信道上节点集群组中的成员情况,即监控加入当前集群组中的节点并在各节点间传递心跳信息,而且可以在接收不到某成员的心跳信息时将其从集群节点中移除。Tomcat6中Membership的实现是org.apache.catalina.tribes.membership.McastService。
Sender:用于Channel中配置“复制信息”的发送器,实现发送需要同步给其它节点的数据至集群中的其它节点。发送器不需要属性的定义,但可以在其内部定义一个Transport元素。
Transport:用于Sender内部,配置数据如何发送至集群中的其它节点。Tomcat6有两种Transport的实现:
1) PooledMultiSender
基于Java阻塞式IO,可以将一次将多个信息并发发送至其它节点,但一次只能传送给一个节点。
2)PooledParallelSener
基于Java非阻塞式IO,即NIO,可以一次发送多个信息至一个或多个节点。
Receiver:用于Channel定义某节点如何从其它节点的Sender接收复制数据,Tomcat6中实现的接收方式有两种BioReceiver和NioReceiver。
2.默认集群配置(此部分摘自网络,仅供参考)
tomcat7默认的集群配置如下,其配置细节实际上被忽略了
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<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="auto" 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.MessageDispatch15Interceptor"/> </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.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
补充:
Membership 中:
address:指定多播地址;
port:指定端口号;
frequency:节点间心跳信息传送的频率;
dropTime:设置节点为不可用节点的超时时间;
Receiver中:
address:在哪个地址上完成心跳信息传递和节点数据传输;
port:指定端口号;
autoBind:自动绑定,一次性可以接受多少个;
selectorTimeout:挑选(如节点是否可用)的超时时间;
maxThreads:最大线程数;
3.具体配置
3.1编辑配置文件
tomcatA的server.xml文件内容如下:
[root@localhost conf]# cat server.xml
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="80" address="192.168.85.129" maxThreads="1024"
protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="60000"
redirectPort="443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA">
<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.100.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.85.129"
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.MessageDispatch15Interceptor"/>
</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.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
tomcatB的server.xml文件内容如下:
[root@localhost conf]# cat server.xml
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="80" address="192.168.85.130" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatB">
<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.100.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.85.130"
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.MessageDispatch15Intercepto"/>
</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.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
根据tomcat7.0官方资料中的说明,有这么一句话
Make sure your web.xml has the <distributable/>element,继续配置各节点的web.xml,使tomcatA和tomcatB的web.xml文件中加上一句;
3.3检查语法并重启tomcat后测试
注意:
如果出错请查看日志catalina.out,我也出现了错误,查看官方文档才知道是我的两个tomcat时间不一致:
Make sure that all nodes have the same time and sync with NTP service! #时间同步
Make sure that your loadbalancer is configured for sticky session mode. #负载均衡要配置会话保持
而且有时有必要在各节点为使用组播地址添加组播路由,格式为:
route add -net 组播地址 netmask 255.255.255.255 dev eth0
测试结果:
无论怎么刷新,都是一个页面

参考文档:
http://zyycaesar.iteye.com/blog/296606






浙公网安备 33010602011771号