web站点架构

Java技术体系


Java运行过程


GC 线程



JAVA
SRE--运维工程师Ops
bash--调用内部命令(机器码)--运行很多进程--资源损耗
c--"编译器"作为一个进程--内部运行多个进程
python/go--"解释器"作为一个进程--内部运行多个进程
网站开发所用语言--php/jsp/asb.net(cshark)
jsp--主流互联网开发语言
底层不兼容--加中间层(抵消差异)--简洁一致的输出
java虚拟机(中间层的一部分)
提供一个程序运行环境
系统级接口(不统一)--变为-->虚拟接口(统一的接口)
没有调用系统本地"方法"--任何平台都可以运行--write once,run anywhere
写程序--拥有的条件
c库组件--存放程序员用到的代码(编码库)--提供的调用编程接口--即API
编程语言本身组件--关键字
调式和运行组件--检查错误(如:语法检查)
程序员:调用编码+语言+调式运行-->在jvm上跑起来
GC(gabage collection)
垃圾回收(我们在不断的分配内存空间--垃圾回收--防止内存被消耗空)
计数器(哪些内存需要回收,开始0,使用+1,完成-1,0--回收)
数据装载到内存中--执行完成后--释放
c--两个系统调用
malloc() 低效-->jemalloc() 并行内存分配(varnish)
free()
类加载器(class loader)--代码调用到公共库中的内容--需要装载类文件
JVM=类加载器+执行引擎
Java编写的程序--elasticsearch,hadoop...
运行Java程序,部署JRE|JDK
部署JDK两种方式:
1 Oracle官方下载:
www.bing.com--搜索JDK--Oracle官方下载--JDK下载(Java SE)
以运行程序为目的--建议使用JRE,否则可以使用JDK
二进制程序--不是源代码--OpenJDK(开源)
点击"Accept License Agreement"
下载rpm包--无多余的依赖关系--直接安装即可--Linux x64 jdk-8u171-linux-x64.rpm
centos7.3
rz 上传
cd /usr/java/ 非标准路径
ll 符号链接--可以多版本并存--但使用最新版本
cd /usr/java/latest/bin 有很多程序(Java命令)
jps 显示进程编号
设定环境变量--告诉系统级应用程序(如:tomcat--java编程),去哪里找Java
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/latest JAVA_HOME,指定java的家目录路径
export PATH=$JAVA_HOME/bin:$PATH 在bash中可以运行Java命令
. /etc/profile.d/java.sh
echo $JAVA_HOME
java -version
2 OpenJDK(开源--centos自带)
centos7.4
yum info java-1.8.0-openjdk 显示"The OpenJDK runtime environment."--JRE
yum info java-1.8.0-openjdk-devel
yum info java-1.8.0-openjdk-headless
不包含"audio and video"相关功能,需要音频处理--安装额外组件即可
yum install java-1.8.0-openjdk-devel
安装此包,可以自动解决依赖关系--安装openjdk(主包)和openjdk-devel
java -h
java -version
JDK三种模式
server mode:为服务器端程序运行而优化
client mode:为客户端程序运行而优化--内存分配的策略不同
mixed mode:
javac Java编译器
javadoc Java文档管理工具
javac编译完成后,使用java运行,启动一个java进程
tomcat运行--也启动一个java进程,不是tomcat进程
http协议--CGI--服务器端开发(后端开发)
无CGI
静态页面(内嵌java代码)--客户端展示(静态页面+插件JRE--执行java代码)--applet
有CGI
java后端服务--解析用户请求(http协议)+http响应
client--http服务器--CGI----severlet(解析CGI协议)--Java后端服务(应用)
severlet(解析整个页面内容)--太头疼
jsp(解析静态页面,java代码不动)--severlet(解析java代码)
.jsp -->jasper--> .java --> javac --> .class --> jvm
jasper--翻译静态页面代码,java代码不动--代码变为纯java程序文件--前后分开:
前端程序员--写前端代码--静态页面
后端程序员--写后端代码--内嵌的java代码
javac--把java代码编译为类文件
serverlet--JDK没有--要想开发jsp格式的网页页面
1 安装JDK--基础
2 把别人实现好的serverlet类库装进来--?
3 把jsp类库装进来--?
JSP Container: JDK+2个解决方案(serverlet和jsplet类库解决方案)
代码-->翻译-->执行
serverlet和jsplet类库解决方案
开源--tomcat
收费--IBM webSphere | Oracle weblogic
---------------------------------------------------------------------------------------------
tomcat
一个web server--支持http和https
server端(都支持)--client端(httpd支持,nginx不支持)
运行为一个Java进程,即:java(jvm)--内部主程序是tomcat,即:server
server(进程本身)--内部是帮助解析运行jsp页面程序文件
请求--server--connector(类)--service--engine--host--context
组件的层级关系 如下图1
除了这些组件,帮助完成其他功能--还有其他组件
connector(3种连接器组件):http https ajp(二进制协议,类似于fpm-fastcgi)
engine(引擎): 运行jsp代码的组件(tomcat最核心组件)
service(服务): 把一个或多个连接器与引擎绑定关联在一起
1个连接器只能属于1个引擎,但1个引擎可以有多个连接器(需要有对应关系)--service
1个service只能有1个engine
host: 虚拟主机
engine内部可以有多个host--一个host表示一个虚拟主机
engine-->主机名和端口-->host
一个host可以部署多个应用程序(pma+wordpress+...),每个应用放在一个url中
与PHP不同,java代码都是类文件,可能依赖类库中的其他类文件--类加载器加载完成后才能运行
a|b|c不同应用--加载不同的类文件--不好管理
context(上下文): 分开独立管理配置每一个应用程序及其环境--url实现 /path
单tomcat使用的内存空间不能超过32G
服务器128G--只运行tomcat--多起几个tomcat,充分利用资源
端口不是80
应用不能以管理员的身份运行--非管理员--不能用1024内的特权端口--默认8080
普通用户身份运行--改为80--也没有权限去监听--使用代理服务器代理tomcat
热部署--不停机可以增删host
内键的图形接口 host manager
管理应用程序 manager app
tomcat使用手册 docs
tomcat测试页面 使用jsp写程序的事例
图1

