文章目录

  • 1web技术
    • 1.1 HTTP协议和B/S 结构
    • 1.2 前端三大核心技术
      • 1.2.1 HTML
      • 1.2.2 CSS(Cascading Style Sheets)层叠样式表
      • 1.2.3 JavaScript
  • 2Java基础
    • 2.1 WEB架构
      • 2.1.1 web资源和访问
      • 2.1.2 后台应用架构
    • 2.2 Java
      • 2.2.2 java 组成
      • 2.2.4 JDK
  • 3tomcat基础功能
    • 3.1 Tomcat历史和介绍
      • 3.1.1 WEB应用服务器
      • 3.1.2 Tomcat 介绍
      • 3.1.3 Tomcat 各版本区别
    • 3.2 安装 Tomcat
      • 3.2.1 基于包安装 Tomcat
      • 3.2.2 二进制安装 Tomcat
    • 3.3 tomcat的文件结构和组成
      • 3.3.1 目录结构
      • 3.3.3 组件
      • 3.4.4 应用部署实现
  • 4结合反向代理部署tomcat服务
    • 4.1 常见部署方式介绍
    • 4.2 利用 nginx 反向代理实现全部转发置指定同一个虚拟主机
    • 4.3 利用nginx实现动静分离代理
    • 4.5 实现 tomcat 负载均衡
      • 4.5.1 HTTP的无状态,有连接和短连接
      • 4.5.2 会话保持方式
      • 4.5.3实现 https 的负载均衡
  • 5tomcat session负载集群
    • 5.1 配置说明
    • 5.2 实战案例: 实现 Tomcat Session 集群
  • 6memcached
    • 6.4 Memcached 工作机制
      • 6.4.1 内存分配机制
      • 6.4.2 懒过期 Lazy Expiration
      • 6.4.4 集群
    • 6.5 安装和启动
      • 6.5.1 yum安装
    • **6.6 使用 memcached**
      • 6.6.1 memcached 开发库和工具
      • 6.6.2 memcached 操作命令
      • 6.6.3 python 语言连接 memcached
  • 7session共享服务
    • 7.1 msm 介绍
    • 7.2 安装
      • 7.3 sticky 模式
      • 7.3.1 sticky 模式工作原理
      • 7.3.2 配置过程
      • 7.3.3 实战案例 1 : tomcat和memcached集成在一台主机
        • 7.3.3.1 配置nginx充当proxy
        • 7.3.3.2 配置memcached
        • 7.3.3.3 配置 tomcat
        • 7.3.3.4python测试脚本
    • 7.4 non-sticky 模式
      • 7.4.1 non-sticky 模式工作原理
      • 7.4.2 memcached配置
      • 7.4.3 redis 配置
  • 8tomcat性能优化
    • 8.1 JVM组成
    • 8.2 GC (Garbage Collection) 垃圾收集器
      • 8.2.1 Garbage 垃圾确定方法
      • 8.2.2 垃圾回收基本算法
        • 8.2.2.1 标记-清除 Mark-Sweep
        • 8.2.2.2 标记-压缩 (压实)Mark-Compact
        • 8.2.2.3 复制 Copying
        • 8.2.2.5 STW
      • 8.2.3 分代堆内存GC策略
        • 8.2.3.1 堆内存分代
        • 8.2.3.2 年轻代回收 Minor GC
        • 8.2.3.3 老年代回收 Major GC
      • 8.2.4 java 内存调整相关参数
    • 8.2.5 垃圾收集方式
      • 8.2.6 调整策略
      • 8.2.7 垃圾回收器
    • 8.4 Tomcat 性能优化常用配置
      • 8.4.1 内存空间优化
      • 8.4.2 线程池调整
  • 9Java程序编译
    • 9.1 源代码克隆与编译过程说明
    • 9.2 maven 部署准备
      • 9.2.1 maven 介绍
      • 9.2.2 maven 安装
    • 9.3 Maven 的打包命令说明
    • 9.4 执行 java 代码编译实战案例
  • 10 私有仓库nexus
    • 10.1 Nexus 介绍
    • 10.2 部署 Nexus
      • 10.2.1 下载并启动 Nexus
      • 10.2.2 登录 web 界面初始化
    • 10.3 使用 Nexus 构建私有 Yum 和 Apt 仓库

企业级WEB应用服务器TOMCAT

1web技术

1.1 HTTP协议和B/S 结构

客户端和服务端往往处在不同的物理主机上,它们分属不同的进程,这些进程间需要通信。跨主机的进程间通信需要使用网络编程。最常见的网络编程接口是Socket。

Socket称为套接字,本意是插座。也就是说网络通讯需要两端,如果一端被动的接收另一端请求并提供计算和数据的称为服务器端,另一端往往只是发起计算或数据请求,称为客户端。
这种编程模式称为Client/Server编程模式,简称C/S编程。开发的程序也称为C/S程序。C/S编程往往使用传输层协议(TCP/UDP),较为底层,比如:QQ,迅雷, 云音乐, 云盘, foxmail,xshell等

有一部分程序员还是要编写HTML、CSS、JavaScript,这些代码运行在浏览器端,称为WEB前端编程。合起来称为Browser/Server编程,即B/S编程。

