客户端和服务端往往处在不同的物理主机上,它们分属不同的进程,这些进程间需要通信。跨主机的进程间通信需要使用网络编程。最常见的网络编程接口是Socket。
Socket称为套接字,本意是插座。也就是说网络通讯需要两端,如果一端被动的接收另一端请求并提供计算和数据的称为服务器端,另一端往往只是发起计算或数据请求,称为客户端。
这种编程模式称为Client/Server编程模式,简称C/S编程。开发的程序也称为C/S程序。C/S编程往往使用传输层协议(TCP/UDP),较为底层,比如:QQ,迅雷, 云音乐, 云盘, foxmail,xshell等
有一部分程序员还是要编写HTML、CSS、JavaScript,这些代码运行在浏览器端,称为WEB前端编程。合起来称为Browser/Server编程,即B/S编程。
HTML(HyperText Markup Language)超文本标记语言,它不同于一般的编程语言。超文本即超出纯
文本的范畴,例如:描述文本颜色、大小、字体等信息,或使用图片、音频、视频等非文本内容。
HTML由一个个的标签(标记)组成,这些标签各司其职,有的提供网页信息,有的负责文字,有的负责图片,有的负责网页布局,所以一个HTML文件,是由格式标签和数据组成。
HTML本身为了格式化显示文本,但是当网页呈现大家面前的时候,需求HTML提供更多样式能力。这
使得HTML变得越来越臃肿。这促使了CSS的诞生。
Javascript 简称JS,是一种动态的弱类型脚本解释性语言,和HTML、CSS并称三大WEB核心技术,得到
了几乎主流浏览器支持。
1994年,网景Netscape公司成立并发布了Netscape Navigator浏览器,占据了很大的市场份额,网景
意识到WEB需要动态,需要一种技术来实现。
PC 端或移动端浏览器访问
从静态服务器请求HTML、CSS、JS等文件发送到浏览器端,浏览器端接收后渲染在浏览器上
从图片服务器请求图片资源显示
从业务服务器访问动态内容,动态内容是请求后有后台服务访问数据库后得到的,最终返回到浏览器端
手机 App 访问
内置了HTML和JS文件,不需要从静态WEB服务器下载 JS 或 HTML。为的就是减少文件的发送,现代前
端开发使用的JS文件太多或太大了
有必要就从图片服务器请求图片,从业务服务器请求动态数据
客户需求多样,更多的内容还是需要由业务服务器提供,业务服务器往往都是由一组服务器组成。
传统架构(单机系统),一个项目一个工程:比如商品、订单、支付、库存、登录、注册等等,统一部署,一个进程
all in one的架构方式,把所有的功能单元放在一个应用里。然后把整个应用部署到一台服务器上。如果负载能力不行,将整个应用进行水平复制,进行扩展,然后通过负载均衡实现访问。
特别是对于一个大型应用,我们不可能吧所有内容都放在一个应用里面,我们如何维护、如何分工合作都是问题。如果项目庞大,管理难度大
微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去掉耦合,每一个微服务提供单个业务功能,一个服务只做一件事。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等
从技术角度讲就是一种小而独立的处理过程,类似与进程的概念,能够自行单独启动或销毁
微服务架构(分布式系统),各个模块/服务,各自独立出来,“让专业的人干专业的事”,独立部署。分布式系统中,不同的服务可以使用各自独立的数据库。
微服务的实现框架有多种,不同的应用架构,部署方式也有不同
常见的微服务框架
阿里开源贡献给了ASF,目前已经是Apache的顶级项目
一款高性能的Java RPC服务框架,微服务生态体系中的一个重要组件
将单体程序分解成多个功能服务模块,模块间使用Dubbo框架提供的高性能RPC通信
内部协调使用Zookeeper,实现服务注册、服务发现和服务治理
一个完整的微服务解决方案,相当于Dubbo的超集
微服务框架,将单体应用拆分为粒度更小的单一功能服务
基于HTTP协议的REST(Representational State Transfer 表述性状态转移)风格实现模块间通信
跨平台运行
Java 包含下面部分:
jsp
JSP本质是提供一个HTML模板,也就是在网页中预留以后填充的空,后续将Java程序运行生成的数据对HTML进行填空就可以了。如果网页布局需要调整,JAVA源代码不需要很大的调整
Java SE API: Java 基础类库开发接口
JRE:Java Runtime Environment缩写,指Java运行时环境, 包含 JVM + Java核心类库
JDK:Java Development Kit,即 Java 语言的软件开发工具包,JDK协议基于 JRL(JavaResearch License)协议
安装oracle Java的红帽的命令
[root@rocky8 ~]# rpm -ivh jdk-11.0.15.1_linux-x64_bin.rpm
warning: jdk-11.0.15.1_linux-x64_bin.rpm: Header V3 RSA/SHA256 Signature, key ID ec551f03: NOKEY
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:jdk-11-2000:11.0.15.1-ga ################################# [100%]
[root@rocky8 ~]#
在Ubuntu上安装jdk1.8
root@ubuntu2004:~# ls
install_dns.sh jdk-8u333-linux-x64.tar.gz reset.sh reset_v6.sh snap
root@ubuntu2004:~# tar xf jdk-8u333-linux-x64.tar.gz
root@ubuntu2004:~# ls
install_dns.sh jdk1.8.0_333 jdk-8u333-linux-x64.tar.gz reset.sh reset_v6.sh snap
root@ubuntu2004:~# mkdir /apps/
root@ubuntu2004:~# mv jdk1.8.0_333/ /apps/
root@ubuntu2004:~# ll /apps/
total 12
drwxr-xr-x 3 root root 4096 Jun 12 21:35 ./
drwxr-xr-x 20 root root 4096 Jun 12 21:35 ../
drwxr-xr-x 8 10143 10143 4096 Apr 26 14:03 jdk1.8.0_333/
root@ubuntu2004:~# ln -s /apps/jdk1.8.0_333/ /apps/jdk
root@ubuntu2004:~# ll /apps/jdk
lrwxrwxrwx 1 root root 19 Jun 12 21:36 /apps/jdk -> /apps/jdk1.8.0_333//
root@ubuntu2004:~#
root@ubuntu2004:~# ls /apps/jdk/bin/
appletviewer java javapackager jdb jps jvisualvm rmic tnameserv
ControlPanel javac java-rmi.cgi jdeps jrunscript keytool rmid unpack200
extcheck javadoc javaws jhat jsadebugd native2ascii rmiregistry wsgen
idlj javafxpackager jcmd jinfo jstack orbd schemagen wsimport
jar javah jconsole jjs jstat pack200 serialver xjc
jarsigner javap jcontrol jmap jstatd policytool servertool
root@ubuntu2004:~# vim /etc/profile.d/jdk.sh
export JAVA_HOME=/apps/jdk
export PATH=$PATH:$JAVA_HOME/bin
root@ubuntu2004:~# . /etc/profile.d/jdk.sh
root@ubuntu2004:~# java -version
java version "1.8.0_333"
Java(TM) SE Runtime Environment (build 1.8.0_333-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.333-b02, mixed mode)
root@ubuntu2004:~#
Oracle JDK的二进制文件安装
#下载安装包:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
[root@centos8 ~]#tar xvf jdk-8u241-linux-x64.tar.gz -C /usr/local/
[root@centos8 ~]#cd /usr/local/
[root@centos8 ~]#ln -s jdk1.8.0_241/ jdk
#初始化环境变量
[root@centos8 ~]#vim /etc/profile.d/jdk.sh
[root@centos8 ~]#cat /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin
#以下两项非必须项
#export JRE_HOME=$JAVA_HOME/jre
#export CLASSPATH=.:$JAVA_HOME/lib/:$JRE_HOME/lib/
[root@centos8 ~]#. /etc/profile.d/jdk.sh
#注意:JAVA_HOME变量必须设置,否则tomcat启动时会出下面错误
[root@centos8 ~]#catalina.sh
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program
[root@centos8 ~]#startup.sh
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program
#验证安装
[root@centos8 ~]#java -version
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
[root@centos8 ~]#which java
/usr/local/jdk/bin/java
Web 应用服务器的使用
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,Tomcat 具有处理HTML静态资源页面的功能,它还是一个Servlet和JSP容器
起始于SUN 公司的一个Servlet的参考实现项目 Java Web Server,开发者是 James Duncan Davidson,在1999年,将项目贡献给了apache软件基金会(ASF),和ASF现有的项目 JServ 合并,并开源成为顶级项目
Tomcat 仅仅实现了Java EE规范中与Servlet、JSP相关的类库,是JavaEE不完整实现。
CentOS 8 包仓库中目前还没有提供tomcat相关包
root@centos8 ~]#yum list tomcat
Last metadata expiration check: 1:25:35 ago on Wed 15 Jul 2020 09:01:28 AM CST.
Error: No matching Packages to list
CentOS 7 yum仓库源中自带的Tomcat 7.0版本安装,此方式安装tomcat版本较低,不推荐
安装之前必须要安装JDK
范例:Ubuntu20.04安装tomcat9
[root@ubuntu2004 ~]#apt update
[root@ubuntu2004 ~]#apt list tomcat*
Listing... Done
tomcat9-admin/focal-security,focal-updates,now 9.0.31-1ubuntu0.1 all [installed]
tomcat9-common/focal-security,focal-updates,now 9.0.31-1ubuntu0.1 all
[installed,automatic]
tomcat9-docs/focal-security,focal-updates,now 9.0.31-1ubuntu0.1 all [installed]
tomcat9-examples/focal-security,focal-updates,now 9.0.31-1ubuntu0.1 all
[installed]
tomcat9-user/focal-security,focal-updates 9.0.31-1ubuntu0.1 all
tomcat9/focal-security,focal-updates,now 9.0.31-1ubuntu0.1 all [installed]
[root@ubuntu2004 ~]#apt -y install tomcat9 tomcat9-admin tomcat9-docs tomcat9-
examples
打开浏览器访问:http://tomcat:8080/
注意: 安装tomcat 前必须先部署JDK
https://tomcat.apache.org/download-80.cgi
https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/
[root@localhost ~]# tar xf apache-tomcat-9.0.64.tar.gz -C /usr/local/
[root@localhost ~]# ll /usr/local/
total 0
drwxr-xr-x 9 root root 220 Jun 12 23:21 apache-tomcat-9.0.64
drwxr-xr-x. 2 root root 6 Oct 11 2021 bin
drwxr-xr-x. 2 root root 6 Oct 11 2021 etc
drwxr-xr-x. 2 root root 6 Oct 11 2021 games
drwxr-xr-x. 2 root root 6 Oct 11 2021 include
lrwxrwxrwx 1 root root 13 Jun 12 22:37 jdk -> jdk-11.0.15.1
drwxr-xr-x 9 root root 126 Jun 12 22:37 jdk-11.0.15.1
drwxr-xr-x. 2 root root 6 Oct 11 2021 lib
drwxr-xr-x. 3 root root 17 May 2 13:38 lib64
drwxr-xr-x. 2 root root 6 Oct 11 2021 libexec
drwxr-xr-x. 2 root root 6 Oct 11 2021 sbin
drwxr-xr-x. 5 root root 49 May 2 13:38 share
drwxr-xr-x. 2 root root 6 Oct 11 2021 src
[root@localhost ~]# ln -s /usr/local/apache-tomcat-9.0.64/ /usr/local/tomcat
[root@localhost ~]# ls /usr/local/tomcat
bin conf lib logs README.md RUNNING.txt webapps
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE RELEASE-NOTES temp work
[root@localhost ~]# ls /usr/local/tomcat/bin
bootstrap.jar ciphers.sh daemon.sh setclasspath.bat startup.sh version.bat
catalina.bat commons-daemon.jar digest.bat setclasspath.sh tomcat-juli.jar version.sh
catalina.sh commons-daemon-native.tar.gz digest.sh shutdown.bat tomcat-native.tar.gz
catalina-tasks.xml configtest.bat makebase.bat shutdown.sh tool-wrapper.bat
ciphers.bat configtest.sh makebase.sh startup.bat tool-wrapper.sh
[root@localhost ~]# vim /etc/profile.d/tomcat.sh
PATH=/usr/local/tomcat/bin:$PATH
[root@localhost ~]# . /etc/profile.d/tomcat.sh
[root@localhost ~]# startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
扩展知识:tomcat 和 catalina 关系
omcat的servlet容器在4.X版本中被Craig McClanahan(Apache Struts项目的创始人,也是Tomcat的 Catalina 的架构师)重新设计为Catalina.即Catalina就是servlet容器。
Tomcat的核心分为3个部分:
(1)Web容器:处理静态页面;
(2)JSP容器:把jsp页面翻译成一般的 servlet
(3)catalina: 是一个servlet容器,用于处理servlet
Catalina是美国西海岸靠近洛杉矶22英里的一个小岛,因为其风景秀丽而著名,曾被评为全美最漂亮的小岛。Servlet运行模块的最早开发者Craig McClanahan因为喜欢Catalina岛,故以Catalina命名他所开这个模块,另外在开发的早期阶段,Tomcat是被搭建在一个叫Avalon的服务器框架上,而Avalon则是Catalina岛上的一个小镇的名字,于是想一个与小镇名字相关联的单词也是自然而然。设计者估计是想把tomcat设计成最美的轻量级容器吧。下图为该小岛。
配置规则:
每一个组件都由一个Java“类”实现,这些组件大体可分为以下几个类型:
顶级组件:Server
服务类组件:Service
连接器组件:http, https, ajp(apache jserv protocol)
容器类:Engine, Host, Context
被嵌套类:valve, logger, realm, loader, manager, ...
集群类组件:listener, cluster, ...
核心组件
Tomcat启动一个Server进程。可以启动多个Server,即tomcat的多实例, 但一般只启动一个
创建一个Service提供服务。可以创建多个Service,但一般也只创建一个
每个Service中,是Engine和其连接器Connector的关联配置
可以为这个Service提供多个连接器Connector,这些Connector使用了不同的协议,绑定了不同的端口。其作用就是处理来自客户端的不同的连接请求或响应
Service 内部还定义了Engine,引擎才是真正的处理请求的入口,其内部定义多个虚拟主机Host
Engine对请求头做了分析,将请求发送给相应的虚拟主机
如果没有匹配,数据就发往Engine上的defaultHost缺省虚拟主机
Engine上的缺省虚拟主机可以修改
Host 定义虚拟主机,虚拟主机有name名称,通过名称匹配
Context 定义应用程序单独的路径映射和配置
范例:多个组件关系 conf/server.xml
实站案例: 部署基于JAVA的博客系统 JPress
JPress 是一个使用Java开发的类似WordPress的产品的建站神器,目前已有超过10万+网站使用 JPress搭建,其中包括多个政府机构,200+上市公司,中科院、红十字会等。和JPress 相类似的基于 java 开发的博客系统还有zrlog,Halo等
开源协议: LGPL-3.0
[root@localhost webapps]# pwd
/usr/local/tomcat/webapps
[root@localhost webapps]# ls
docs examples host-manager manager ROOT test
[root@localhost ~]# ls
anaconda-ks.cfg install_jdk.sh jpress-v4.2.0.war reset_v6.sh
apache-tomcat-9.0.64.tar.gz jdk-11.0.15.1_linux-x64_bin.tar.gz reset.sh
[root@localhost ~]# cp jpress-v4.2.0.war jpress.war
[root@localhost ~]# ls
anaconda-ks.cfg install_jdk.sh jpress-v4.2.0.war reset.sh
apache-tomcat-9.0.64.tar.gz jdk-11.0.15.1_linux-x64_bin.tar.gz jpress.war reset_v6.sh
[root@localhost ~]# cp jpress.war /usr/local/tomcat/webapps
[root@localhost ~]# ls /usr/local/tomcat/webapps
docs examples host-manager jpress.war manager ROOT test
[root@localhost ~]# ls /usr/local/tomcat/webapps
docs examples host-manager jpress jpress.war manager ROOT test
[root@localhost ~]#
WEB的管理Server status和Manager APP实现应用部署
打开浏览器可以访问tomcat管理的默认管理页面,点击下图两个按钮都会出现下面提示403的错误提示
默认的管理页面被禁用,启用方法如下
修改conf/conf/tomcat-users.xml
用户认证,配置文件是conf/tomcat-users.xml。打开tomcat-users.xml,我们需要一个角色manager-gui。
[root@centos8 tomcat]#vim conf/tomcat-users.xml
#加下面两行,指定用户和密码
#修改全局配置文件需要重启服务生效
[root@centos8 tomcat]#systemctl restart tomcat
修改webapps/manager/META-INF/context.xml
[root@localhost META-INF]# pwd
/usr/local/tomcat/webapps/manager/META-INF
[root@localhost META-INF]# cat context.xml
#增加10网段
#修改WebApp的配置无需重启服务即可生效
再次通过浏览器访问两个按钮Server Status和Manager App,可以看到以下管理界面,输入前面的用户和密码进行登录
或者这样访问:
curl http://tomcat:[email protected]:8080/manager/status
links -dump http://tomcat:[email protected]:8080/manager/status #只显示文字
[root@localhost META-INF]# pwd
/usr/local/tomcat/webapps/host-manager/META-INF
[root@localhost META-INF]# vim context.xml
[root@localhost META-INF]# cat context.xml
#方法二注释IP地址,解除限制
[root@localhost conf]# pwd
/usr/local/tomcat/conf
[root@localhost conf]# vim tomcat-users.xml
[root@localhost conf]# systemctl restart tomcat
多虚拟主机配置
[root@localhost ~]# mkdir /data/ehuosite/ROOT -p
[root@localhost ~]# cd /data/ehuosite/ROOT
[root@localhost conf]# pwd
/usr/local/tomcat/conf
[root@localhost conf]# vim server.xml
[root@localhost conf]# systemctl restart tomcat
虚拟主机的访问日志设置
[root@localhost conf]# vim server.xml
[root@localhost ~]# tail -f /usr/local/tomcat/logs/www.ehuo.org_access_log.2022-06-14.txt
10.0.0.1 - - [14/Jun/2022:17:42:29 +0800] "GET / HTTP/1.1" 200 197
standalone模式,Tomcat单独运行,直接接受用户的请求,不推荐。
反向代理,单机运行,提供了一个Nginx作为反向代理,可以做到静态由nginx提供响应,动态jsp代理给Tomcat
LNMT:Linux + Nginx + MySQL + Tomcat
LAMT:Linux + Apache(Httpd)+ MySQL + Tomcat
LNMT:Linux + Nginx + MySQL + Tomcat
LNNMT:Linux + Nginx + Nginx + MySQL + Tomcat
nginx实现Tomcat的负载均衡
root@ubuntu2004:~# cat /etc/nginx/conf.d/proxy.ehuo.org.conf
upstream tomcat {
server 10.0.0.15:8080;
server 10.0.0.35:8080 ;
}
server {
listen 80 ;
server_name www.ehuo.org ;
location / {
proxy_pass http://tomcat ;
proxy_set_header Host $http_host;
}
}
root@ubuntu2004:~# nginx -t; nginx -s reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost ~]# vim /usr/local/tomcat/conf/server.xml
[root@localhost ~]# mkdir /data/webapps -p
[root@localhost ~]# chown -R tomcat.tomcat /data/webapps/
[root@localhost ~]# mkdir /data/webapps/ROOT/
[root@localhost ~]# chown -R tomcat.tomcat /data/webapps/
[root@localhost ~]# cd /data/webapps/ROOT/
[root@localhost ROOT]# vim index.html
[root@localhost ROOT]# systemctl restart tomcat
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; #注意: 8080后不要加/,需要在nginx服务器修改 /etc/hosts
}
以上设置,可以将jsp的请求反向代理到tomcat,而其它文件仍由nginx处理,从而实现所谓动静分离。但由于jsp文件中实际上是由静态资源和动态组成,所以无法彻底实现动静分离。实际上Tomcat不太适合做动静分离,用它来管理程序的图片不好做动静分离部署
root@ubuntu2004:~# cat /etc/nginx/conf.d/proxy.ehuo.org.conf
upstream tomcat {
server 10.0.0.15:8080;
server 10.0.0.35:8080 ;
}
server {
listen 80 ;
server_name www.ehuo.org ;
location / {
proxy_pass http://tomcat ;
proxy_set_header Host $http_host;
}
location ~* \.(jpg|png|css|js|html)$ {
root /data/static;
}
}
#在浏览器上是两个请求,再次请求静态的资源;
可以在增加缓存;
有一个问题就是session留住;
动态服务器的问题,往往就是并发能力太弱,往往需要多台动态服务器一起提供服务。如何把并发的压力分摊,这就需要调度,采用一定的调度策略,将请求分发给不同的服务器,这就是Load Balance负载均衡。
当单机Tomcat,演化出多机多级部署的时候,一个问题便凸显出来,这就是Session。而这个问题的由来,都是由于HTTP协议在设计之初没有想到未来的发展。
Session绑定
nginx:source ip, cookie
HAProxy:source ip, cookie
优点:简单易配置
缺点:如果目标服务器故障后,如果没有做sessoin持久化,就会丢失session,此方式生产很少使用
Session 复制集群
tomcat自己的提供的多播集群,通过多播将任何一台的session同步到其它节点。
缺点
session 共享服务器,使用memcached、redis做共享的Session服务器,此为推荐方式
[root@rocky8 ~]#vim /etc/nginx/conf.d/blog.wangxiaochun.com.conf
upstream blog {
ip_hash;
server 10.0.0.101:8080;
server 10.0.0.102:8080;
}
server {
listen 80;
server_name blog.wangxiaochun.com;
return 302 https://$host$request_uri;
#return 302 https://$server_name$request_uri; #$server_name 来自于上面server_name,即blog.wangxiaochun.com
}
server {
listen 443 ssl;
server_name blog.wangxiaochun.com;
ssl_certificate /etc/nginx/ssl/blog.wangxiaochun.com.pem;
ssl_certificate_key /etc/nginx/ssl/blog.wangxiaochun.com.key;
client_max_body_size 20m;
location / {
proxy_pass http://blog;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
#配置后端tomcat服务器
[root@rocky8 ~]#vim /usr/local/tomcat/conf/server.xml
...
#添加下面行
#添加上面行
[root@rocky8 ~]#mkdir /data/blog -p
[root@rocky8 ~]#mv jpress-4.1.2.war /data/blog/ROOT.war
[root@rocky8 ~]#chown -R tomcat.tomcat /data/blog
#注意:先只在第一台tomcat服务器上配置完成初始化连接数据库和上传图片发表文章后,然后复制相关web件至第二台主机即可,无需多次初始化
#配置后端数据库
[root@rocky8 ~]#yum -y install mysql-server
[root@rocky8 ~]#systemctl enable --now mysqld
mysql> create user blog@'10.0.0.%' identified by '123456';
mysql> create database jpress;
mysql> grant all on jpress.* to blog@'10.0.0.%';
#配置后端NFS共享存储
[root@rocky8 ~]#yum -y install nfs-utils
[root@rocky8 ~]#groupadd -g 80 www
[root@rocky8 ~]#useradd -g www -u 80 -s /sbin/nlogin www
[root@rocky8 ~]#mkdir /data/blog/ROOT/attachment -p
[root@rocky8 ~]#vim /etc/exports
[root@rocky8 ~]#cat /etc/exports
/data/blog/ROOT/attachment *(rw,all_squash,anonuid=80,anongid=80)
[root@rocky8 ~]#systemctl enable --now nfs-server.service
[root@rocky8 ~]#chown -R www.www /data/blog/ROOT/attachment
#tomcat服务器挂载 NFS共享
[root@rocky8 ~]#vim /etc/fstab
NFS服务器IP:/data/blog/ROOT/attachment /data/blog/ROOT/attachment nfs _netdev 0 0
[root@rocky8 ~]#yum -y install nfs-utils
[root@rocky8 ~]#mount -a
Tomcat 官方实现了 Session 的复制集群,将每个Tomcat的Session进行相互的复制同步,从而保证所有Tomcat都有相同的Session信息.
配置说明
Cluster 集群配置
Manager 会话管理器配置
Channel 信道配置
Membership 成员判定。使用什么多播地址、端口多少、间隔时长ms、超时时长ms。同一个多播地址和端口认为同属一个组。使用时修改这个多播地址,以防冲突
Receiver 接收器,多线程接收多个其他节点的心跳、会话信息。默认会从4000到4100依次尝试可用端口
address=“auto”,auto可能绑定到127.0.0.1上,所以一定要改为当前主机可用的IP
Sender 多线程发送器,内部使用了tcp连接池。
Interceptor 拦截器
Valve
ReplicationValve 检测哪些请求需要检测Session,Session数据是否有了变化,需要启动复制过程ClusterListener
ClusterSessionListener 集群session侦听器
root@ubuntu2004:~# cat /etc/nginx/conf.d/proxy.ehuo.org.conf
upstream tomcat {
server 10.0.0.15:8080;
server 10.0.0.35:8080 ;
}
server {
listen 80 ;
server_name www.ehuo.org ;
location / {
proxy_pass http://tomcat ;
proxy_set_header Host $http_host;
}
location ~* \.(jpg|png|css|js|html)$ {
root /data/static;
}
}
在所有后端tomcat主机上修改conf/server.xml
[root@localhost conf]# vim server.xml
#其他略去
[root@localhost conf]# systemctl restart tomcat
其他略去
修改应用的web.xml文件开启该应用程序的分布式
[root@t1 ~]#ll /usr/local/tomcat/webapps/ROOT/WEB-INF/
total 4
-rw-r----- 1 tomcat tomcat 1227 Jul 1 05:53 web.xml
[root@t1 ~]#cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/webapps/ROOT/
[root@t1 ~]#tree /data/webapps/ROOT/
/data/webapps/ROOT/
├── index.jsp
└── WEB-INF
└── web.xml
1 directory, 2 files
#在倒数第二行加一行
[root@t1 ~]##vim /data/webapps/ROOT/WEB-INF/web.xml
[root@t1 ~]#tail -n3 /data/webapps/ROOT/WEB-INF/web.xml
#添加此行
#注意权限
[root@t1 ~]#ll /data/webapps/ROOT/WEB-INF/
total 4
-rw-r----- 1 tomcat tomcat 1243 Jan 17 09:37 web.xml
[root@t1 ~]#systemctl restart tomcat
#同时观察日志
[root@t1 ~]#tail -f /usr/local/tomcat/logs/catalina.out
15-Jul-2020 11:29:10.998 INFO [Membership-MemberAdded.]
org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member
added:[org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0,
102}:4000,{10, 0, 0, 102},4000, alive=1022, securePort=-1, UDP Port=-1, id={89
-26 -30 -99 16 80 65 95 -65 14 -33 124 -55 -123 -30 82 }, payload={}, command=
{}, domain={}]]
#另一台也是
最后测试
Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统
memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台memcached 可用就不会出现数据丢失,当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并提供服务。
Memcached 借助了操作系统的 libevent 工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能
Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的session实现session共享
应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用。
Memcached采用了Slab Allocator机制来分配、管理内存。
Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。
Chunk:用于缓存记录k/v值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes等多种,数据只有100bytes存储在128bytes中,存在少许浪费。
Chunk最大就是Page的大小,即一个Page中就一个Chunk
查看Slab Class
#-f, --slab-growth-factor= chunk size growth factor (default: 1.25)
[root@centos8 ~]#memcached -u memcached -f 2 -vv
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 192 perslab 5461
slab class 3: chunk size 384 perslab 2730
slab class 4: chunk size 768 perslab 1365
slab class 5: chunk size 1536 perslab 682
slab class 6: chunk size 3072 perslab 341
slab class 7: chunk size 6144 perslab 170
slab class 8: chunk size 12288 perslab 85
slab class 9: chunk size 24576 perslab 42
slab class 10: chunk size 49152 perslab 21
slab class 11: chunk size 98304 perslab 10
slab class 12: chunk size 196608 perslab 5
slab class 13: chunk size 524288 perslab 2
<27 server listening (auto-negotiate)
<28 server listening (auto-negotiate)
memcached不会监视数据是否过期,而是在取数据时才看是否过期,如果过期,把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据。
Memcached集群,称为基于客户端的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群
Memcached集群内部并不互相通信,一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点
[root@localhost ~]# yum info memcached
Last metadata expiration check: 0:00:28 ago on Tue 14 Jun 2022 10:25:34 PM CST.
Available Packages
Name : memcached
Version : 1.5.22
Release : 2.el8
Architecture : x86_64
Size : 161 k
Source : memcached-1.5.22-2.el8.src.rpm
Repository : AppStream
Summary : High Performance, Distributed Memory Object Cache
URL : https://www.memcached.org/
License : BSD
Description : memcached is a high-performance, distributed memory object caching
: system, generic in nature, but intended for use in speeding up dynamic
: web applications by alleviating database load.
root@localhost ~]# yum -y install memcached
root@localhost ~]# systemctl enable --now memcached.service
Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /usr/lib/systemd/system/memcached.service.
[root@localhost ~]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"
[root@localhost ~]#
[root@localhost ~]# ss -ntlup |grep memcached
tcp LISTEN 0 128 127.0.0.1:11211 0.0.0.0:* users:(("memcached",pid=3833,fd=28))
tcp LISTEN 0 128 [::1]:11211 [::]:* users:(("memcached",pid=3833,fd=29))
#修改端口绑定的IP为当前主机的所有IP
[root@centos8 ~]#vim /etc/sysconfig/memcached
[root@centos8 ~]#cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
#OPTIONS="-l 127.0.0.1,::1" #注释此行
OPTIONS=""
root@localhost ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:11211 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 100 127.0.0.1:25 0.0.0.0:*
LISTEN 0 128 [::]:11211 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
[root@localhost ~]#
与memcached通信的不同语言的连接器。libmemcached提供了C库和命令行工具。
五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令,都使用如下所示的语法:
command
#参数说明如下:
command set/add/replace
key key 用于查找缓存值
flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes 在缓存中存储的字节数
value 存储的值(始终位于第二行)
#增加key,过期时间为秒,bytes为存储数据的字节数
add key flags exptime bytes
#加
add mykey 1 60 4
test
STORED
#查
get mykey
VALUE mykey 1 4
test
#改
set mykey 1 60 5
test1
STORED
get mykey
VALUE mykey 1 5
test1
END
#删除
delete mykey
DELETED
get mykey
END
#清空
flush_all
OK
get mykey
END
quit
[root@centos8 ~]#yum -y install python3 python3-memcached
[root@centos8 ~]#cat m3.py
#!/usr/bin/python3
#coding:utf-8
import memcache
m = memcache.Client(['127.0.0.1:11211'], debug=True)
for i in range(10):
m.set("key%d" % i,"v%d" % i)
ret = m.get('key%d' % i)
print("%s" % ret)
[root@centos8 ~]#chmod +x m3.py
[root@centos8 ~]#./m3.py
v0
v1
v2
v3
v4
v5
v6
v7
v8
v9
msm(memcached session manager)提供将Tomcat的session保持到memcached或redis的程序,可以实现高可用。
支持Tomcat的 6.x、7.x、8.x、9.x
将spymemcached.jar、memcached-session-manage、kyro相关的jar文件都放到Tomcat的lib目录中去,这个目录是 $CATALINA_HOME/lib/ ,对应本次安装就是/usr/local/tomcat/lib。
kryo-3.0.3.jar
asm-5.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
minlog-1.3.1.jar
kryo-serializers-0.45.jar
msm-kryo-serializer-2.3.2.jar
memcached-session-manager-tc8-2.3.2.jar
spymemcached-2.12.3.jar
memcached-session-manager-2.3.2.jar
sticky 模式即前端tomcat和后端memcached有关联(粘性)关系
参考文档:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
Tomcat-1 (t1) will primarily store it's sessions in memcached-2 (m2) which isrunning on another machine (m2 is a regular node for t1). Only if m2 is notavailable, t1 will store it's sessions in memcached-1 (m1, m1 is thefailoverNode for t1). With this configuration, sessions won't be lost whenmachine 1 (serving t1 and m1) crashes. The following really nice ASCII art showsthis setup.
Tomcat-1(t1)主要将其会话存储在另一台计算机上运行的memcached-2(m2)中(m2是t1的常规节点)。 仅当m2不可用时,t1才会将其会话存储在memcached-1中(m1,m1是t1的failoverNode)。 使用此配置,当计算机1(服务于t1和m1)崩溃时,会话不会丢失。 以下非常好的ASCII艺术显示了此设置。
. \ / .
. X .
. / \ .
t1和m1部署可以在一台主机上,t2和m2部署也可以在同一台。
当新用户发请求到Tomcat1时, Tomcat1生成session返回给用户的同时,也会同时发给memcached2备份。即Tomcat1 session为主session,memcached2 session为备用session,使用memcached相当于备份了一Session
如果Tomcat1发现memcached2 失败,无法备份Session到memcached2,则将Sessoin备份存放memcached1中
修改tomcat配置
修改 $CATALINA_HOME/conf/context.xml
特别注意,t1配置中为failoverNodes=“n1”, t2配置为failoverNodes=“n2”
#以下是sticky的配置
...
配置说明
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中了。
环境准备:
IP | 主机名 | 服务 | 软件 |
---|---|---|---|
10.0.0.102 | proxy | 调度器 | CentOS8、Nginx、HTTPD |
10.0.0.15 | t1 | tomcat1 | JDK8、Tomcat8、memcached |
10.0.0.35 | t2 | tomcat2 | JDK8、Tomcat8、memcached |
[root@proxy ~]# cat /etc/nginx/conf.d/proxy.ehuo.org.conf
upstream tomcat {
server 10.0.0.15:8080;
server 10.0.0.35:8080 ;
}
server {
listen 80 ;
server_name www.ehuo.org ;
location / {
proxy_pass http://tomcat ;
proxy_set_header Host $http_host;
}
location ~* \.(jpg|png|css|js|html)$ {
root /data/static;
}
}
[root@proxy ~]#cat /etc/hosts
10.0.0.100 proxy.magedu.org proxy
10.0.0.101 t1.magedu.org t1
10.0.0.102 t2.magedu.org t2
#在 tomcat1 上配置 memcached
[root@t1 ~]#dnf -y install memcached
[root@t1 ~]#vim /etc/sysconfig/memcached
[root@t1 ~]#cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
#注释下面行
#OPTIONS="-l 127.0.0.1,::1"
[root@t1 ~]#systemctl enable --now memcached.service
#在 tomcat2 上配置 memcached
[root@t2 ~]#dnf -y install memcached
[root@t2 ~]#vim /etc/sysconfig/memcached
[root@t2 ~]#cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
#注释下面行
#OPTIONS="-l 127.0.0.1,::1"
[root@t2 ~]#systemctl enable --now memcached.service
7.3.3.3.1 配置 tomcat1
[root@t1 tomcat]#vim conf/server.xml
[root@t1 tomcat]#vim conf/context.xml
...
#将相关包传到lib/目录下,共10个文件
asm-5.2.jar
kryo-3.0.3.jar
kryo-serializers-0.45.jar
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc8-2.3.2.jar
minlog-1.3.1.jar
msm-kryo-serializer-2.3.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
spymemcached-2.12.3.jar
[root@t1 tomcat]#systemctl restart tomcat
[root@t1 tomcat]#cat /data/webapps/ROOT/index.jsp
<%@ page import="java.util.*" %>
tomcat test
tomcat website
On <%=request.getServerName() %>
<%=request.getLocalAddr() + ":" + request.getLocalPort() %>
SessionID = <%=session.getId() %>
<%=new Date()%>
7.3.3.3.2 配置 tomcat2
[root@t2 tomcat]#vim conf/server.xml
[root@t1 tomcat]#vim conf/context.xml
...
在t1 上安装部署python3环境,访问memcached
[root@t1 ~]#dnf -y install python3 python3-memcached
#或者下面方式也可以安装
[root@t1 ~]#dnf -y install python3
[root@t1 ~]#pip3 install python-memcached
#准备python测试脚本
[root@t1 ~]#cat showmemcached.py
#!/usr/bin/python3
import memcache
mc = memcache.Client(['10.0.0.101:11211','10.0.0.102:11211'], debug=True)
print('-' * 30)
#查看全部 key
#for x in mc.get_stats('items'): # stats items 返回 items:5:number 1
# print(x)
#print('-' * 30)
for x in mc.get_stats('cachedump 5 0'): # stats cachedump 5 0 # 5和上面的items返
回的值有关;0表示全部
print(x)
[root@t1 ~]#chmod +x showmemcached.py
#运行python脚本
[root@t1 ~]#./showmemcached.py
('10.0.0.101:11211 (1)', {})
('10.0.0.102:11211 (1)', {})
non-sticky 模式即前端tomcat和后端memcached无关联(无粘性)关系
Tomcat session为中转Session,对每一个SessionID随机选中后端的memcached节点n1(或者n2)为主session,而另一个memcached节点n2(或者是n1)为备session。产生的新的Session会发送给主、memcached,并清除本地Session。
后端两个memcached服务器对一个session来说是一个是主,一个是备,但对所有session信息来说每个memcached即是主同时也是备
如果n1下线,n2则转正。n1再次上线,n2依然是主Session存储节点。
放到 $CATALINA_HOME/conf/context.xml 中
...
支持将session存放在Redis中,但当前对Redis的支持不允许连接到多个Redis节点,可以通过Redis的集群服务实现防止redis的单点失败
参考文档:
https://github.com/ran-jit/tomcat-cluster-redis-session-manager/wiki
https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration#example-for-non-sticky-sessions–kryo–redis
下载 jedis.jar,放到 $CATALINA_HOME/lib/ ,对应本次安装就是/usr/local/tomcat/lib。
# yum install redis
# vim /etc/redis.conf
bind 0.0.0.0
# systemctl start redis
放到 $CATALINA_HOME/conf/context.xml 中
...
浏览器访问,使用redis相关工具可以观察到redis中的信息
在目前流行的互联网架构中,Tomcat在目前的网络编程中是举足轻重的,由于Tomcat的运行依赖于JVM,从虚拟机的角度把Tomcat的调整分为外部环境调优 JVM 和 Tomcat 自身调优两部分
JVM 组成部分
JVM运行时数据区域由下面部分构成
所谓本地方法,使用native 关健字修饰的方法,比如:Thread.sleep方法. 简单的说是非Java实现的方法,例如操作系统的C编写的库提供的本地方法,Java调用这些本地方法接口执行。但是要注意,本地方法应该避免直接编程使用,因为Java可能跨平台使用,如果用了Windows API,换到了Linux平台部署就有了问题
在堆内存中如果创建的对象不再使用,仍占用着内存,此时即为垃圾.需要即使进行垃圾回收,从而释放内存空间给其它对象使用
堆内存里面经常创建、销毁对象,内存也是被使用、被释放。如果不妥善处理,一个使用频繁的进程,可能会出现虽然有足够的内存容量,但是无法分配出可用内存空间,因为没有连续成片的内存了,内存全是碎片化的空间。
所以需要有合适的垃圾回收机制,确保正常释放不再使用的内存空间,还需要保证内存空间尽可能的保持一定的连续
对于垃圾回收,需要解决三个问题
分垃圾标记阶段和内存释放两个阶段。
特点:
优点:算法简单
缺点:标记-清除最大的问题会造成内存碎片,但是不浪费空间,效率较高(如果对象较多时,逐一删除效率也会受到影响)
分垃圾标记阶段和内存整理两个阶段。
特点:
标记-压缩算法好处是整理后内存空间连续分配,有大段的连续内存可分配,没有内存碎片。
缺点是内存整理过程有消耗,效率相对低下
先将可用内存分为大小相同两块区域A和B,每次只用其中一块,比如A。当A用完后,则将A中存活的对象复制到B。复制到B的时候连续的使用内存,最后将A一次性清除干净。
特点
好处是没有碎片,复制过程中保证对象使用连续空间,且一次性清除所有垃圾,所以即使对象很多,收回效率也很高
缺点是比较浪费内存,只能使用原来一半内存,因为内存对半划分了,复制过程毕竟也是有代价。
8.2.2.4 多种算法总结
没有最好的算法,在不同场景选择最合适的算法
对于大多数垃圾回收算法而言,GC线程工作时,停止所有工作的线程,称为Stop The World。GC 完成时,恢复其他工作线程运行。这也是JVM运行中最头疼的问题。
上述垃圾回收算法都有优缺点,能不能对不同数据进行区分管理,不同分区对数据实施不同回收策略,分而治之。
将heap内存空间分为三个不同类别: 年轻代、老年代、持久代
Heap堆内存分为
伊甸园区eden: 只有一个,刚刚创建的对象
幸存(存活)区Servivor Space:有2个幸存区,一个是from区,一个是to区。大小相等、地位相同、可互换。
from 指的是本次复制数据的源区.
to 指的是本次复制数据的目标区
默认空间大小比例:
默认JVM试图分配最大内存的总内存的1/4,初始化默认总内存为总内存的1/64,年青代中heap的1/3,老年代占2/3
范例: 查看JVM内存分配情况
[root@centos8 ~]#cat Heap.java
public class Heap {
public static void main(String[] args){
//返回JVM试图使用的最大内存,字节单位
long max = Runtime.getRuntime().maxMemory();
//返回JVM初始化总内存
long total = Runtime.getRuntime().totalMemory();
System.out.println("max="+max+"字节\t"+(max/(double)1024/1024)+"MB");
System.out.println("total="+total+"字节\t"+
(total/(double)1024/1024)+"MB");
}
}
通常场景下,大多数对象都不会存活很久,而且创建活动非常多,新生代就需要频繁垃圾回收。
但是,如果一个对象一直存活,它最后就在from、to来回复制,如果from区中对象复制次数达到阈值(默认15次,CMS为6次,可通过java的选项 -XX:MaxTenuringThreshold=N 指定),就直接复制到老年
进入老年代的数据较少,所以老年代区被占满的速度较慢,所以垃圾回收也不频繁。
如果老年代也满了,会触发老年代GC,称为Old GC或者 Major GC。
由于老年代对象一般来说存活次数较长,所以较常采用标记-压缩算法。
当老年代满时,会触发 Full GC,即对所有"代"的内存进行垃圾回收
Minor GC比较频繁,Major GC较少。但一般Major GC时,由于老年代对象也可以引用新生代对象,所以先进行一次Minor GC,然后在Major GC会提高效率。可以认为回收老年代的时候完成了一次FullGC。
所以可以认为 MajorGC = FullGC
选项分类
#默认JVM试图分配最大内存的总内存的1/4,初始化默认总内存为总内存的1/64
按工作模式不同:指的是GC线程和工作线程是否一起运行
按回收线程数:指的是GC线程是否串行或并行执行
对JVM调整策略应用极广
注意: 在不同领域和场景对JVM需要不同的调整策略
一般情况下,大概可以使用以下原则:
新生代串行收集器Serial:单线程、独占式串行,采用复制算法,简单高效但会造成STW
新生代并行回收收集器PS(Parallel Scavenge):多线程并行、独占式,会产生STW, 使用复制算法
关注调整吞吐量,此收集器关注点是达到一个可控制的吞吐量
高吞吐量可以高效率利用CPU时间,尽快完成运算任务,主要适合在后台运算而不需要太多交互的任务
新生代并行收集器ParNew:就是Serial 收集器的多线程版,将单线程的串行收集器变成了多线程并行、独占式,使用复制算法,相当于PS的改进版
经常和CMS配合使用,关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,适合需要与用户交互的程序,良好的响应速度能提升用户体验
JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= -XX:MaxNewSize= "
-server:服务器模式
-Xms:堆内存初始化大小
-Xmx:堆内存空间上限
-XX:NewSize=:新生代空间初始化大小
-XX:MaxNewSize=:新生代空间最大值
案例:
[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
......
......
常用属性:
compressionMinSize:启用压缩传输的数据流最小值,单位是字节
compressableMimeType:定义启用压缩功能的MIME类型text/html, text/xml, text/css,text/javascript
以github 上 java 开源项目dubbo-admin 为例
github 说明:
https://github.com/apache/dubbo-admin/
官方部署过程
production Setup
Clone source code on develop branch git clone https://github.com/apache/dubbo-
admin.git
Specify registry address in dubbo-admin-
server/src/main/resources/application.properties
Build
mvn clean package -Dmaven.test.skip=true
Start
mvn --projects dubbo-admin-server spring-boot:run
OR
cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar
Visit http://localhost:8080
Default username and password is root
Maven 翻译为"专家"、“内行”,是 Apache 基金会旗下的一个纯 Java 开发的开源项目
Maven 是一个项目管理工具,可以对 Java项目进行构建、解决打包依赖等。
POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个 XML 文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖等,在执行任务或目标时,Maven 会在当前目录中查找 pom 文件,通过读取pom文件获取所需的配置信息,然后执行目标
pom.xml 文件中可以指定以下配置:
项目依赖
插件
执行目标
项目构建 profile
项目版本
项目开发者列表 相关邮件列表信息
用 指定项目打包形式,jar或者war
安装maven前必须安装java 环境:
Maven 3.3 要求 JDK 1.7 或以上
Maven 3.2 要求 JDK 1.6 或以上
Maven 3.0/3.1 要求 JDK 1.5 或以上
范例:Ubuntu20.04安装maven
root@ubuntu2004 ~]#apt -y install maven
#自动安装Openjdk11
[root@ubuntu2004 ~]#java -version
openjdk version "11.0.15" 2022-04-19
OpenJDK Runtime Environment (build 11.0.15+10-Ubuntu-0ubuntu0.20.04.1)
OpenJDK 64-Bit Server VM (build 11.0.15+10-Ubuntu-0ubuntu0.20.04.1, mixed mode,
sharing)
[root@ubuntu2004 ~]#mvn -v
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.15, vendor: Private Build, runtime: /usr/lib/jvm/java-11-
openjdk-amd64
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-110-generic", arch: "amd64", family: "unix"
#镜像加速
[root@ubuntu2004 ~]#vim /etc/maven/settings.xml
nexus-aliyun
*
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public
二进制安装
[root@ubuntu1804 ~]#apt update
[root@ubuntu1804 ~]#apt install openjdk-8-jdk -y
[root@ubuntu1804 ~]#java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-8u282-b08-0ubuntu1~18.04-b08)
OpenJDK 64-Bit Server VM (build 25.282-b08, mixed mode)
[root@ubuntu1804 ~]#wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
[root@ubuntu1804 ~]#tar xf apache-maven-3.6.3-bin.tar.gz -C /usr/local/
[root@ubuntu1804 ~]#ln -s /usr/local/apache-maven-3.6.3/ /usr/local/maven
[root@ubuntu1804 ~]#echo 'PATH=/usr/local/maven/bin:$PATH' > /etc/profile.d/maven.sh
[root@ubuntu1804 ~]#echo 'export MAVEN_HOME=/usr/local/maven' >> /etc/profile.d/maven.sh
[root@ubuntu1804 ~]#. /etc/profile.d/maven.sh
[root@ubuntu1804 ~]#mvn -v
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/maven
Java version: 1.8.0_282, vendor: Private Build, runtime: /usr/lib/jvm/java-8-
openjdk-amd64/jre
Default locale: en_HK, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-112-generic", arch: "amd64", family: "unix"
#镜像加速
[root@ubuntu1804 ~]#vim /usr/local/maven/conf/settings.xml
nexus-aliyun
*
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public
Maven工程构建的各个环节
编译安装 spring-boot 项目
[root@ubuntu1804 ~]#apt -y install maven git
#镜像加速
[root@ubuntu1804 ~]#vim /etc/maven/settings.xml
nexus-aliyun
*
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public
[root@ubuntu1804 ~]#cd /data
[root@ubuntu1804 data]#git clone https://gitee.com/lbtooth/spring-boot-helloWorld.git
[root@ubuntu1804 data]#cd spring-boot-helloWorld/
[root@ubuntu1804 spring-boot-helloWorld]#ls
deploy Dockerfile Jenkinsfile LICENSE pom.xml README.md src
[root@ubuntu1804 spring-boot-helloWorld]#ls src
main test
#编译
[root@ubuntu1804 spring-boot-helloWorld]#mvn -T 4 clean package Dmaven.test.skip=true
......
[INFO] --- maven-jar-plugin:3.1.1:jar (default-jar) @ spring-boot-helloworld ---
[INFO] Building jar: /root/spring-boot-helloWorld/target/spring-boot-helloworld-
0.9.0-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.3.RELEASE:repackage (repackage) @
spring-boot-helloworld ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 57.183 s (Wall Clock)
[INFO] Finished at: 2022-06-15T09:53:14+08:00
[INFO] ------------------------------------------------------------------------
[root@ubuntu1804 spring-boot-helloWorld]#ls target/
classes maven-archiver spring-boot-
helloworld-0.9.0-SNAPSHOT.jar.original
generated-sources maven-status surefire-
reports
generated-test-sources spring-boot-helloworld-0.9.0-SNAPSHOT.jar test-classes
#默认为8080端口
[root@ubuntu1804 spring-boot-helloWorld]#java -jar target/spring-boot-helloworld-0.9.0-SNAPSHOT.jar --server.port=8888
Nexus 是一个强大的 Maven 和其它仓库的管理器,它极大地简化了自己内部仓库的维护和外部仓库的访问。
Nexus 官网:
https://www.sonatype.com/
官方下载页面
https://help.sonatype.com/repomanager3/download/download-archives—repository-manager-3
安装要求
https://help.sonatype.com/repomanager3/installation/system-requirements
#官方要求内存8G以上,太小比如4G以下会导致无法启动
注意: : 安装Nexus建议内存至少4G以上
#安装JDK
[root@ubuntu1804 ~]#apt install openjdk-8-jdk -y
[root@ubuntu1804 ~]#java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-8u282-b08-0ubuntu1~18.04-b08)
OpenJDK 64-Bit Server VM (build 25.282-b08, mixed mode)
#可能需要科学上网下载
[root@ubuntu1804 ~]#wget https://download.sonatype.com/nexus/3/nexus-3.29.2-02-
unix.tar.gz
[root@ubuntu1804 ~]#ll -h nexus-3.29.2-02-unix.tar.gz
-rw-r--r-- 1 root root 155M Feb 18 17:09 nexus-3.29.2-02-unix.tar.gz
[root@ubuntu1804 ~]#tar xf nexus-3.29.2-02-unix.tar.gz -C /usr/local/
[root@ubuntu1804 ~]#ln -s /usr/local/nexus-3.29.2-02/ /usr/local/nexus
[root@ubuntu1804 ~]#ln -s /usr/local/nexus/bin/nexus /usr/bin/
[root@ubuntu1804 ~]#file /usr/local/nexus/bin/nexus
bin/nexus: POSIX shell script, ASCII text executable, with very long lines
#查看配置文件,可以在此文件中修改端口等配置
[root@ubuntu1804 ~]#cat /usr/local/nexus/etc/nexus-default.properties
## DO NOT EDIT - CUSTOMIZATIONS BELONG IN $data-dir/etc/nexus.properties
##
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-
http.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/
# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature
nexus.hazelcast.discovery.isEnabled=true
#前台运行
[root@ubuntu1804 ~]#nexus run
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
.....
2021-02-18 17:20:21,580+0800 INFO [jetty-main-1] *SYSTEM
org.eclipse.jetty.server.Server - Started @37755ms
2021-02-18 17:20:21,581+0800 INFO [jetty-main-1] *SYSTEM
org.sonatype.nexus.bootstrap.jetty.JettyServer -
-------------------------------------------------
Started Sonatype Nexus OSS 3.29.2-02
-------------------------------------------------
#注意: 如果内存太小,可能会出现下面提示错误
[root@ubuntu1804 ~]#nexus run
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000717000000,
1890582528, 0) failed; error='Cannot allocate memory' (errno=12)
#后台运行
[root@ubuntu1804 ~]#nexus start
#查看状态
[root@ubuntu1804 ~]#nexus status
#停止服务
[root@ubuntu1804 ~]#nexus stop
#查看端口
[root@ubuntu1804 ~]#ss -ntlp|grep java
LISTEN 0 50 0.0.0.0:8081 0.0.0.0:* users:(("java",pid=20564,fd=798))
LISTEN 0 1 127.0.0.1:38147 0.0.0.0:* users:(("java",pid=20564,fd=125))
#创建service文件
#参考链接https://help.sonatype.com/repomanager3/installation/system-requirements
[root@ubuntu1804 ~]#cat /lib/systemd/system/nexus.service
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/usr/local/nexus/bin/nexus start
ExecStop=/usr/local/nexus/bin/nexus stop
User=root
#User=nexus
Restart=on-abort
[Install]
WantedBy=multi-user.target
[root@ubuntu1804 ~]#systemctl daemon-reload
[root@ubuntu1804 ~]#systemctl enable --now nexus.service
[root@ubuntu1804 ~]#tail /var/log/syslog
Aug 4 12:20:23 ubuntu1804 systemd[1]: Starting nexus service...
Aug 4 12:20:23 ubuntu1804 nexus[9534]: WARNING:
************************************************************
Aug 4 12:20:23 ubuntu1804 nexus[9534]: WARNING: Detected execution as "root"
user. This is NOT recommended!
Aug 4 12:20:23 ubuntu1804 nexus[9534]: WARNING:
************************************************************
Aug 4 12:20:23 ubuntu1804 nexus[9534]: Starting nexus
Aug 4 12:20:23 ubuntu1804 systemd[1]: Started nexus service.
Aug 4 12:21:58 ubuntu1804 systemd[1]: Reloading.
通过浏览器访问
http://nexus主机:8081/
需要在右上角点Sign in 进行登录才能进行管理
查看默认密码
[root@ubuntu1804 ~]#cat /usr/local/sonatype-work/nexus3/admin.password
设置密码,使用admin用户和上面的密码登录
通过 Nexus 构建为公司内网 Yum 和 Apt 仓库,代理至阿里云镜像安装包
,可能会出现下面提示错误
[root@ubuntu1804 ~]#nexus run
WARNING: ************************************************************
WARNING: Detected execution as “root” user. This is NOT recommended!
WARNING: ************************************************************
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000717000000,
1890582528, 0) failed; error=‘Cannot allocate memory’ (errno=12)
#后台运行
[root@ubuntu1804 ~]#nexus start
#查看状态
[root@ubuntu1804 ~]#nexus status
#停止服务
[root@ubuntu1804 ~]#nexus stop
#查看端口
[root@ubuntu1804 ~]#ss -ntlp|grep java
LISTEN 0 50 0.0.0.0:8081 0.0.0.0:* users:((“java”,pid=20564,fd=798))
LISTEN 0 1 127.0.0.1:38147 0.0.0.0:* users:((“java”,pid=20564,fd=125))
#创建service文件
#参考链接https://help.sonatype.com/repomanager3/installation/system-requirements
[root@ubuntu1804 ~]#cat /lib/systemd/system/nexus.service
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/usr/local/nexus/bin/nexus start
ExecStop=/usr/local/nexus/bin/nexus stop
User=root
#User=nexus
Restart=on-abort
[Install]
WantedBy=multi-user.target
[root@ubuntu1804 ~]#systemctl daemon-reload
[root@ubuntu1804 ~]#systemctl enable --now nexus.service
[root@ubuntu1804 ~]#tail /var/log/syslog
Aug 4 12:20:23 ubuntu1804 systemd[1]: Starting nexus service…
Aug 4 12:20:23 ubuntu1804 nexus[9534]: WARNING:
Aug 4 12:20:23 ubuntu1804 nexus[9534]: WARNING: Detected execution as “root”
user. This is NOT recommended!
Aug 4 12:20:23 ubuntu1804 nexus[9534]: WARNING:
Aug 4 12:20:23 ubuntu1804 nexus[9534]: Starting nexus
Aug 4 12:20:23 ubuntu1804 systemd[1]: Started nexus service.
Aug 4 12:21:58 ubuntu1804 systemd[1]: Reloading.
### 10.2.2 登录 web 界面初始化
通过浏览器访问
http://nexus主机:8081/
需要在右上角点Sign in 进行登录才能进行管理
[外链图片转存中...(img-IyEgSOaf-1655604069980)]
查看默认密码
[root@ubuntu1804 ~]#cat /usr/local/sonatype-work/nexus3/admin.password
设置密码,使用admin用户和上面的密码登录
[外链图片转存中...(img-y3Saqglp-1655604069980)]
## 10.3 使用 Nexus 构建私有 Yum 和 Apt 仓库
通过 Nexus 构建为公司内网 Yum 和 Apt 仓库,代理至阿里云镜像安装包