centos7.4--OpenJDK(yum安装)--192.168.1.6
yum list all tomcat*
tomcat.noarch 主程序
tomcat-lib.noarch 库文件
tomcat-admin-webapps.noarch 管理程序--host manager 和 manager app
tomcat-docs-webapp.noarch 文档documentation
tomcat-webapps.noarch 样例测试页面
tomcat-jsp-2.2-api.noarch jsp类库(程序包)
tomcat-servlet-3.0-api.noarch serverlet类库
tomcat--java程序--需要先编译成类文件
安装方式
1 yum直接安装(rpm包)
2 官方下载--编译好的版本--展开即用
下载源码(未编译)--需要先下载Maven构建器--把tomcat构建成字节码--头疼
项目管理器(项目构建工具):编译顺序,一个程序由不同的程序文件组成,很多依赖关系
c--make
java--ant(早期脚本管理工具)--Maven(xml文件格式定义)--grade(yaml格式定义其配置文件)
yum -y install tomcat-admin-webapps tomcat-docs-webapp tomcat-lib tomcat-webapps
less /usr/lib/systemd/system/tomcat.service
ExecStart=/usr/libexec/tomcat/server start
less /usr/libexec/tomcat/server
向Java虚拟机传递参数--启动一个类
MAIN_CLASS Bootstrap自举
CATALINA_HOME tomcat自己安装目录,应用程序类文件存放处
systemctl start tomcat
ss -ntlp 8080,8005,8009端口
浏览器:http://192.168.1.6:8080/ 测试页面
rpm -ql tomcat
/etc/tomcat 配置文件路径
/etc/sysconfig/tomcat 环境配置文件,修改JDK内存空间--上限和初始值
/usr/lib/systemd/system/tomcat.service unit-file
/usr/share/tomcat 默认安装路径
/usr/share/tomcat/conf-->/etc/tomcat-->主配置文件:server.xml
/usr/share/tomcat/lib-->/usr/share/java/tomcat 关键
/usr/share/tomcat/logs-->/var/log/tomcat
/usr/share/tomcat/temp-->/var/cache/tomcat/temp
/usr/share/tomcat/webapps-->/var/lib/tomcat/webapps webapps存放位置
/usr/share/tomcat/work-->/var/cache/tomcat/work 关键
/usr/share/tomcat/bin/bootstrap.jar tomcat启动
centos7.3--OracleJDK--192.168.1.5
官网下载:http://tomcat.apache.org/
rz 上传apache-tomcat-7.0.86.tar.gz
tar xf apache-tomcat-7.0.86.tar.gz -C /usr/local/
cd /usr/local/ ; ll
ln -sv apache-tomcat-7.0.86/ tomcat ; ll 创建符号链接,便于操作
cd /usr/local/tomcat ; ls bin/
shutdown.sh startup.sh configtest.sh version.sh
catalina.sh(可以调用其他脚本,放在path变量里)
bin/version.sh 显示版本
vim /etc/profile.d/tomcat.sh
export CATALINA_BASE=/usr/local/tomcat
export PATH=$CATALINA_BASE/bin:$PATH
. /etc/profile.d/tomcat.sh
echo $CATALINA_BASE
catalina.sh --help
catalina.sh run 运行在当前窗口
catalina.sh start 非加载安全策略的方式启动(运行在后端)
catalina.sh start -security 额外加载安全策略/usr/local/tomcat/conf/catalina.policy
catalina.sh version
catalina.sh start
ss -ntlp 8080,8005,8009端口
浏览器:http://192.168.1.5:8080/ 测试页面
ps aux 不要以root运行,切换到普通用户运行
useradd -r tomcat
chown -R tomcat:tomcat /usr/local/tomcat/*
ll /usr/local/tomcat/
su - tomcat -c "catalina.sh start" tomcat运行命令,并退出
ss -ntl 8080端口
ps aux tomcat身份运行tomcat
centos7.4 rpm包安装
vim /etc/tomcat/server.xml
Server
Service
Connector|...
Engine
Host 只有一个实现类
Valve(过滤) 有多个实现类--className类|... 属性赋值(把类实例化为一个对象)
访问控制,记录不同级别的访问日志,......
基于日志/IP/主机名/basic认证--做访问控制
详细内容参考文档
手动提供一测试类应用,并冷部署
centos7.4
systemctl status tomcat
systemctl stop tomcat
ll /usr/share/tomcat/
/usr/share/tomcat/webapps/-->/var/lib/tomcat/webapps/ 链接,一样内容
mkdir -p /usr/share/tomcat/webapps/test/{classes,lib,WEB-INF,META-INF}
vim /usr/share/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>Test Page</title>
</head>
<body>
<% out.println("hello world");
%>
</body>
</html>
systemctl restart tomcat ; ss -ntlp 8080端口
浏览器:http://192.168.1.6:8080/test/ ok,如图1
less /usr/share/tomcat/work/Catalina/localhost/test/org/apache/jsp/index_jsp.java
jsp--把页面中的非Java代码转换为Java代码后,存放在work目录下
jsp程序第一次访问--比较慢(内容较大的尤其如此)--需要编译为类文件.class
写一个脚本--主要页面都请求一次--让其编译完成
程序发生改变--需要重新编译
tomcat自动比较index.jsp和index_jsp.java时间戳(index.jsp较新,tomcat重新编译)
jsp程序的性能比php高2~6倍
浏览器:http://192.168.1.5:8080/ 测试页面--通过接口管理应用程序
点击"Manager App" 需要认证登陆
vim /etc/tomcat/tomcat-users.xml
在<tomcat-users>...</tomcat-users>标签内部定义
<role rolename="manager-gui"/>
允许用户通过图形界面访问状态页面和管理界面
<role rolename="manager-script"/>
允许用户通过文本接口(命令行操作)访问状态页面和管理界面
<role rolename="manager-jmx"/>
允许通过jmx代理访问状态页面和管理界面
jmx--Java-Management-Extension 扩展
JVM内部信息数据--(各个属性:内存空间/对象种类/垃圾收集...)
外部系统(监控系统)获取这些信息需要通过jmx接口--授权访问--防止信息泄露
<role rolename="manager-status"/> 查看状态信息
vim /etc/tomcat/tomcat-users.xml 如下图2
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>
systemctl restart tomcat
浏览器:http://192.168.1.5:8080/ 测试页面
点击"Manager App" 输入账号和密码--认证登陆
Expire session: 过期会话,超过多长时间就删除 leaks:查找漏洞
浏览(上传war文件"solo-2.8.0.war")并deploy(部署)--页面显示solo-2.8.0,如下图3
centos7.4 图形界面 firefox 192.168.1.7:8080
点击"Manager App"--点击"/solo-2.8.0"--如下图4
点击"Server Status" 如下图5
图1

图2

图3

图4

图5

centos7.3 IP变为192.168.1.6
centos7.4 IP变为192.168.1.7
浏览器:http://192.168.1.7:8080/ 测试页面
"Host Manager" 控制虚拟主机--添加|删除(无需删除即可部署)--热部署
ss -ntl 8005,8009,8080
8005端口监听在本机127.0.0.1上
yum -y install telnet
telnet 127.0.0.1 8005
SHUTDOWN
ss -ntl 8005,8009,8080所有端口关闭
不安全--更改端口或者更改命令
vim /etc/tomcat/server.xml
<Server port="8005" shutdown="SHUTDOWN">
openssl rand -hex 20
72572204d1e5b059898caf984970149ccd13468f
把"SHUTDOWN"命令替换为输出的20个16进制字符
LDAP/JDBC--用户认证系统(此处不做深究)
vim /etc/tomcat/server.xml
Connector配置 如下图1
Host配置 如下图2
<Host name="www.fgq.io" appBase="/data/webapps"
unpackWARs="true" autoDeploy="true">
</Host>
mkdir -p /data/webapps/ROOT/{classes,lib,WEB-INF,META-INF}
/data/webapps/ROOT/ 主程序存放此处,没有创建ROOT,会自动找ROOT目录
其他程序存放在/data/webapps下,清晰,将来移除会更加简单
vim /data/webapps/ROOT/index.jsp 测试页面
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.fgq.io</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("fgq.io","fgq.io"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
更改程序后,可以自动部署
systemctl restart tomcat ; ss -ntlp 处于正常监听状态,配置没问题
centos7.4-2
vim /etc/hosts
192.168.1.7 www.fgq.io
firefox http://www.fgq.io:8080/ 图形界面 如图3
部署应用程序javaee-bbs在context路径下
rz 上传文件
unzip javaee_v2.1.zip
把解压后的目录移动到我们创建的Host目录下
mv javaee_v2.1 /data/webapps 或
mv bbs /data/webapps
cd /data/webapps
ln -sv javaee_v2.1 bbs
ln -sv javaee_v2.1 javaee 创建链接-利于部署-出现错误-可以回滚-此处就不改了
ls bbs/WebRoot/
vim /etc/tomcat/server.xml
在设定的Host虚拟主机内部添加Context 如下图4
<Context path="/bbs" docBase="bbs/WebRoot" reloadable="true" />
systemctl restart tomcat ; ss -ntlp
centos7.4-2
firefox http://www.fgq.io:8080/bbs/ 图形界面-不能访问,此处配置ok即可,不多做了
注释掉添加的"Context"内容
浏览器:192.168.1.7:8080/
点击"Host Managr" 需要认证登陆
admin-gui - allows access to the HTML GUI 图形界面操作
admin-script - allows access to the text interface 命令行操作
vim /etc/tomcat/tomcat-users.xml 如图5
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>
生产中,安全起见,最好分开(tomcat--后台,仅内网访问,可略)
systemctl restart tomcat ; ss -ntlp
点击"Host Managr" 登陆 如下图6
部署一个虚拟主机前,需要下面的操作
mkdir -p /data/feng/webapps/ROOT/{classes,lib,WEB-INF,META-INF}
vim /data/feng/webapps/ROOT/index.jsp
<%@ page language="java" %>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.feng.io</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("feng.io","feng.io"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
点击"Add"部署上线后,我们可以看到增加了一个虚拟主机
centos7.4-2
vim /etc/hosts
192.168.1.7 www.fgq.io www.feng.io
firefox http://www.feng.io:8080/ 图形界面 blue颜色变化 如图7
浏览器中点击"stop",停掉www.feng.io
systemctl stop tomcat ; ss -ntl
systemctl start tomcat ; ss -ntl
刷新浏览器界面,www.feng.io虚拟主机消失,即图形界面的配置是保存在内存中的
永久生效--更改配置文件
热部署--临时增加一个虚拟主机使其生效--也是一个方法
ls /var/log/tomcat/ 没有我们定义的主机的日志--需要设置
在Host主机内部定义Valve--虚拟主机的专用日志
vim /etc/tomcat/server.xml 如下图8
<Host name="www.fgq.io" appBase="/data/webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="fgq_access_log." suffix=".log"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
systemctl restart tomcat ; ss -ntl
centos7.4-2
firefox http://www.fgq.io:8080/
centos7.4
ls /var/log/tomcat/ 显示我们定义的日志--fgq_access_log.2018-04-24.log
图1

图2

图3

图4

图5

图6

图7

图8

反代用户请求 如下图1和2(不常用)
nt: nginx+tomcat 同一台机器上
centos7.4
yum -y install nginx
vim /etc/nginx/conf.d/tomcat.conf
server {
server_name www.feng.io;
listen 80;
location / {
proxy_pass http://192.168.1.7:8080;
}
}
请求www.feng.io,代理至192.168.1.7:8080
本机没有192.168.1.7这个主机--请求被代理至默认主机
nginx -t ; systemctl start nginx.service ; ss -ntl 80端口
centos7.4-2
firefox浏览器:www.feng.io--默认主机的测试页面(index.jsp)
vim /etc/nginx/conf.d/tomcat.conf
server {
server_name www.feng.io;
listen 80;
location / {
proxy_pass http://www.fgq.io:8080;
}
}
vim /etc/hosts
192.168.1.7 www.fgq.io 主机名解析--否则出错
nginx -t ; nginx -s reload
centos7.4-2
firefox浏览器:www.feng.io
代理至www.fgq.io:8080主机的测试页面(/data/webapps/ROOT/index.jsp)
注意:代理主机名和代理IP有区别的
vim /etc/nginx/conf.d/tomcat.conf
两个主机名都可以访问,定义2个server
:1,$y 第一行到最后一行复制,p粘贴
server {
server_name www.feng.io;
listen 80;
location / {
proxy_pass http://127.0.0.1:8080; 更改
}
}
server {
server_name www.fgq.io; 更改
listen 80;
location / {
proxy_pass http://www.fgq.io:8080;
}
}
nginx -t ; nginx -s reload
centos7.4-2
firefox浏览器:
www.feng.io 代理至默认主机127.0.0.1
www.fgq.io 代理至www.fgq.io:8080(测试页面/data/webapps/ROOT/index.jsp)
把所有请求都代理给tomcat,负担过重
只把动态内容代理给tomcat
静态内容--nginx处理
vim /etc/nginx/conf.d/tomcat.conf
如下图3 不完善
centos7.4-2 firefox浏览器
www.feng.io nginx测试页面
www.feng.io/index.jsp 动态页面
systemctl stop nginx
systemctl status nginx.service disabled不会自动启动
------------------------------------------------------------------------
at: httpd+tomcat 同一台机器上
centos7.4
yum -y install httpd
httpd -M
proxy_module (shared) proxy_ajp_module (shared) proxy_http_module (shared)
vim /etc/httpd/conf.d/tomcat_http.conf
<VirtualHost *:80>
ServerName www.fgq.io
ServerAlias www.feng.io 为一个主机提供多个主机名
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On 把客户端请求的主机名传递至后端主机
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://127.0.0.1:8080
ProxyPassReverse / http://127.0.0.1:8080
<Location />
Require all granted
</Location>
</VirtualHost>
systemctl start httpd ; ss -ntl 80端口
centos7.4 firefox浏览器
www.fgq.io 第二个主机响应(后端Host有www.fgq.com)
www.fgq.io 默认主机响应--前提是"ProxyPreserveHost Off"--请求传递至192.168.1.7
www.feng.io 都是默认主机响应--不论"ProxyPreserveHost Off/On"
一个主机,2个主机名,响应时,使用不同的虚拟主机--灵活性
ajp协议
cp /etc/httpd/conf.d/tomcat_http.conf /etc/httpd/conf.d/tomcat_ajp.conf
vim /etc/httpd/conf.d/tomcat_ajp.conf
<VirtualHost *:80>
ServerName www.fgq.io
ServerAlias www.feng.io
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / ajp://127.0.0.1:8009
ProxyPassReverse / ajp://127.0.0.1:8009
<Location />
Require all granted
</Location>
</VirtualHost>
systemctl start httpd ; ss -ntl 80端口
centos7.4 firefox浏览器
www.fgq.io 第二个主机响应
www.feng.io 默认主机响应
浏览器:192.168.1.7:8080--host manager--server status--ajp
------------------------------------------------------------------------
nat: nginx httpd+tomcat 两台主机
centos7.4-3(192.168.1.9)
yum -y install nginx
vim /etc/nginx/conf.d/tomcat.conf
server {
listen 80;
server_name www.fgq.io www.feng.io;
index index.jsp index.html;
location / {
proxy_pass http://www.fgq.io; 把请求都代理至www.fgq.io
}
}
vim /etc/hosts
192.168.1.7 www.fgq.io www.feng.io
systemctl start nginx ; ss -ntl
centos7.4-2
vim /etc/hosts
192.168.1.9 www.fgq.io www.feng.io
firefox浏览器:
www.fgq.io和www.feng.io 都是第二个主机响应
没有把主机名真正的传递至与之对应的主机上
centos7.4-3
vim /etc/nginx/conf.d/tomcat.conf
要把主机名传递过去(不同主机名,响应不同内容)--再添加一个server
server {
listen 80;
server_name www.fgq.io ; 更改
index index.jsp index.html;
location / {
proxy_pass http://www.fgq.io;
}
}
server {
listen 80;
server_name www.feng.io;
index index.jsp index.html;
location / {
proxy_pass http://www.feng.io;
}
}
nginx -t ; nginx -s reload
centos7.4-2 firefox浏览器:
www.fgq.io 第二个主机响应
www.feng.io 默认主机响应
图1

图2

图3

图4

图5

如上图4--web架构
如上图5--实验拓扑
系统--不在物理服务器上--而是托管在云端--很多组件不需要自己构建
LBaaS(云端的负载均衡服务)--可以代替"负载均衡器"
DBaaS(云端的数据存储服务)--可以代替DBA--不需要自己维护存储系统
混合云--私有云和公有云都存储一份--备用
公有云+自己搞--存储公有云(七牛云)
3种环境
开发环境
测试环境
线上环境 云端/机房
centos7.4 192.168.1.7 tomcat
centos7.4-2 192.168.1.8 tomcat
centos7.4-3 192.168.1.6 nginx/httpd/haproxy
centos7.4-4 192.168.1.12 client
先同步时间,再配置,此处执行了计划任务
centos7.4,centos7.4-2 jdk,tomcat配置
yum -y install java-1.8.0-openjdk-devel tomcat-admin-webapps tomcat-webapps tomcat-lib tomcat-docs-webapp
mkdir -p /data/webapps/ROOT/{classes,lib,WEB-INF}
vim /etc/tomcat/server.xml 如下图1
<Host name="www.fgq.io" appBase="/data/webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="fgq_access_log." suffix=".log"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
注意:此处的主机名,centos7.4和centos7.4-2都是www.fgq.io
vim /data/webapps/ROOT/index.jsp--centos7.4
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.fgq.io</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("fgq.io","fgq.io"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
vim /data/webapps/ROOT/index.jsp--centos7.4-2
<%@ page language="java" %>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.feng.io</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("feng.io","feng.io"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
systemctl start tomcat ; ss -ntl 8080,8005,8009
浏览器:192.168.1.7:8080 ok; 192.168.1.8:8080 ok 没区别看不出来
cp -r /data/webapps/ROOT/ /usr/share/tomcat/webapps/test
浏览器:192.168.1.7:8080/test ok; 192.168.1.8:8080/test ok 区别出来
centos7.4-4
vim /etc/hosts
192.168.1.7 www.fgq.io
192.168.1.8 www.fgq.io
firefox浏览器:192.168.1.7:8080/test ok; 192.168.1.8:8080/test ok 可以区别出来
centos7.4-3 192.168.1.6 nginx负载均衡(调度)
yum -y install nginx
vim /etc/nginx/nginx.conf
添加upstream和location,如下图2
nginx -t ; systemctl start nginx.service
ss -ntl 80端口
浏览器:
192.168.1.6 ok
192.168.1.6/test ok
刷新会轮询出现192.168.1.7和192.168.1.8的内容,而且session id变化,会话丢失
ip_hash/cookie(此处不做会话保持),后面有简便的
systemctl stop nginx.service
centos7.4-3 192.168.1.6 haproxy负载均衡(调度)
yum -y install haproxy
vim /etc/haproxy/haproxy.cfg
删除原来的frontend和backend,添加新的frontend和backend 如下图3
光标移动至main上面的一行
.,$-2d 删除当前行至倒数第二行
frontend http-in
bind *:80
default_backend appsrvs
backend appsrvs
balance roundrobin
server app1 192.168.1.7:8080 check
server app2 192.168.1.8:8080 check
listen stats
bind *:9009
stats enable
systemctl start haproxy.service ; ss -ntl 9009和80端口
浏览器:
192.168.1.6:9009/haproxy?stats ok
192.168.1.6/test ok
刷新会轮询出现192.168.1.7和192.168.1.8的内容,而且session id变化
cookie会话保持(不做,参考haproxy文章)
systemctl stop haproxy.service
centos7.4-3 192.168.1.6 httpd负载均衡(调度)
yum -y install httpd
httpd -M
proxy_module proxy_ajp_module proxy_http_module
proxy_balancer_module
vim /etc/httpd/conf.d/tomcat_http.conf 如下图4
<proxy balancer://appsrvs>
BalancerMember http://192.168.1.7:8080
BalancerMember http://192.168.1.8:8080
ProxySet lbmethod=byrequests
</Proxy>
<VirtualHost *:80>
ServerName www.fgq.io
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://appsrvs/
ProxyPassReverse / balancer://appsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
httpd -t ; systemctl start httpd ; ss -ntl 80端口
浏览器:192.168.1.6/test ok
刷新会轮询出现192.168.1.7和192.168.1.8的内容,而且session id变化
使用ajp协议
cp /etc/httpd/conf.d/tomcat_http.conf /etc/httpd/conf.d/tomcat_ajp.conf
vim /etc/httpd/conf.d/tomcat_ajp.conf 如下图5
<proxy balancer://appsrvs>
BalancerMember ajp://192.168.1.7:8009
BalancerMember ajp://192.168.1.8:8009
ProxySet lbmethod=byrequests
</Proxy>
<VirtualHost *:80>
ServerName www.fgq.io
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://appsrvs/
ProxyPassReverse / balancer://appsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
httpd -t ; systemctl restart httpd ; ss -ntl 80端口
浏览器:192.168.1.6/test ok
刷新会轮询出现192.168.1.7和192.168.1.8的内容,而且session id变化
ajp协议的会话保持--增加首部信息--session sticky
vim /etc/httpd/conf.d/tomcat_ajp.conf 如下图6
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<proxy balancer://appsrvs>
BalancerMember ajp://192.168.1.7:8009 route=tcA
BalancerMember ajp://192.168.1.8:8009 route=tcB
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
</Proxy>
<VirtualHost *:80>
ServerName www.fgq.io
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://appsrvs/
ProxyPassReverse / balancer://appsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
httpd -t ; systemctl restart httpd ; ss -ntl 80端口
浏览器:192.168.1.6/test ok 刷新--session id无变化--会话保持
centos7.4-4:firefox浏览器: 192.168.1.6/test ok 刷新--session id无变化--会话保持
F12--cookie--.tcA/B
根据cookie绑定,即使同一个client用不同的浏览器访问,cookie也不同
设置并启用内键的管理状态页面
vim /etc/httpd/conf.d/tomcat_ajp.conf 如下图7
在最下方添加如下信息:
<Location /balancer-manager>
SetHandler balancer-manager
ProxyPass !
Require all granted
</Location>
httpd -t ; systemctl restart httpd ; ss -ntl 80端口
浏览器:192.168.1.6/balancer-manager ok 如下图8
会话保持另一种方法--session cluster(集群不能太大)
persistent manager 持久会话管理器(内存中)
周期性存储在磁盘的某个特定文件中--session.xxx
GDBC manager 持久会话管理器(磁盘中)--不常用(名字不准确)
把会话存储在外部的关系型数据库中--MySQL,Oracle
delta manager 增量(变化的意思,不一定是增加)--完成集群会话管理
节点多--会话多--资源消耗
backup manager 备用管理器
两个或多个节点互为备份,保留会话的一部分,使用在集群较多的环境(淘汰了)
集群较多的环境--现在用session server(下面有)
delta manager(此处使用)
把多个tomcat加入到一个集群
成员关系判定--集群中有几个节点--发送自己的增量数据给这些节点
所属的集群名字--判断加入那个集群
是否处于同一个多播域/多播地址--判断是否处于同一个集群中
同一个多播地址--此节点属于这个集群
此节点是否在这个集群中(网络故障导致下线)--周期性判定网络节点的健康状态
leader node--周期性判定网络节点的健康状态--低效
每个节点主动报告自己是否在线--高效
每个节点周期性向外传递自己的信息给leader node-->heart beat(心跳信息)
leader node--收集每个节点发来的报告--判断集群的节点数量
同时把当前的picture(节点报告状态)--同步给同一集群的其他节点(协作逻辑)
-----------------------------------------------------------------------------------------
相关概念了解--后面会细讲--此处不深究
分布式-->多个节点共同参与一个工作
分布式系统
Paxos协议--分布式系统受益于此协议--人类社会的缩影--人工智能
zookeeper--zab协议--zookeeper原子广播协议
etcd(docker)--raft协议--不挑战智商
tomcat--内部程序包含了这些功能,没有用这些协议
问题-->network partition(网络分区)--网络故障--节点找不到组织了--四分五裂
quorum机制--判断哪一部分可以代表组织继续工作
with quorum 拥有法定票数,才能代表组织继续工作
> total/2 大于总票数的一半
leader node在这里--ok,开始工作
leader node不在这里--启用投票机制(领导选举方式),选一个新领导
有选举权+无被选举权--观察者节点
有选举权+无被选举权--不能被选为领导
选举权+被选举权
node--先提(自己做leader)先得--得票数大于规定的基本票数--ok--leader
without quorum 不拥有法定票数,不能代表组织继续工作
<= total/2 小于等于总票数的一半
放弃组织成员的一切权力,不被使用,直到找到组织
分布式系统(多台主机工作)实现分布式协作时,只能满足3个功能的2个
ACP
分区容错性--P--一部分出错,一部分可以继续使用--必须的
可用性--A
一致性--C
平衡--AP/CP
-----------------------------------------------------------------------------------------
session cluster--delta manager
添加集群的相关设定
vim /etc/tomcat/server.xml(centos7.4--192.168.1.7)
在Engine行添加自己的id,在Engine下方添加cluster信息--到官网复制后更改
如下图9和图10
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tcA">
<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.110.110.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.1.7"
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>
vim /etc/tomcat/server.xml(centos7.4-2--192.168.1.8)
如下图11
cp /etc/tomcat/web.xml /usr/share/tomcat/webapps/test/WEB-INF/
vim /usr/share/tomcat/webapps/test/WEB-INF/web.xml
在web-app标签内部添加信息:<distributable/> 如下图12
网络文档如下图13
systemctl stop tomcat.service
tail -f /var/log/tomcat/catalina.2018-04-26.log 输出的日志
systemctl start tomcat.service 再看日志--如下图14
centos7.4-3(使用nginx做代理服务器)
systemctl stop httpd.service ; ss -ntl 关闭httpd服务器,因为会话保持测试不出效果
systemctl start nginx.service ; ss -ntl
浏览器:192.168.1.6/test/ 刷新后,虽然调度到不同的主机,但是会话还是一致的
如下图15和图16
会话集群--无论调度至哪个节点--会话是一致的
centos7.4-3(使用haproxy做代理服务器)
systemctl stop nginx.service ; ss -ntl
systemctl start haproxy.service ; ss -ntl 80和9009端口
浏览器:192.168.1.6/test/ 刷新后,虽然调度到不同的主机,会话仍然是一致的
图1

图2

图3

图4

图5

图6

图7

图8

图9

图10

图11

图12

图13

图14

图15

图16

NoSQL(非关系型数据库)
memcached:cache(无持久功能)--内存中,down机则数据丢失,50~100万个事务数
redis:store service(有持久功能)--k/v,50~100万个事务数(普通的pc-server就可以)
MySQL(关系型数据库) 50个事务数
MongoDB和CouchDB(文档存储)/...
k/v store,document store,列存储,graphe store
缓存介绍--如下图1
读多写少--如下图2
memcached--参考文档
yum info memcached
yum -y install memcached
rpm -ql memcached
memcached -h
rpm包安装(yum)默认生成一个memcached的用户
memcached内存空间分配的介绍,如下图3
memcached -u memcached -vv
memcached -u memcached -f 1.5 -vvv slab class变少了
cat /etc/sysconfig/memcached
CACHESIZE="64" 生产中会调整
OPTIONS="" 把支持的选项填进去: -d ...
-U 0 关闭udp
cat /usr/lib/systemd/system/memcached.service
ExecStart=/usr/bin/memcached -u $USER -p $PORT -m $CACHESIZE -c $MAXCONN $OPTIONS
更改/etc/sysconfig/memcached文件,此处直接生效
我们做测试就不改了
systemctl start memcached.service
ss -ntlu udp/tcp 11211端口
memcached-tool 连接至哪台服务器,发送一些命令
memcached-tool 127.0.0.1 stats 统计数据项
auth_cmds 认证多少次
cmd_get 用户查询多少次
cmd_set 设定内存数据多少次
cas_hits 命中多少次(不同数据类型,命中方式不同)
get_hits 查询命中多少次
delete_hits 删除命中多少次
decr_hits decr命中多少次
...
memcached-tool 127.0.0.1 dump 显示键值
没有存储任何数据
yum info libmemcached 存数据
memcat 显示键值
memcp 复制数据
memdump 显示键值
memflush 清空数据库
memping 探测服务器存活
...
yum -y install libmemcached
memping -h
memping --servers=127.0.0.1:11211 没有信息就是最好的消息
yum -y install telnet
less /usr/share/doc/memcached-1.4.15/protocol.txt
命令的用法
<command name> <key> <flags> <exptime> <bytes>
flags 0-65535的数字
telnet 127.0.0.1 11211
stats
add mykey 1 300 11 存储键值
hello world 输入要存入的键值(字节数要和上面对应),显示"STORED"存储成功
get mykey 显示键值,一旦过期,get时,不会出现数据
set mykey 1 300 15 更改数据
hello ilinux.io 输入变更后的数据
get mykey
删除/...
add count 1 3600 1
0 输入数字
get count
incr count 8 增加8,回车后自动显示变更后的结果
decr count 3 减少3
stats 可以看到,不同命令的命中次数
memcached-tool 127.0.0.1:11211 dump
flush_all 清除数据--标记为无效,并非真的清除
memcached-tool 127.0.0.1:11211 dump 可以看到有items,但无内容
程序--通过驱动--连接至存储
php连接mysql php-myslq
php连接memcached php-pecl-memcache(base) php-pecl-memcached(epel)
yum list all *memcache* 文档也有
图1

图2

图3

会话保持的第三种方法--session server(性能好,有冗错能力)
把会话存储在服务器上,tomcat不支持,使用第三方应用msm(memcached-session-manager)
tomcat会话管理器--msm--支持将session保存到这样的存储系统中(session server)
代码托管网站www.github.com
搜索"tomcat session",使用第三方应用msm
https://github.com/magro/memcached-session-manager
文档
https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
msm(memcached-session-manager)
double writing功能
同时写两份数据到主节点和从节点
failover功能
从"主节点"读取数据--主节点down机--自动切换为另一个节点(健康状态检测和切换)
memcached仅存储流式化数据,jsp(Java语言),纯面向对象;
内存中的会话(对象式的)存储到memcached,再获取,不是原样的;
msm--流式化框架完成数据流式化
基于众多应用管理会话:redis/couchbase/memcached;
建议会话保存在redis; 性能(同memcached)+持久存储能力
数据--流式化--存储--读取
序列化工具介绍 如下图1 文档网页
配置第三方工具可用,需要手动整合进来几个类库 如下图2 文档网页
存储不同,用到的组件不同
我们配置session server
存储 memcached
序列化工具 javolution-serializer
拓扑
centos7.4 192.168.1.7 centos7.4-2 192.168.1.8 centos7.4-3 192.168.1.6
centos7.4和centos7.4-2都安装tomcat+memcached(相当于是四台主机)
centos7.4已经安装了tomcat+memcached
centos7.4-2已经安装了tomcat,但是没有安装memcached
centos7.4-2
yum -y install memcached
systemctl start memcached.service 将来使用时,最起码要更改内存大小
ss -ntlu udp,tcp-11211端口
删除之前配置文件中添加的<Cluster...Cluster/>,与"session server"不兼容
centos7.4和centos7.4-2
systemctl stop tomcat.service
vim /etc/tomcat/server.xml
:107,146d
下载工具包并上传文件
https://github.com/magro/memcached-session-manager
http://www.java2s.com/Code/Jar/j/Downloadjavolution5431jar.htm
javolution-5.4.3.1.jar.zip 需要解包
memcached-session-manager-2.3.0.jar
memcached-session-manager-tc7-2.3.0.jar
msm-javolution-serializer-2.1.1.jar
spymemcached-2.9.1.jar
rpm -ql tomcat-lib .jar文件都存放在/usr/share/java/tomcat/
cd /usr/share/java/tomcat/
rz 上传5个文件
unzip javolution-5.4.3.1.jar.zip
更改配置文件,添加Context
centos7.4和centos7.4-2
vim /etc/tomcat/server.xml
<Context path="/test" docBase="test" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.7:11211,n2:192.168.1.8:11211"
failoverNodes="n2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
/>
</Context>
systemctl start tomcat ; ss -tnl 8080,8005,8009端口
tail -f /var/log/tomcat/catalina.2018-04-27.log 看日志是否出错
显示"INFO: Server startup" ok
centos7.4-3
systemctl stop haproxy.service
systemctl start nginx.service
浏览器:
http://192.168.1.6/test/ 如下图3和4
http://192.168.1.7:8080/test/ ok haproxy做代理,就不能访问后端服务器
http://192.168.1.8:8080/test/ ok
centos7.4-4:firefox浏览器:http://192.168.1.6/test/ ok
centos7.4:systemctl stop memcached.service n1挂掉
centos7.4-4:firefox浏览器:http://192.168.1.6/test/ ok,标识符变为n2
centos7.4:systemctl start memcached.service n1启用
centos7.4-4:firefox浏览器:http://192.168.1.6/test/ ok,标识符仍是n2,n1为备用
redis做会话存储以后讲
https://github.com/search?utf8=%E2%9C%93&q=tomcat+session
图1

图2

图3

图4

图5

图6

Tomcat的常用优化配置
内存分析 如上图5和图6
内存优化
centos7.4
free -m 查看内存信息:总内存/已用内存/剩余内存
vim /etc/sysconfig/tomcat
默认没有启用,添加信息即可
JAVA_OPTS="-server -Xms80m -Xmx100m"
systemctl restart tomcat ; ss -ntl
jps 看Bootstrap的进程编号
cat /proc/26503/cmdline 看Bootstrap启动时启用了哪些参数,显示我们定义的参数
centos7.4-2没有定义就不会显示出参数
线程池
启用URIEncoding属性 以http为例
vim /etc/tomcat/server.xml
Connector的HTTP协议中,操作,如下图1
...
JVM常用的分析工具
jsp 看Bootstrap的id
jinfo
jinfo -flags
jinfo -flags 26503(Bootstrap的进程编号) 显示参数信息
jinfo -sysprops 26503 Java system properties
jps -v
jstat -options
jstat -gc 26503
S0C S1C 容量--capacity Survivor
S0U S1U 利用情况--utilization Survivor
EC EU 新生代
OC OU 老年代
MC MU 元空间
YGC--新生代垃圾回收次数 YGCT--新生代垃圾回收时间
FGC--full gc 次数 FGCT--full gc 时间
GCT--total gc 时间
jstat -gc 26503 -1000 1s显示1次
jstat -gc 26503 -1000 3 3次后退出
jconsole 图形界面工具
centos7.4图形界面连接,输入命令--不安全连接即可--如下图2
连接后,如下图3
jvisualvm 图形界面工具(centos7.4--yum安装时,没有此工具--可能少安装了某个包)
centos7.3图形界面连接(centos7.3前面实验安装过官网下载的tomcat)
catalina.sh start 启动tomcat
jvisualvm 如下图4
连接tomcat 如下图5
了解有这些工具即可
图1

图2

图3

图4

图5

网友评论