1.2 前端三大核心技术

1.2.1 HTML

HTML(HyperText Markup Language)超文本标记语言,它不同于一般的编程语言。超文本即超出纯
文本的范畴,例如:描述文本颜色、大小、字体等信息,或使用图片、音频、视频等非文本内容。

HTML由一个个的标签(标记)组成,这些标签各司其职,有的提供网页信息,有的负责文字,有的负责图片,有的负责网页布局,所以一个HTML文件,是由格式标签和数据组成。

1.2.2 CSS(Cascading Style Sheets)层叠样式表

HTML本身为了格式化显示文本,但是当网页呈现大家面前的时候,需求HTML提供更多样式能力。这
使得HTML变得越来越臃肿。这促使了CSS的诞生。

1.2.3 JavaScript

Javascript 简称JS,是一种动态的弱类型脚本解释性语言,和HTML、CSS并称三大WEB核心技术,得到
了几乎主流浏览器支持。

1994年,网景Netscape公司成立并发布了Netscape Navigator浏览器,占据了很大的市场份额,网景
意识到WEB需要动态,需要一种技术来实现。

2Java基础

2.1 WEB架构

2.1.1 web资源和访问

PC 端或移动端浏览器访问

从静态服务器请求HTML、CSS、JS等文件发送到浏览器端,浏览器端接收后渲染在浏览器上
从图片服务器请求图片资源显示

从业务服务器访问动态内容,动态内容是请求后有后台服务访问数据库后得到的,最终返回到浏览器端

手机 App 访问

内置了HTML和JS文件,不需要从静态WEB服务器下载 JS 或 HTML。为的就是减少文件的发送,现代前
端开发使用的JS文件太多或太大了

有必要就从图片服务器请求图片,从业务服务器请求动态数据

客户需求多样,更多的内容还是需要由业务服务器提供,业务服务器往往都是由一组服务器组成。

2.1.2 后台应用架构

  • 单体架构

传统架构(单机系统),一个项目一个工程:比如商品、订单、支付、库存、登录、注册等等,统一部署,一个进程

all in one的架构方式,把所有的功能单元放在一个应用里。然后把整个应用部署到一台服务器上。如果负载能力不行,将整个应用进行水平复制,进行扩展,然后通过负载均衡实现访问。

特别是对于一个大型应用,我们不可能吧所有内容都放在一个应用里面,我们如何维护、如何分工合作都是问题。如果项目庞大,管理难度大

  • 微服务

微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去掉耦合,每一个微服务提供单个业务功能,一个服务只做一件事。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等

从技术角度讲就是一种小而独立的处理过程,类似与进程的概念,能够自行单独启动或销毁

微服务架构(分布式系统),各个模块/服务,各自独立出来,“让专业的人干专业的事”,独立部署。分布式系统中,不同的服务可以使用各自独立的数据库。

微服务的实现框架有多种,不同的应用架构,部署方式也有不同

常见的微服务框架

  • Dubbo

阿里开源贡献给了ASF,目前已经是Apache的顶级项目

一款高性能的Java RPC服务框架,微服务生态体系中的一个重要组件

将单体程序分解成多个功能服务模块,模块间使用Dubbo框架提供的高性能RPC通信

内部协调使用Zookeeper,实现服务注册、服务发现和服务治理

  • Spring cloud

一个完整的微服务解决方案,相当于Dubbo的超集

微服务框架,将单体应用拆分为粒度更小的单一功能服务

基于HTTP协议的REST(Representational State Transfer 表述性状态转移)风格实现模块间通信

2.2 Java

跨平台运行

2.2.2 java 组成

Java 包含下面部分:

  • 语言、语法规范。关键字,如: if、for、class等
  • 源代码 source code
  • 依赖库,标准库(基础)、第三方库(针对某些应用)。底层代码太难使用且开发效率低,封装成现成的库
  • JVM虚拟机。将源代码编译为中间码即字节码后,再运行在JVM之上

jsp

JSP本质是提供一个HTML模板,也就是在网页中预留以后填充的空,后续将Java程序运行生成的数据对HTML进行填空就可以了。如果网页布局需要调整,JAVA源代码不需要很大的调整

2.2.4 JDK

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:~# 

jdk11的安装

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

3tomcat基础功能

3.1 Tomcat历史和介绍

3.1.1 WEB应用服务器

Web 应用服务器的使用

3.1.2 Tomcat 介绍

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不完整实现。

3.1.3 Tomcat 各版本区别

3.2 安装 Tomcat

3.2.1 基于包安装 Tomcat

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/

3.2.2 二进制安装 Tomcat

注意: 安装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.shPATH=/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容器,用于处理servletCatalina是美国西海岸靠近洛杉矶22英里的一个小岛,因为其风景秀丽而著名,曾被评为全美最漂亮的小岛。Servlet运行模块的最早开发者Craig McClanahan因为喜欢Catalina岛,故以Catalina命名他所开这个模块,另外在开发的早期阶段,Tomcat是被搭建在一个叫Avalon的服务器框架上,而Avalon则是Catalina岛上的一个小镇的名字,于是想一个与小镇名字相关联的单词也是自然而然。设计者估计是想把tomcat设计成最美的轻量级容器吧。下图为该小岛。

3.3 tomcat的文件结构和组成

3.3.1 目录结构

配置规则:

  • webApp的专有配置优先于系统的全局配置
  • 修改系统的全局配置文件,需要重新启动服务生效
  • 修改 webApp的专有配置,无需重启即可生效

3.3.3 组件

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

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" /><Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /><Engine name="Catalina" defaultHost="localhost"><Host name="localhost"  appBase="webapps" unpackWARs="true"
autoDeploy="true"><Context ><Context /></Host></Engine></Service>
</Server>

3.4.4 应用部署实现

实站案例: 部署基于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
<tomcat-users xmlns="http://tomcat.apache.org/xml"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"version="1.0">
#加下面两行,指定用户和密码
<role rolename="manager-gui"/>
<user username="admin" password="123456" roles="manager-gui"/>
</tomcat-users>
#修改全局配置文件需要重启服务生效
[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<Context antiResourceLocking="false" privileged="true" ><CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"sameSiteCookies="strict" /><Valve className="org.apache.catalina.valves.RemoteAddrValve"allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|10\.0\.0.\d+" /> #增加10网段<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>#修改WebApp的配置无需重启服务即可生效

再次通过浏览器访问两个按钮Server Status和Manager App,可以看到以下管理界面,输入前面的用户和密码进行登录


或者这样访问:

curl http://tomcat:123456@10.0.0.35:8080/manager/status
links -dump http://tomcat:123456@10.0.0.35: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
<?xml version="1.0" encoding="UTF-8"?><Context antiResourceLocking="false" privileged="true" ><CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"sameSiteCookies="strict" /><!--<Valve className="org.apache.catalina.valves.RemoteAddrValve"allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />-->  #方法二注释IP地址,解除限制<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>[root@localhost conf]# pwd
/usr/local/tomcat/conf
[root@localhost conf]# vim tomcat-users.xml<role rolename="manager-gui"/><role rolename="admin-gui"/><user username="admin" password="123456" roles="manager-gui,admin-gui"/>   [root@localhost conf]# systemctl restart tomcat

多虚拟主机配置

  • name 必须是主机名,用主机名来匹配
  • appBase 当前主机的网页根目录,是相对于 $CATALINA_HOME ,也可以使用绝对路径
  • unpackWARs 是否自动解压war格式
  • autoDeploy 热部署,自动加载并运行应用
[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<Host name="www.ehuo.org"  appBase="/data/ehuosite"unpackWARs="true" autoDeploy="true">                                                       </Host>
[root@localhost conf]# systemctl restart tomcat

虚拟主机的访问日志设置

[root@localhost conf]# vim server.xml <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="www.ehuo.org_access_log" suffix=".txt"                                          pattern="%h %l %u %t &quot;%r&quot; %s %b" />[root@localhost ~]# tail -f /usr/local/tomcat/logs/www.ehuo.org_access_log.2022-06-14.txt10.0.0.1 - - [14/Jun/2022:17:42:29 +0800] "GET / HTTP/1.1" 200 197

4结合反向代理部署tomcat服务

4.1 常见部署方式介绍

  • standalone模式,Tomcat单独运行,直接接受用户的请求,不推荐。

  • 反向代理,单机运行,提供了一个Nginx作为反向代理,可以做到静态由nginx提供响应,动态jsp代理给Tomcat

​ LNMT:Linux + Nginx + MySQL + Tomcat

​ LAMT:Linux + Apache(Httpd)+ MySQL + Tomcat

  • 前置一台Nginx,给多台Tomcat实例做反向代理和负载均衡调度,Tomcat上部署的纯动态页面更适合

​ LNMT:Linux + Nginx + MySQL + Tomcat

  • 多级代理

​ LNNMT:Linux + Nginx + Nginx + MySQL + Tomcat

4.2 利用 nginx 反向代理实现全部转发置指定同一个虚拟主机

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

4.3 利用nginx实现动静分离代理

vim nginx.conf
root /usr/share/nginx/html;
#下面行可不加
#location / {
#  root /data/webapps/ROOT;
#  index index.html;
#}
# ~* 不区分大小写
location ~* \.jsp$ {proxy_pass http://node1.magedu.com:8080; #注意: 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留住;

4.5 实现 tomcat 负载均衡

动态服务器的问题,往往就是并发能力太弱,往往需要多台动态服务器一起提供服务。如何把并发的压力分摊,这就需要调度,采用一定的调度策略,将请求分发给不同的服务器,这就是Load Balance负载均衡。

当单机Tomcat,演化出多机多级部署的时候,一个问题便凸显出来,这就是Session。而这个问题的由来,都是由于HTTP协议在设计之初没有想到未来的发展。

4.5.1 HTTP的无状态,有连接和短连接

  • 无状态:指的是服务器端无法知道2次请求之间的联系,即使是前后2次请求来自同一个浏览器,也没有任何数据能够判断出是同一个浏览器的请求。后来可以通过cookie、session机制来判断。
  • 有连接:是因为它基于TCP协议,是面向连接的,需要3次握手、4次断开。
  • 短连接:Http 1.1之前,都是一个请求一个连接,而Tcp的连接创建销毁成本高,对服务器有很大的影响。所以,自Http 1.1开始,支持keep-alive,默认也开启,一个连接打开后,会保持一段时间(可设置),浏览器再访问该服务器就使用这个Tcp连接,减轻了服务器压力,提高了效率

4.5.2 会话保持方式

Session绑定

  • nginx:source ip, cookie

  • HAProxy:source ip, cookie

    优点:简单易配置

​ 缺点:如果目标服务器故障后,如果没有做sessoin持久化,就会丢失session,此方式生产很少使用

Session 复制集群

tomcat自己的提供的多播集群,通过多播将任何一台的session同步到其它节点。

缺点

  • Tomcat的同步节点不宜过多,互相即时通信同步session需要太多带宽
  • 每一台都拥有全部session,内存损耗太多

session 共享服务器,使用memcached、redis做共享的Session服务器,此为推荐方式

4.5.3实现 https 的负载均衡

[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
...
#添加下面行<Host name="blog.wangxiaochun.com"  appBase="/data/blog"unpackWARs="true" autoDeploy="true"></Host>
#添加上面行</Engine>
</Service>
</Server>
[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

5tomcat session负载集群

Tomcat 官方实现了 Session 的复制集群,将每个Tomcat的Session进行相互的复制同步,从而保证所有Tomcat都有相同的Session信息.

5.1 配置说明

配置说明

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侦听器

5.2 实战案例: 实现 Tomcat 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<Host name="www.ehuo.org"  appBase="/data/ehuosite"unpackWARs="true" autoDeploy="true">                                                       #其他略去<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"address="10.0.0.15"  #只改此行port="4000"autoBind="100"selectorTimeout="5000"maxThreads="6"/></Host>
[root@localhost conf]# systemctl restart tomcat<Host name="t2.magedu.com" appBase="/data/webapps" autoDeploy="true" >其他略去<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"address="10.0.0.35"  #只改此行port="4000"autoBind="100"selectorTimeout="5000"maxThreads="6"/>

修改应用的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
</description>
<distributable/>  #添加此行
</web-app>
#注意权限
[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={}]]#另一台也是
最后测试

6memcached

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共享

6.4 Memcached 工作机制

6.4.1 内存分配机制

应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用。

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:Slab按照Chunk的大小分组,就组成不同的Slab Class, 第一个Chunk大小为 96B的Slab为Class1,Chunk 120B为Class 2,如果有100bytes要存,那么Memcached会选择下图中SlabClass 2 存储,因为它是120bytes的Chunk。Slab之间的差异可以使用Growth Factor 控制,默认1.25。

查看Slab Class

#-f, --slab-growth-factor=<num> 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)

6.4.2 懒过期 Lazy Expiration

memcached不会监视数据是否过期,而是在取数据时才看是否过期,如果过期,把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据。

6.4.4 集群

Memcached集群,称为基于客户端的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群

Memcached集群内部并不互相通信,一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点

6.5 安装和启动

6.5.1 yum安装

[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 ~]# 

6.6 使用 memcached

6.6.1 memcached 开发库和工具

与memcached通信的不同语言的连接器。libmemcached提供了C库和命令行工具。

6.6.2 memcached 操作命令

五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:

  • set
  • add
  • replace
  • get
  • delete
前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令,都使用如下所示的语法:
command <key> <flags> <expiration time> <bytes>
<value>
#参数说明如下:
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

6.6.3 python 语言连接 memcached

[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

7session共享服务

7.1 msm 介绍

msm(memcached session manager)提供将Tomcat的session保持到memcached或redis的程序,可以实现高可用。

支持Tomcat的 6.x、7.x、8.x、9.x

7.2 安装

将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

7.3 sticky 模式

7.3.1 sticky 模式工作原理

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艺术显示了此设置。
<t1>  <t2>. \ / ..  X .. / \ .
<m1>  <m2>

t1和m1部署可以在一台主机上,t2和m2部署也可以在同一台。

当新用户发请求到Tomcat1时, Tomcat1生成session返回给用户的同时,也会同时发给memcached2备份。即Tomcat1 session为主session,memcached2 session为备用session,使用memcached相当于备份了一Session

如果Tomcat1发现memcached2 失败,无法备份Session到memcached2,则将Sessoin备份存放memcached1中

7.3.2 配置过程

修改tomcat配置

修改 $CATALINA_HOME/conf/context.xml

特别注意,t1配置中为failoverNodes=“n1”, t2配置为failoverNodes=“n2”

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

配置说明

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

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

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

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

7.3.3 实战案例 1 : tomcat和memcached集成在一台主机

环境准备:

  • 时间同步,确保NTP或Chrony服务正常运行。
  • 防火墙规则
  • 禁用SELinux
  • 三台主机
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

7.3.3.1 配置nginx充当proxy

[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

7.3.3.2 配置memcached

#在 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 配置 tomcat

7.3.3.3.1 配置 tomcat1

[root@t1 tomcat]#vim conf/server.xml
<Host name="www.ehuo.org"  appBase="/data/webapps"unpackWARs="true" autoDeploy="true"></Host>[root@t1 tomcat]#vim conf/context.xml
<Context>...<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="n1:10.0.0.15:11211,n2:10.0.0.35:11211"failoverNodes="n1"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
</Context>
#将相关包传到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.*" %>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>tomcat test</title>
</head>
<body>
<h1> tomcat website </h1>
<div>On <%=request.getServerName() %></div>
<div><%=request.getLocalAddr() + ":" + request.getLocalPort() %></div>
<div>SessionID = <span style="color:blue"><%=session.getId() %></span></div>
<%=new Date()%>
</body>
</html>

7.3.3.3.2 配置 tomcat2

[root@t2 tomcat]#vim conf/server.xml
<Host name="www.ehuo.org"  appBase="/data/webapps"unpackWARs="true" autoDeploy="true"></Host>[root@t1 tomcat]#vim conf/context.xml
<Context>...<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="n1:10.0.0.15:11211,n2:10.0.0.35:11211"failoverNodes="n2"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
</Context>

7.3.3.4python测试脚本

在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)', {})

7.4 non-sticky 模式

7.4.1 non-sticky 模式工作原理

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存储节点。

7.4.2 memcached配置

放到 $CATALINA_HOME/conf/context.xml 中

<Context>
...<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="n1:10.0.0.101:11211,n2:10.0.0.102:11211"sticky="false"sessionBackupAsync="false"lockingMode="uriPattern:/path1|/path2"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
</Context>

7.4.3 redis 配置

支持将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 中

<Context>
...<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="redis://:password@redis.example.com:portnumber"sticky="false"sessionBackupAsync="false"lockingMode="uriPattern:/path1|/path2"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFac
tory"/>
</Context>

浏览器访问,使用redis相关工具可以观察到redis中的信息

8tomcat性能优化

在目前流行的互联网架构中,Tomcat在目前的网络编程中是举足轻重的,由于Tomcat的运行依赖于JVM,从虚拟机的角度把Tomcat的调整分为外部环境调优 JVM 和 Tomcat 自身调优两部分

8.1 JVM组成

JVM 组成部分

  • 类加载子系统: 使用Java语言编写.java Source Code文件,通过javac编译成.class Byte Code文件。class loader类加载器将所需所有类加载到内存,必要时将类实例化成实例
  • 运行时数据区: 最消耗内存的空间,需要优化
  • 执行引擎: 包括JIT (JustInTimeCompiler)即时编译器, GC垃圾回收器
  • 本地方法接口: 将本地方法栈通过JNI(Java Native Interface)调用Native Method Libraries, 比如:C,C++库等,扩展Java功能,融合不同的编程语言为Java所用

JVM运行时数据区域由下面部分构成

  • Method Area (线程共享):方法区是所有线程共享的内存空间,存放已加载的类信息(构造方法,接口定义),常量(final),静态变量(static), 运行时常量池等。但实例变量存放在堆内存中. 从JDK8开始此空间由永久代改名为元空间
  • heap (线程共享):堆在虚拟机启动时创建,存放创建的所有对象信息。如果对象无法申请到可用内存将抛出OOM异常.堆是靠GC垃圾回收器管理的,通过-Xmx -Xms 指定最大堆和最小堆空间大小
  • **Java stack (线程私有):**Java栈是每个线程会分配一个栈,存放java中8大基本数据类型,对象引用,实例的本地变量,方法参数和返回值等,基于FILO()(First In Last Out),每个方法为一个栈帧
  • **Program Counter Register (线程私有):**PC寄存器就是一个指针,指向方法区中的方法字节码,每一个线程用于记录当前线程正在执行的字节码指令地址。由执行引擎读取下一条指令.因为线程需要切换,当一个线程被切换回来需要执行的时候,知道执行到哪里了
  • **(线程私有):**本地方法栈为本地方法执行构建的内存空间,存放本地方法执行时的局部变量、操作数等。

所谓本地方法,使用native 关健字修饰的方法,比如:Thread.sleep方法. 简单的说是非Java实现的方法,例如操作系统的C编写的库提供的本地方法,Java调用这些本地方法接口执行。但是要注意,本地方法应该避免直接编程使用,因为Java可能跨平台使用,如果用了Windows API,换到了Linux平台部署就有了问题

8.2 GC (Garbage Collection) 垃圾收集器

在堆内存中如果创建的对象不再使用,仍占用着内存,此时即为垃圾.需要即使进行垃圾回收,从而释放内存空间给其它对象使用

堆内存里面经常创建、销毁对象,内存也是被使用、被释放。如果不妥善处理,一个使用频繁的进程,可能会出现虽然有足够的内存容量,但是无法分配出可用内存空间,因为没有连续成片的内存了,内存全是碎片化的空间。

所以需要有合适的垃圾回收机制,确保正常释放不再使用的内存空间,还需要保证内存空间尽可能的保持一定的连续

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

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

8.2.1 Garbage 垃圾确定方法

  • 引用计数: 每一个堆内对象上都与一个私有引用计数器,记录着被引用的次数,引用计数清零,该对象所占用堆内存就可以被回收。循环引用的对象都无法将引用计数归零,就无法清除。Python中即使用此种方式
  • 根搜索(可达)算法 Root Searching

8.2.2 垃圾回收基本算法

8.2.2.1 标记-清除 Mark-Sweep

分垃圾标记阶段和内存释放两个阶段。

  • 标记阶段,找到所有可访问对象打个标记。清理阶段,遍历整个堆
  • 对未标记对象(即不再使用的对象)逐一进行清理。

特点:

优点:算法简单

缺点:标记-清除最大的问题会造成内存碎片,但是不浪费空间,效率较高(如果对象较多时,逐一删除效率也会受到影响)

8.2.2.2 标记-压缩 (压实)Mark-Compact

分垃圾标记阶段和内存整理两个阶段。

  • 标记阶段,找到所有可访问对象打个标记。
  • 内存清理阶段时,整理时将对象向内存一端移动,整理后存活对象连续的集中在内存一端。

特点:

标记-压缩算法好处是整理后内存空间连续分配,有大段的连续内存可分配,没有内存碎片。

缺点是内存整理过程有消耗,效率相对低下

8.2.2.3 复制 Copying

先将可用内存分为大小相同两块区域A和B,每次只用其中一块,比如A。当A用完后,则将A中存活的对象复制到B。复制到B的时候连续的使用内存,最后将A一次性清除干净。

特点

好处是没有碎片,复制过程中保证对象使用连续空间,且一次性清除所有垃圾,所以即使对象很多,收回效率也很高

缺点是比较浪费内存,只能使用原来一半内存,因为内存对半划分了,复制过程毕竟也是有代价。

8.2.2.4 多种算法总结

没有最好的算法,在不同场景选择最合适的算法

  • 效率: 复制算法>标记清除算法> 标记压缩算法
  • 内存整齐度: 复制算法=标记压缩算法> 标记清除算法
  • 内存利用率: 标记压缩算法=标记清除算法>复制算法

8.2.2.5 STW

对于大多数垃圾回收算法而言,GC线程工作时,停止所有工作的线程,称为Stop The World。GC 完成时,恢复其他工作线程运行。这也是JVM运行中最头疼的问题。

8.2.3 分代堆内存GC策略

上述垃圾回收算法都有优缺点,能不能对不同数据进行区分管理,不同分区对数据实施不同回收策略,分而治之。

8.2.3.1 堆内存分代

将heap内存空间分为三个不同类别: 年轻代、老年代、持久代

Heap堆内存分为

  • 年轻代Young:Young Generation

​ 伊甸园区eden: 只有一个,刚刚创建的对象

​ 幸存(存活)区Servivor Space:有2个幸存区,一个是from区,一个是to区。大小相等、地位相同、可互换。

​ from 指的是本次复制数据的源区.

​ to 指的是本次复制数据的目标区

  • 老年代Tenured:Old Generation, 长时间存活的对象

默认空间大小比例:

默认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");}
}

8.2.3.2 年轻代回收 Minor GC

  1. 起始时,所有新建对象(特大对象直接进入老年代)都出生在eden,当eden满了,启动GC。这个称
    为Young GC 或者 Minor GC。
  2. 先标记eden存活对象,然后将存活对象复制到s0(假设本次是s0,也可以是s1,它们可以调
    换),eden剩余所有空间都清空。GC完成。
  3. 继续新建对象,当eden再次满了,启动GC。
  4. 先同时标记eden和s0中存活对象,然后将存活对象复制到s1。将eden和s0清空,此次GC完成
  5. 继续新建对象,当eden满了,启动GC。
  6. 先标记eden和s1中存活对象,然后将存活对象复制到s0。将eden和s1清空,此次GC完成

通常场景下,大多数对象都不会存活很久,而且创建活动非常多,新生代就需要频繁垃圾回收。

但是,如果一个对象一直存活,它最后就在from、to来回复制,如果from区中对象复制次数达到阈值(默认15次,CMS为6次,可通过java的选项 -XX:MaxTenuringThreshold=N 指定),就直接复制到老年

8.2.3.3 老年代回收 Major GC

进入老年代的数据较少,所以老年代区被占满的速度较慢,所以垃圾回收也不频繁。

如果老年代也满了,会触发老年代GC,称为Old GC或者 Major GC。

由于老年代对象一般来说存活次数较长,所以较常采用标记-压缩算法。

当老年代满时,会触发 Full GC,即对所有"代"的内存进行垃圾回收

Minor GC比较频繁,Major GC较少。但一般Major GC时,由于老年代对象也可以引用新生代对象,所以先进行一次Minor GC,然后在Major GC会提高效率。可以认为回收老年代的时候完成了一次FullGC。

所以可以认为 MajorGC = FullGC

8.2.4 java 内存调整相关参数

选项分类

  • -选项名称 此为标准选项,所有HotSpot都支持
  • -X选项名称 此为稳定的非标准选项
  • -XX:选项名称 非标准的不稳定选项,下一个版本可能会取消

#默认JVM试图分配最大内存的总内存的1/4,初始化默认总内存为总内存的1/64

8.2.5 垃圾收集方式

按工作模式不同:指的是GC线程和工作线程是否一起运行

  • 独占垃圾回收器:只有GC在工作,STW 一直进行到回收完毕,工作线程才能继续执行
  • 并发垃圾回收器:让GC线程垃圾回收某些阶段可以和工作线程一起进行,如:标记阶段并行,回收阶段仍然串行

按回收线程数:指的是GC线程是否串行或并行执行

  • 串行垃圾回收器:一个GC线程完成回收工作
  • 并行垃圾回收器:多个GC线程同时一起完成回收工作,充分利用CPU资源

8.2.6 调整策略

对JVM调整策略应用极广

  • 在WEB领域中Tomcat等
  • 在大数据领域Hadoop生态各组件
  • 在消息中间件领域的Kafka等
  • 在搜索引擎领域的ElasticSearch、Solr等

注意: 在不同领域和场景对JVM需要不同的调整策略

  • 减少 STW 时长,串行变并行
  • 减少 GC 次数,要分配合适的内存大小

一般情况下,大概可以使用以下原则:

  • 客户端或较小程序,内存使用量不大,可以使用串行回收
  • 对于服务端大型计算,可以使用并行回收
  • 大型WEB应用,用户端不愿意等待,尽量少的STW,可以使用并发回收

8.2.7 垃圾回收器

新生代串行收集器Serial:单线程、独占式串行,采用复制算法,简单高效但会造成STW

新生代并行回收收集器PS(Parallel Scavenge):多线程并行、独占式,会产生STW, 使用复制算法

​ 关注调整吞吐量,此收集器关注点是达到一个可控制的吞吐量

​ 高吞吐量可以高效率利用CPU时间,尽快完成运算任务,主要适合在后台运算而不需要太多交互的任务

新生代并行收集器ParNew:就是Serial 收集器的多线程版,将单线程的串行收集器变成了多线程并行、独占式,使用复制算法,相当于PS的改进版

经常和CMS配合使用,关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,适合需要与用户交互的程序,良好的响应速度能提升用户体验

8.4 Tomcat 性能优化常用配置

8.4.1 内存空间优化

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

案例:

[root@centos8 ~]#vim /usr/local/tomcat/bin/catalina.shJAVA_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

8.4.2 线程池调整

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

常用属性:

  • connectionTimeout :连接超时时长,单位ms
  • maxThreads:最大线程数,默认200
  • minSpareThreads:最小空闲线程数
  • maxSpareThreads:最大空闲线程数
  • acceptCount:当启动线程满了之后,等待队列的最大长度,默认100
  • URIEncoding:URI 地址编码格式,建议使用 UTF-8
  • enableLookups:是否启用客户端主机名的DNS反向解析,缺省禁用,建议禁用,就使用客户端IP就行
  • compression:是否启用传输压缩机制,建议 “on”,CPU和流量的平衡

​ compressionMinSize:启用压缩传输的数据流最小值,单位是字节

​ compressableMimeType:定义启用压缩功能的MIME类型text/html, text/xml, text/css,text/javascript

9Java程序编译

9.1 源代码克隆与编译过程说明

以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.gitSpecify registry address in dubbo-admin-
server/src/main/resources/application.propertiesBuildmvn clean package -Dmaven.test.skip=true
Startmvn --projects dubbo-admin-server spring-boot:run
OR
cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar
Visit http://localhost:8080Default username and password is root

9.2 maven 部署准备

9.2.1 maven 介绍

Maven 翻译为"专家"、“内行”,是 Apache 基金会旗下的一个纯 Java 开发的开源项目

Maven 是一个项目管理工具,可以对 Java项目进行构建、解决打包依赖等。

POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个 XML 文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖等,在执行任务或目标时,Maven 会在当前目录中查找 pom 文件,通过读取pom文件获取所需的配置信息,然后执行目标

pom.xml 文件中可以指定以下配置:

项目依赖
插件
执行目标
项目构建 profile
项目版本
项目开发者列表 相关邮件列表信息
用<packaging> 指定项目打包形式,jar或者war

安装maven前必须安装java 环境:

Maven 3.3 要求 JDK 1.7 或以上
Maven 3.2 要求 JDK 1.6 或以上
Maven 3.0/3.1 要求 JDK 1.5 或以上

9.2.2 maven 安装

范例: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
<mirror><id>nexus-aliyun</id><mirrorOf>*</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>   

二进制安装

[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
<mirrors><!--阿里云镜像--><mirror><id>nexus-aliyun</id><mirrorOf>*</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>                                 </mirrors>

9.3 Maven 的打包命令说明

Maven工程构建的各个环节

  • clean: 以前编译得到的旧文件class字节码文件删除
  • compile:将java源程序编译成class字节码文件
  • test:自动测试,例如,自动调用junit程序
  • report:报告测试程序执行的结果
  • package:应用打包,动态Web工程打成war包,java工程打成jar包
  • install: 是指将打包得到的文件复制到仓库中指定的位置
  • deploy:将动态Web工程生成的war包复制到Servlet容器下,使其可以运行

9.4 执行 java 代码编译实战案例

编译安装 spring-boot 项目

[root@ubuntu1804 ~]#apt -y install maven git
#镜像加速
[root@ubuntu1804 ~]#vim /etc/maven/settings.xml<mirror><id>nexus-aliyun</id><mirrorOf>*</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
[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

10 私有仓库nexus

10.1 Nexus 介绍

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以下会导致无法启动

10.2 部署 Nexus

10.2.1 下载并启动 Nexus

注意: : 安装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.

10.2.2 登录 web 界面初始化

通过浏览器访问

http://nexus主机:8081/

需要在右上角点Sign in 进行登录才能进行管理

查看默认密码

[root@ubuntu1804 ~]#cat /usr/local/sonatype-work/nexus3/admin.password

设置密码,使用admin用户和上面的密码登录

10.3 使用 Nexus 构建私有 Yum 和 Apt 仓库

通过 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 仓库,代理至阿里云镜像安装包

企业级WEB应用服务器TOMCAT相关推荐

  1. Web应用服务器tomcat

    Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公司及个人共同开发而成.由于有了 ...

  2. Web应用服务器——Tomcat

    最近学校的课程在学习Spring框架,接触到了Tomcat,这一篇就来浅析一哈Tomcat的安装及使用 目录 1.Tomcat 1.1 Web服务器 & Web应用服务器 1.2 Tomcat ...

  3. Web应用服务器-Tomcat

    1.Tomcat简介 Tomcat是由Apache.Sun 和其他一些公司及个人共同开发而成的Web 应用服务器,由于其技术先进.性能稳定以及免费而受大家的喜爱,是目前比较流行的Web 应用服务.To ...

  4. JSP之WEB服务器:Apache与Tomcat的区别 ,几种常见的web/应用服务器

    APACHE是一个web服务器环境程序 启用他可以作为web服务器使用 不过只支持静态网页 如(asp,php,cgi,jsp)等动态网页的就不行 如果要在APACHE环境下运行jsp 的话就需要一个 ...

  5. Apache Tomcat 7.0.93 发布,开源 Java Web 应用服务器

    Apache Tomcat 7.0.93 已发布,Tomcat 是 Java Servlet.JavaServer Pages.Java 表达式语言和 Java WebSocket 技术的开源实现,是 ...

  6. 应用发布服务器_Apache Tomcat 10.0.0-M1 发布,开源 Web 应用服务器

    Apache Tomcat 10.0.0 发布了第一个里程碑版本.Tomcat 是 Java Servlet.JavaServer Pages.Java 表达式语言和 Java WebSocket 技 ...

  7. Tomcat“汤姆猫?“ ---------web应用服务器(个人整理)

    个人整理,感谢观看 一,Tomcat的介绍 二,核心组件 三,处理请求流程 四,部署Tomcat 下载并安装JDK 安装后启动Tomcat 优化tomcat启动速度 配置虚拟主机站点 一,Tomcat ...

  8. WEB应用服务器都有哪些?

    下面介绍几种常用的WEB服务器: Microsoft的 IIS服务器 Microsoft的Web服务器产品为Internet Information Server (IIS), IIS 是允许在公共I ...

  9. Solr 企业级搜索应用服务器学习

    转自:https://blog.csdn.net/cs_hnu_scw/article/details/79388080 备注:学习Solr最好先了解一下Lucene的基本内容,不需要很熟,但是知道个 ...

  10. 主流Web应用服务器简介

          JBoss含有Jsp和Servlet容器,也就可以做web容器,也包含EJB容器,是完整的J2EE应用服务器 JBoss 是一个运行EJB的J2EE应用服务器.它是开放源代码的项目,遵循最 ...

最新文章

  1. DCMTK:表示细分对象的类
  2. java 扩展数据类型_java数据类型及其拓展
  3. 全球 IPv4 地址耗尽,IPv6 来了!
  4. Xpath语法学习记录
  5. 阿里云助力宁波市教育局“甬上云校”停课不停学
  6. 大地Win11 64位全新专业版系统V2021.08
  7. 【例题+习题】【数值计算方法复习】【湘潭大学】(二)
  8. 个人笔记-C#txt文本分割器
  9. 未来的人工智能和 AR/VR 会从哪些方面影响教育?有什么机会?
  10. 量子计算机原理 不确定,【图片】不确定性原理对量子纠缠的解释【经典物理吧】_百度贴吧...
  11. 前苏格拉底时期的古希腊哲学流派
  12. 在latex中设置表格背景色
  13. Qt开发——圆面积计算器
  14. Moviepy自动化视频处理:添加音频、背景音乐,实现多轨音频
  15. 计算机与英语相关工作,计算机行业岗位英语单词整合
  16. 微生物-肠道-脑轴:新的治疗机会
  17. 盘点6个主流的数据分析工具,及优缺点对比
  18. node 文字生成图片
  19. Google advertiser api开发概述
  20. 网站架构设计发展路径学习

热门文章

  1. 麻辣烫有几种类型?不同种麻辣烫怎么做
  2. android 记事本软件,安卓日历记事本软件
  3. 行为型模式:备忘录模式
  4. linux0.11 阅读笔记
  5. 操作系统实验三虚拟存储器管理之模拟页面置换算法(FIFOLRU)
  6. Puppeteer开发过程中遇到的问题及解决方案
  7. WordPress站点被挂马,如何预防、检测和应对?
  8. 致电电信索要公网ip地址,如何判断自己属于公网ip地址
  9. 鼠标跟随flash代码_Flash动画设计之 MTV实例创作《不说再见》
  10. BZOJ5394: [Ynoi2016]炸脖龙(欧拉广义降幂)