开发、构建、部署
Maven
概念
Maven 翻译为”专家”、”内行”,是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。
作用
- 依赖管理:jar包放置在maven仓库中
- 一键构建:体现在Maven的生命周期,每一个构建项目的命令都对应了底层的一个Maven插件
- 热编译、热部署
下载和安装
下载Maven:
- 访问:
http://maven.apache.org/download.cgi - 下载对应版本:
安装Maven:
- 解压下载好的Maven安装包
- 添加一个系统环境变量
Path为Maven目录的bin目录,即配置一个MAVEN_HOME并作为Path - 利用
mvn -v测试版本信息
注意:Maven依赖JAVA_HOME,需要先确保电脑正确配置了JAVA_HOME
Maven仓库
分类:
本地(Local)
Maven 的本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。
默认的本地Maven仓库在
${user.home}/.m2/repository里运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
自定义本地仓库位置:修改Maven安装目录下的
conf文件夹内的settings.xml文件:
中央(Central)
- Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。
- 中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。
- 中央仓库的关键概念:
- 这个仓库由 Maven 社区管理。
- 不需要配置。
- 需要通过网络访问
远程(Remote)
- 如果 Maven 在中央仓库中也找不到依赖的文件,它会停止构建过程并输出错误信息到控制台。为避免这种情况,Maven 提供了远程仓库的概念,它是开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。
- 在中央仓库获取不到的
pom.xml中声明的依赖文件会在远程仓库中下载。
Maven依赖搜索顺序
- 步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
- 步骤 2 - 在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载到本地仓库中以备将来引用。
- 步骤 3 - 如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
- 步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库以备将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)。
Maven坐标
概念
- 坐标用于描述仓库中资源的位置
主要组成
- groupId:定义当前Maven项目隶属的组织名称(通常是域名反写)
- artifactId:定义当前Maven项目名称(通常是模块名称)
- version:定义当前项目的版本号
- packaging:定义该项目的打包方式
Maven项目标准目录结构
src/main/java:核心Java代码部分src/main/resources:配置文件部分src/test/java:测试代码部分src/test/resources:测试配置文件部分src/main/webapp:页面资源,包括js、css、图片等等,Web项目包含此目录
Maven常用命令
mvn clean:清除target目录mvn compile:编译src/main/java下的源代码生成到target目录mvn test:编译src/test/java与src/main/java下的源代码生成到target目录(会执行compile)mvn package:打包项目到target目录(会执行compile和test)- 打包的类型由pom.xml内的
<project>标签内的<packaging>标签指定(默认为jar)
- 打包的类型由pom.xml内的
mvn install:将项目打包并放到本地仓库中(会执行compile和test和package)mvn deploy:将项目发布到远程仓库(会执行compile和test和package和install)
Maven生命周期
Maven概念模型
IDEA集成Maven
这种方式修改的Maven配置只对当前项目生效,要更改所有新项目配置,在IDEA左上角的File选择新项目设置
使用骨架(archetype)创建Maven的Java项目
这种方式创建的Maven目录结构缺少src/main下的resources目录
不使用骨架(archetype)创建Maven的Java项目
创建之后的目录结构:
创建Maven的Web项目
创建之后的目录结构:
手动指定Maven的Web项目的资源包
如果想在src/main/java下也能放置web资源文件,需要添加此目录为模块的Web资源目录:
在pom.xml中指定依赖
每一个
<dependency>标签的依赖都写在<dependencies>标签里每一个
<dependency>依赖至少包含3个部分:groupId:库来源的公司名称artifactId:库来源的项目名称version:版本号
选填的:
scope:作用域
例如,引入Servlet的依赖:
在pom.xml中指定插件
- 每一个
<plugin>标签的插件都写在<plugins>标签里,而<plugins>在<build>标签里 <pluginManagement>标签的<plugins>内的插件只是声明,Maven不会加载
例如,引入tomcat7的插件:
或者,指定maven的compiler编译器插件:
可能遇到的问题:
1.IDEA无法创建Servlet,没有Servlet提示
- 原因:没有导入javax.servlet的包
- 解决方法:在
pom.xml里导入以下依赖后重新加载Maven
1 | <dependency> |
2.无法使用Maven自带的Tomcat启动项目(mvn tomcat:run命令无法使用)
- 原因:Maven本地仓库没有Tomcat的插件
- 解决方法:在
pom.xml里导入Tomcat插件后重新加载Maven
1 | <plugin> |
- 补充:IDEA右侧的Maven侧边工具栏中,还是无法显示tomcat插件,需要去掉pom.xml的
pluginManagement标签重新加载Maven即可
3.Servlet依赖冲突
原因:
pom.xml中导入了Servlet的依赖jar包,在运行时Tomcat也自带有依赖jar包导致冲突解决方法:为pom.xml的Servlet依赖指定
scope标签:<scope>provided</scope>只保留在写代码阶段具体解释来源于CSDN:
对于scope=compile的情况(默认scope),也就是说这个项目在编译,测试,运行阶段都需要这个artifact对应的jar包在classpath中。
而对于scope=provided的情况,则可以认为这个provided是目标容器已经provide这个artifact。换句话说,它只影响到编译,测试阶段。在编译测试阶段,我们需要这个artifact对应的jar包在classpath中,而在运行阶段,假定目标的容器(比如我们这里的liferay容器)已经提供了这个jar包,所以无需我们这个artifact对应的jar包了。
4.IDEA控制台乱码
- 原因:Maven的tomcat编码问题
- 解决方法:修改IDEA的Maven设置:修改Runner项设置
VM Options:-Dfile.encoding=gb2312
Maven高级
分模块开发与设计
- ssm_pojo拆分:
- 新建模块
- 复制原始项目中的pojo层内容到ssm_pojo模块中
- 复制实体类到对应的实体包
- 不需要配置文件到resources目录
- ssm_dao拆分
- 新建模块
- 复制原始项目中的dao层对应内容到ssm_dao模块中
- 数据dao层的接口
- 配置文件:保留与dao层相关的内容,例如分页插件等
- pom.xml中引入坐标,删除springMVC坐标
- spring
- mybatis
- spring整合mybatis
- mysql
- druid
- pagehelper
- pojo层的模块依赖(需要先把pojo层的maven模块执行
install安装到仓库作为依赖)、
- ssm_service拆分
- 新建模块
- 复制原始项目中的service层对应内容到ssm_service模块中
- 业务层接口与实现类(service包以及service层的impl实现包)
- 配置文件:保留与service层相关的配置文件
- pom.xml中保留与service相关坐标即可,删除springMVC坐标
- spring
- junit
- spring整合junit
- 直接依赖ssm_dao模块
- 间接依赖ssm_pojo模块(由于依赖传递,已经被ssm_dao模块依赖)
- 修改service模块spring核心配置文件名为applicationContext-service.xml
- 修改dao模块spring核心配置文件名为applicationContext-dao.xml
- 修改单元测试
@ContextConfiguration注解引入的配置文件名称,由单个文件修改为多个文件
- ssm_controller拆分
- 新建模块
- 复制原始项目中的controller层对应内容到ssm_controller模块中
- 表现层控制器类与相关设置类(Controller与异常类)
- 配置文件:保留与表现层springMVC相关配置文件、服务器相关配置文件
- pom.xml引入表现层相关坐标即可,删除springMVC相关坐标
- spring
- springMVC
- jackson
- servlet
- tomcat服务器插件
- 直接依赖ssm_service
- 间接依赖ssm_dao、ssm_pojo
- 修改web.xml配置文件中加载spring核心配置文件的名称,使用
applicationContext-*.xml通配
分模块开发总结:
- 模块中仅包含档期啊你模块对应的功能类与配置文件
- spring核心配置根据模块的功能独立制作,分别命名区分
- 当前模块所依赖的模块可以通过导入坐标的形式导入依赖,并且需要位于maven仓库(先
install安装) - web.xml需要加载所有的spring核心配置文件(通过通配符加载多个核心配置文件)
聚合
作用:用于快速构建Maven工程,一次性构建多个项目/模块
制作方式:
创建一个空模块,pom.xml中指定打包类型
packaging为pom1
2<!--定义此模块用于构建管理-->
<packaging>pom</packaging>定义当前模块进行构建操作时关联的其他模块名称
1
2
3
4
5
6
7<!--管理的工程列表-->
<modules>
<!--具体的模块名称-->
<module>01module1</module>
<module>02module2</module>
<module>03module3</module>
</modules>
继承
作用:通过继承可以实现在子工程中沿用父工程中的配置
制作方式:
在子工程中声明其父工程坐标与对应的位置
1
2
3
4
5<parent>
<artifactId>SpringDemo</artifactId>
<groupId>com.taoyyz</groupId>
<version>1.0-SNAPSHOT</version>
</parent>在父工程中定义依赖管理
1
2
3
4
5
6
7
8
9
10
11
12<!--声明此处进行依赖管理-->
<dependencyManagement>
<!--具体的一些依赖-->
<dependencies>
<!--具体依赖项-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
</dependencyManagement>在子工程中定义依赖关系,无需声明依赖版本,版本会参照父工程中的依赖版本
1
2
3
4
5
6<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
属性
自定义属性
自定义属性:
1
2
3
4<!--定义自定义属性-->
<properties>
<spring.version>5.0.5.RELEASE</spring.version>
</properties>使用此自定义属性:
${属性名}1
2
3
4
5<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
内置属性:
可以利用
${内置属性名}直接使用pom.xml中内置属性的内容例如:
${project.version}简写为${version}${project.basedir}简写为${basedir}
Setting属性
利用
${settings.属性名}使用settings.xml配置文件中的属性例如:
${settings.localRepository}${settings.interactiveMode}
Java系统属性
利用
${user.属性名}使用Java系统属性例如:
${user.home}${user.dir}
系统属性查询方式:
mvn help:system
环境变量属性
利用
${env.环境变量属性名}获取环境变量属性例如:
${env.JAVA_HOME}${env.MAVEN_HOME}
环境变量查询方式:
mvn help:system
版本管理
分类:
- SNAPSHOT(快照版本)
- RELEASE(发布版本)
工程版本号约定
- 约定规范:
- <主版本>.<次版本>.<增量版本>.<里程碑版本>
- 主版本:表示项目重大架构变更
- 次版本:表示有较大的功能增加和变化,或者全面系统地修复漏洞
- 增量版本:表示有重大漏洞的修复
- 里程碑版本:表名一个版本的里程碑(内部版本),这样的版本同下一个正式版本相比有待测试
- 范例:
5.1.9.RELEASE
资源配置
配置文件可以引用pom.xml中定义的属性
作用:在任意配置文件中加载pom文件中的属性
调用格式:
${属性名}开启配置文件加载pom属性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!--配置资源文件的信息,从Maven的属性加载值-->
<build>
<!--配置资源文件的信息-->
<resources>
<resource>
<directory>${basedir}/18_SSM_integration/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<!--配置测试目录的资源文件的信息-->
<testResources>
<testResource>
<directory>${basedir}/18_SSM_integration/src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
多环境开发配置
定义多个环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<!--创建多环境-->
<profiles>
<!--生产环境-->
<profile>
<!--定义此环境的唯一名称-->
<id>produce_env</id>
<!--定义此环境中专用的属性值-->
<properties>
<jdbc.url>jdbc:mysql:///db1</jdbc.url>
</properties>
</profile>
<!--开发环境-->
<profile>
<!--定义此环境的唯一名称-->
<id>development_env</id>
<!--定义此环境中专用的属性值-->
<properties>
<jdbc.url>jdbc:mysql:///db3</jdbc.url>
</properties>
<!--设置为默认启动此环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>使用某个环境:
- 利用
activation标签指定默认环境 - mvn命令指定加载某环境:
mvn 指令 -P 环境id,例如mvn install -P produce_env
- 利用
跳过测试
应用场景:
- 整体模块功能未开发
- 模块中某个功能未开发完毕
- 单个功能更新调试导致其他功能失败
- 快速打包
跳过测试
方式1:
方式2:执行命令:
mvn install -D skipTests方式3:修改pom.xml中的插件,跳过测试
1
2
3
4
5
6
7
8
9
10<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<!--跳过全部测试-->
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>指定或跳过测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<!--指定测试内容-->
<includes>
<include>**/MultiTest.java</include>
</includes>
<!--指定排除内容-->
<excludes>
<exclude>**/MyBatisTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
私服
Nexus
- 下载安装
- 启动:
nexus.exe /run nexus - 访问服务器:
http://localhost:8081 - 修改配置:
- 基础配置:修改etc目录下的
nexus-default.properties - 运行配置:修改bin目录下的
nexus.vmoptions
- 基础配置:修改etc目录下的
仓库分类
- 宿主仓库hosted
- 保存无法从中央仓库获取的资源
- 自主研发
- 第三方非开源项目
- 保存无法从中央仓库获取的资源
- 代理仓库proxy
- 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库
- 仓库组group
- 将若干个仓库组成一个群组,简化配置
- 仓库组不能保存资源,属于设计型仓库
- 宿主仓库hosted
资源上传
- 把宿主仓库加入到
maven-public群组 - 保存的位置(宿主仓库)
- 资源文件
- 对应坐标
- 把宿主仓库加入到
IDEA中资源的上传和下载
配置本地Maven仓库访问私服的权限:settings.xml
配置
servers标签中的多个server- 配置此
server的id为nexus仓库的id - 配置此
server的username - 配置此
server的password
- 配置此
配置本地仓库的资源来源
- 配置
mirrors标签中的mirror- 配置此
mirror的id - 配置此
mirror的mirrorOf为* - 配置此
mirror的url为nexus仓库的url
- 配置此
- 配置
发布资源到私服
在pom.xml中配置发布管理
1
2
3
4
5
6
7
8
9
10
11
12<distributionManagement>
<repository>
<!--对应server的id-->
<id>repo_tjj</id>
<url>地址url</url>
</repository>
<snapshotRepository>
<!--对应server的id-->
<id>repo_snap</id>
<url>snap的地址url</url>
</snapshotRepository>
</distributionManagement>发布到私服:
mvn deploy
Linux
概念
- Unix:Unix是一个强大的多用户、多任务的操作系统。于1969年在贝尔实验室开发。Unix的商标权由国际开放标准组织(The Open Group)所拥有。Unix是商业版,需要收费。
- Linux:Linux是基于Unix的,是一种自由和开放源码的操作系统,存在许多的发行版本使用Linux内核。
版本
- 内核版本
- 发行版本
主流版本
安装Linux
安装到虚拟机
虚拟机的概念
- 软件模拟的虚拟电脑
常用的虚拟机
- VMware
- VirtualBox
VMware安装CentOS
安装到物理机
Linux目录结构
- root — 启动Linux时使用的一些核心文件。如操作系统内核、引导程序Grub等。
- home — 存储普通用户的个人文件
- ftp — 用户所有服务
- httpd
- samba
- user1
- user2
- bin — 系统启动时需要的执行文件(二进制)
- sbin — 可执行程序的目录,但大多存放涉及系统管理的命令。只有root权限才能执行
- proc — 虚拟,存在linux内核镜像;保存所有内核参数以及系统配置信息
- 1 — 进程编号
- usr — 用户目录,存放用户级的文件
- bin — 几乎所有用户所用命令,另外存在与/bin,/usr/local/bin
- sbin — 系统管理员命令,与用户相关,例如,大部分服务器程序
- include — 存放C/C++头文件的目录
- lib — 固定的程序数据
- local — 本地安装软件保存位置
- man — 手工生成的目录
- info — 信息文档
- doc — 不同包文档信息
- tmp
- X11R6 — 该目录用于保存运行X-Window所需的所有文件。该目录中还包含用于运行GUI要的配置文件和二进制文件。
- X386 — 功能同X11R6,X11 发行版5 的系统文件
- boot — 引导加载器所需文件,系统所需图片保存于此
- lib —根文件系统目录下程序和核心模块的公共库
- modules — 可加载模块,系统崩溃后重启所需模块
- dev — 设备文件目录
- etc — 配置文件
- skel — home目录建立,该目录初始化
- sysconfig — 网络,时间,键盘等配置目录
- var
- file
- lib — 该目录下的文件在系统运行时,会改变
- local — 安装在/usr/local的程序数据,变化的
- lock — 文件使用特定外设或文件,为其上锁,其他文件暂时不能访问
- log — 记录日志
- run — 系统运行合法信息
- spool — 打印机、邮件、代理服务器等假脱机目录
- tmp
- catman — 缓存目录
- mnt — 临时用于挂载文件系统的地方。一般情况下这个目录是空的,而在我们将要挂载分区时在这个目录下建立目录,再将我们将要访问的设备挂载在这个目录上,这样我们就可访问文件了。
- tmp — 临时文件目录,系统启动后的临时文件存放在/var/tmp
- lost+found — 在文件系统修复时恢复的文件
Linux常用命令
操作目录
- 切换目录:
cd - 列出文件列表:
lsls -a:列举出包括隐藏文件的所有文件ls -l:列举出详细信息,简写为llls -lh:以MB为单位列举出详细信息
- 创建目录/删除目录:
mkdir/rmdir- 创建多级目录:
mkdir -p parent/son,-p参数表示如果不存在parent就同时创建父目录 - 删除多级空目录:
rmdir -p parent/son/sonson,会从sonson内层删除到parent之间的空目录
- 创建多级目录:
操作文件
- 查看文件内容:
cat - 查看文件内容,一次查看一页:
more,按空格翻页,按q退出 - 查看文件内容,一次查看一页:
less,按空格翻页,按q退出,按上下键可以方便地查看一行 - 倒序查看文件内容:
tail,默认倒数10行- 指定倒序查看到第几行:
tail -行数 文件名即可 - 倒序查看文件的实时更新内容:
tail -f 文件名
- 指定倒序查看到第几行:
- 复制文件:
cp - 移动文件:
mv,可以用来重命名 - 删除文件:
rm,需要输入n(no)或y(yes)来确认- 删除非空文件夹:
rm -r 文件夹,删除目录内容及所有子目录下的内容,此命令会询问 - 删除非空文件夹,且不询问:
rm -rf 文件夹,删除目录内容及所有子目录下的内容 - 删除超过指定天数7天的zip文件:
find ./ -type f -name "*.zip" -mtime +7 -delete
- 删除非空文件夹:
打包或解压
tar -cvf:打包指定的文件或目录,但不压缩,例如:tar -cvf xxx.tar ./*c:创建一个新的tar文件v:显示出运行过程f:指定文件名z:调用gzip进行压缩t:查看压缩文件的内容x:解压缩
tar -zcvf:打包指定的文件或目录,且利用gzip压缩,例如:tar -zcvf xxx.tar.gz ./*tar -xvf:解压指定的tar包tar -xzvf:解压指定的gzip压缩包,可以利用-C重新指定解压位置
查找文件或内容
find:查找文件,例如:find 目录 -name "文件名",查找指定目录(包括子目录的文件)find 目录 -maxdepth 最大查找深度 -name "文件名",限制查找深度,比如为1时只查找当前1层
grep:查找文件的内容,例如:grep 要查找的关键字 文件名,在指定文件名的文件中查找关键字的内容grep 关键字 文件名 --color,查找结果中高亮显示查找的关键字grep 关键字 文件名 -A行数,查找的结果往后(After)显示几行grep 关键字 文件名 -B行数,查找的结果往前(Before)显示几行
其他常用命令
pwd:查看当前目录groups:查看当前属于的组whoami:查看当前用户getconf LONG_BIT:查看系统版本位数cat /etc/redhat-release:查看发行版本uname -r:查看Linux内核版本free -h:查看内存使用情况lsof -i:端口号:查看占用端口的进程netstat -tunlp | grep 端口号:同上touch:创建一个文件clear:清除屏幕,等同于ctrl+L
VI和VIM编辑器
VI提供了3种模式
- 命令行
- 插入
- 底行
切换到命令行模式:ESC
切换到插入模式:i、o、a
i:在当前位置插入I:在当前行首插入a:在当前位置后插入A:在当前行尾插入o:在当前行之后插入O:在当前行之前插入
切换到替换模式:R
- 替换模式下对每一个字符做的输入都会替换掉原来位置的字符
切换到可视模式:v或V
v:从当前光标开始可视V:从当前行开始按行可视
操作VIM文本
Home:定位光标到这一行的开头^:定位光标到这一行开头的第一个非空白字符
End:定位光标到这一行的结尾$:定位光标到这一行结尾的最后一个非空白字符
PageUp:向上翻页,相当于ctrl + b/Bctrl + y:向上滚动屏幕
PageDown:向下翻页,相当于ctrl + f/Fctrl + e:向下滚动屏幕
h:向左移动光标,但不会导致换行l:向右移动光标,但不会导致换行enter:向下移动光标到下一行第一个非空白字符处H:移动至顶部第一个非空白字符处M:移动至屏幕中间第一个非空白字符处L:移动至底部第一个非空白字符处zz:移动至当前行作为屏幕中间处w:移动到下一个单词字首W:移动到下一个单词字首(忽略标点符号)e:移动到下一个单词字尾E:移动到下一个单词字尾(忽略标点符号)b:移动到上一个单词字首B:移动到上一个单词字首(忽略标点符号)):移动到下一个句首(:移动到上一个句首}:移动到下一个段落首{:移动到上一个段落首%:移动到匹配的另一个{}、[]、()等括号列数|:光标移动到第列数列d + 一个改变光标操作:从光标起始位置删除至改变后的位置dd:快速删除整行x:删除光标处的字符Nx:删除光标处往后N个字符
X:删除光标前一个字符NX:删除光标处往前N个字符
D:删除光标到这行结尾之间的字符C:修改光标到这行结尾之间的字符,相当于D + iS:修改整行的字符,相当于Home + Cdiw:删除光标所在的单词,不包括空白字符daw:删除光标所在的单词,包括空白字符dw:删除光标到下一个单词词首之间的字符yy:复制当前行P:粘贴复制的内容到当前光标前p:粘贴复制的内容到当前光标后
ma:对当前光标处做一个a标记y'a:复制新光标处到a标记之间的内容d'a:删除新光标处到a标记之间的内容
u:撤销改动(undo)ctrl + r:重做改动(redo):/关键字:从头开始向下搜索关键字- 搭配
n快速定位光标到下一个搜索到的内容 - 搭配
N快速定位光标到上一个搜索到的内容
- 搭配
:?关键字:从末尾开始向上搜索关键字zf + 一个改变光标的操作:折叠文本zfap:折叠一个段落的文本zo:打开折叠的文本zc:关闭折叠':移动到上一次修改的行'':移动到上一次光标所在位置N%:跳转到文本的百分之N的位置>>:把当前行向右移动一段距离N>>:把下面N行向右移动一段距离:N,M>>:把N到M行向右移动一段距离
<<:把当前行向左移动一段距离N<<:把下面N行向左移动一段距离:N,M<<:把N到M行向左移动一段距离
.:重复上一条命令
页面命令
显示行号:命令模式下
:后输入set number或set nuset指令可简写为se
查看总行数和所处位置百分比:
ctrl + g字数统计:
g ctrl + g到第一行:
1G,相当于gg,也相当于命令模式下:后输入1到第N行:
行号G,命令模式下:后输入行号到最后一行:
G向上半页:
ctrl + u/U向下半页:
ctrl + d/D暂停vi回到提示符:
ctrl + z重新回到vi:
fg
退出VIM
:q退出VI或VIM:q!放弃所做的更改,强制退出:wq保存更改并退出
重定向控制台的输出
cat 文本文件 > 目标文件名:把文本文件的内容输出到目标文件中cat 文本文件 >> 目标文件名:把文本文件输出并且追加到目标文件中
注意:任何能在控制台打印的信息都可以重定向,不是只有cat
进程管理
ps -ef:查看正在运行的进程ps -ef | grep 关键字:筛选进程列表中含有关键字的进程
kill 进程号:关闭进程kill -9 进程号:强制关闭进程
管道:|
管道可以将一个命令的输出作为另一个命令的输入,例如上面筛选进程的案例:ps -ef | grep 关键字
Linux权限管理
第一个字符表示文件类型:
-:表示这是一个文件l:表示这是一个链接d:表示这是一个目录b:表示这是一个块设备s:表示这是一个套接字
第一组字符(rwx)表示当前用户对该文件的权限
第二组字符(rwx)表示当前组内的用户对该文件的权限
第三组字符(rwx)表示其他组的用户对该文件的权限
权限符号
r表示对于该用户可读,对于文件来说是允许读取内容,对于目录来说是允许读取其中的文件w表示对于该用户可写,对于文件来说是允许修改其内容,对于目录来说可以写信息到目录中,即可以创建、删除文件、移动文件等操作x表示对于该用户可执行,对于文件来说就是可以执行该文件,对于目录来说则是可以进入目录;可以搜索(能用该目录名称作为路径名去访问它所包含的文件和子目录)
修改权限
chmod u=rwx[,g=rwx,o=rwx] 文件名:修改该文件的对应的用户权限,可选chmod 777 文件名:修改该文件名对应的用户权限,其中r:4,w:2,x:1chmod +x 文件名:修改该文件名对应的权限,为所有用户增加x可执行权限
Linux网络操作
主机名配置
hostname:查看当前主机名hostname 新主机名:临时更改主机名,重启失效
hostnamectl set-hostname 新主机名:设置主机名- 或者修改
/etc/sysconfig/network文件的HOSTNAME
关闭防火墙
CentOS 7 默认以firewalld作为防火墙
systemctl stop firewalld:关闭防火墙systemctl disable firewalld:禁用防火墙
IP地址配置
- 修改
/etc/sysconfig/network-scripts/下的网卡配置,例如ifcfg-ens33- 修改
ONBOOT为yes以保证网卡在开机时自启 - 修改
IPADDR为IP地址 - 修改
NETMASK为子网掩码 - 修改
GATEWAY为网关地址 - 修改
DNS1和DNS2为DNS
- 修改
- 修改完毕后执行
service network restart重启网络服务
域名映射
- 修改
/etc/hosts文件
Linux的软件安装
常见的软件安装方式
- 二进制发布包:解压即可安装
- RPM包:获取RPM包然后用RPM命令安装
- Yum:获取RPM软件用Yum安装,可以解决一些库依赖问题
- 源码编译安装:把源码编译打包部署
上传与下载工具
- FileZilla
- lrzsz:支持yum安装:
yum install lrzsz- 上传到本机:
rz - 从本机下载:
sz 文件名
- 上传到本机:
Linux配置JavaWeb环境
安装JDK
- CentOS 7自带Open JDK
- 使用
rpm -qa | grep java,查看所有的java包名 - 使用
rpm -e --nodeps 包名,卸载掉报名对应的包
- 使用
复制
JDK安装包解压缩包
配置环境变量
使用vim修改
/etc/profile文件添加JAVA环境变量:
1
2export JAVA_HOME=/root/jdk1.8.0_171
export PATH=$PATH:$JAVA_HOME/bin使环境变量生效:
source /etc/profile
安装MySQL
复制
MySQL安装包解压缩包
得到的rpm文件:
安装服务器端:
rpm -ivh MySQL-server-5.6.22-1.el7.x86_64.rpm一大堆
mariadb报错解决方案:rpm -qa | grep mariadb列举所有的mariadb包- 通过
rpm -e --nodeps 包名全部卸载 - 重新执行MySQL安装即可
安装完成后的初始密码在
/root/.mysql_secret下
安装客户端:
rpm -ivh MySQL-client-5.6.22-1.el7.x86_64.rpm启动mysql:
service mysql start- 第一次使用mysql必须设置密码:
set password = password('密码');
- 第一次使用mysql必须设置密码:
开放远程访问权限:
grant all privileges on *.* to 'root'@'%' identified by 'root';授权- 注意这个
identified by后面是授权给这个用户的密码
- 注意这个
flush privileges;刷新权限
安装Tomcat
- 复制
Tomcat安装包 - 解压缩包
- 解压完即可使用
bin目录下的startup.sh启动
安装Redis
- Redis需要手动使用GCC编译,需要先安装GCC:
yum install gcc
- 复制
Redis安装包 - 解压缩
- 进入Redis安装目录,执行:
make编译 - 编译完成后,执行:
make PREFIX=/usr/local/redis install进行安装 - Redis将被安装到
/usr/local/redis下
提示:
- Redis配置文件在安装包内,可以手动复制到
/usr/local/redis/bin下 - 使用配置文件启动服务器:
./redis-server ./redis.conf - 启动客户端:
./redis-cli
安装Nginx
- Nginx是一款高性能的Web服务器/反向代理服务器及电子邮件代理服务器。
- Nginx可以作为HTTP代理服务器
- 可以在一台服务器虚拟出多个网站
- 反向代理,负载均衡:对于多个tomcat服务器集群可以平均负担负载
安装
- Nginx需要手动使用GCC编译,需要先安装GCC环境
- 需要第三方的开发包:
- PCRE:
yum install -y pcre pcre-devel,一个Perl库,包括Perl兼容的正则表达式库,Nginx的HTTP模块需要使用PCRE来解析正则表达式 - zlib:
yum install -y zlib zlib-devel,zlib提供了很多压缩和解压缩的方式,Nginx使用zlib对HTTP包的内容进行gzip - OpenSSL:
yum install -y openssl openssl-devel,OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理管理及SSL协议。Nginx不仅支持HTTP,还支持HTTPS
- PCRE:
复制
Nginx安装包解压缩
使用
configure命令生成makefile:1
2
3
4
5
6
7
8
9
10
11
12./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi使用
make命令编译makefile文件:make使用
make install命令安装:make install创建
configure命令里指定的临时目录:mkdir /var/temp/nginx/client -pNginx将被安装到
/usr/local/nginx下
- 启动Nginx:执行Nginx安装目录下的
sbin目录下的nginx:./nginx - 正常停止Nginx:
./nginx -s quit - 强制停止Nginx:
./nginx -s stop - 重新加载配置文件:
./nginx -s reload - Nginx默认端口:80
部署静态资源
第一种方式:
- 放置html资源到Nginx安装目录的html文件夹,Nginx默认部署
html文件夹的index.htmlnginx.conf指定server { }配置的location / { }里的站点路径
第二种方式:配置虚拟主机
- 配置Nginx安装目录下的配置文件:可以指定多个
server { }的端口nginx.conf指定server { }配置的listen后的端口号,通过不同端口访问不同的server
- 配置Nginx安装目录下的配置文件:可以指定多个
server { }的域名nginx.conf指定server { }配置的server_name后配置域名或IP地址,以此访问不同的server- 域名需要通过DNS服务器解析,否则就要手动修改电脑的hosts文件
反向代理与负载均衡
- 正向代理:正向代理,架设在客户机与目标主机之间,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。
- 反向代理:反向代理服务器架设在服务器端,通过缓冲经常被请求的页面来缓解服务器的工作量,将客户机请求转发给内部网络上的目标服务器;并将从服务器上得到的结果返回给请求连接的客户端,此时代理服务器与目标主机一起对外表现为一个服务器。
反向代理
修改nginx.conf配置:
在
http { }内配置一个upstream:1
2
3upstream 代理的名称 {
server 被代理的服务器ip:端口;
}定义一个server:
1
2
3
4
5
6
7
8
9server {
listen 80; #用于访问的端口号
server_name localhost; #用于访问的域名或IP地址
location / {
proxy_pass http://代理的项目名称; #反向代理的访问路径
index index.jsp; #访问的文件名
}
}重启nginx:
./nginx -s reload
负载均衡
为每一个被代理的tomcat服务器和端口配置为server:此时访问被代理的项目,3台server被Nginx随机分配
1
2
3
4
5upstream 代理的名称 {
server 被代理的服务器1ip:端口;
server 被代理的服务器2ip:端口;
server 被代理的服务器3ip:端口;
}为每一个被代理的tomcat服务器和端口配置为server,并且指定权重:
1
2
3
4
5upstream 代理的名称 {
server 被代理的服务器1ip:端口 weight=权重1;
server 被代理的服务器2ip:端口 weight=权重2;
server 被代理的服务器3ip:端口 weight=权重3;
}注意:由于每次访问的tomcat服务器不确定,可能导致session问题,建议使用
ip_hash方式分配负载为此upstream代理指定为按照请求的ip的hash结果分配:
1
2
3
4
5
6upstream 代理的名称 {
ip_hash;
server 被代理的服务器1ip:端口;
server 被代理的服务器2ip:端口;
server 被代理的服务器3ip:端口;
}为此upstream代理指定为按照访问url的hash结果分配,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效:
1
2
3
4
5
6
7upstream 代理的名称 {
hash $request_uri;
hash_method crc32;
server 被代理的服务器1ip:端口;
server 被代理的服务器2ip:端口;
server 被代理的服务器3ip:端口;
}注意:此时不能指定weight等其他参数,hash_method后为hash算法
为此upstream代理的server指定其他参数:
down:此server暂时不参与负载backup:当其他所有的非backup服务器为down或者忙的时候才请求backup服务器1
2
3
4
5
6upstream 代理的名称 {
ip_hash;
server 被代理的服务器1ip:端口 down; #不参与负载
server 被代理的服务器2ip:端口 weight=2; #权重为2
server 被代理的服务器3ip:端口 backup; #备用服务器
}
Linux部署项目案例
Maven项目进行
package命令后生成的包名过长,可以在build标签内指定finalName标签设置名称指定数据库连接配置的字符集:
- 修改
druid.properties:url=jdbc:mysql://localhost:3306/db1?characterEncoding=utf-8
- 修改
修改项目中的绝对路径为相对路径
修改无误后利用Maven进行打包,执行Maven的:
package复制打包好的
war文件到服务器上,在运行tomcat的情况下直接复制到webapps目录下即可自动部署
可能遇到的问题:
Web项目获取不到服务器端的验证码,日志显示服务器500错误:
根本原因:java.awt.AWTError:Can't connect to X11 window server using localhost as the value of the DISPLAY variable.原因:这种情况是由于用到了java.awt包下的Image等对象导致的问题
解决方法:修改tomcat的
bin目录下的catalina.sh:在最上方添加:
JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true"即可解决图片500问题
Docker
使用背景
项目部署的问题:
Docker解决依赖的兼容问题:
Docker解决不同系统环境问题:
Docker解决大型项目依赖关系复杂、不同组件依赖的兼容性问题:
Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
Docker应用运行在容器中,使用沙箱机制,相互隔离
Docker解决开发、测试、生产环境的差异问题:
- Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意的Linux系统上运行
概念
Docker与虚拟机
镜像和容器
Docker和DockerHub
Docker架构
快速入门
安装Docker
企业部署一般都是采用Linux操作系统,而其中又数CentOS发行版占比最多,所以安装Docker到CentOS下
卸载Docker(可选)
1
2
3
4
5
6
7
8
9
10
11yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce安装yum工具
1
2
3yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken更新本地镜像源
1
2
3
4
5
6
7
8设置docker镜像源
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
yum makecache fast安装Docker-CE
1
yum install -y docker-ce
启动Docker
启动前要关闭防火墙
1
2
3
4
5
6关闭
systemctl stop firewalld
禁止开机启动防火墙
systemctl disable firewalld
查看防火墙状态
systemctl status firewalld启动Docker
1
2
3
4systemctl start docker # 启动docker服务
systemctl stop docker # 停止docker服务
systemctl restart docker # 重启docker服务查看状态可以通过:
systemctl status dockerdocker -v
配置镜像加速
参考阿里云容器镜像服务:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
配置/etc/docker/daemon.json
1 | sudo mkdir -p /etc/docker |
Docker基本操作
镜像名称
镜像名称一般分为两部分组成:[repository]:[tag]
如果没有指定[tag],默认为latest最新版本
镜像操作命令
拉取pull
案例:从DockerHub拉取一个镜像
在DockerHub搜索镜像名
复制拉取命令
执行拉取命令等待
pull完成
导出save和加载load
案例:利用docker save将镜像导出磁盘,然后再通过load加载回来
利用docker 命令 –help查看
docker save和docker load的语法使用
docker tag创建新镜像mynginx1.0使用
docker save导出到磁盘1
2docker save -o mynginx.tar nginx:latest
导出成-o后面的mynginx.tar,镜像为nginx的最新版本使用
docker load导入镜像1
2docker load -i mynginx.tar
导入的来源为-i后的mynginx.tar
容器命令
案例1:创建运行Nginx容器
去DockerHub查看Nginx的容器运行命令
在80端口运行nginx容器映射到80端口上,可以通过
ip:80端口访问此nginx容器docker run --name 容器名 -p 80:80 -d nginx查看访问日志:
docker logs 容器名- 刷新查看日志:
docker logs -f 容器名
清理日志
- 进入容器目录:
cd /var/lib/docker/containers/容器ID - 查看大小:
ls -lh - 清空日志:
cat /dev/null > 容器ID-json.log
- 进入容器目录:
案例2:进入容器修改内容
要求:进入Nginx容器,修改HTML内容,添加一行文本
同理:操作redis容器
创建redis容器:
1
docker run --name myredis -p 80:80 -d redis redis-server --appendonly yes
进入容器:
进入bash命令进入然后启动redis-cli
1
2[root@master docker]# docker exec -it myredis bash
root@d5ae50394a6d:/data# redis-cli直接进入redis-cli命令
1
[root@master docker]# docker exec -it myredis redis-cli
现在即可使用redis的命令
查看已部署的容器信息
- 查看正在运行的容器:
docker ps - 查看所有容器,包括没有运行的:
docker ps -a - 查看容器信息并且不省略:
docker ps --no-trunc
数据卷
概念
数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录
基本语法
挂载数据卷
案例1:创建一个nginx容器,修改容器内的html目录内的index.html内容
执行docker run时利用-v指定了volume时若不存在,会自动创建此volume
案例2:创建并运行一个MySQL容器,将宿主机目录挂载到容器
创建启动容器
1
2
3
4
5
6
7
8docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123 \
-p 3306:3306 \
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \
-v /tmp/mysql/logs:/var/log/mysql \
-v /tmp/mysql/data:/var/lib/mysql \
-d mysql:5.7.25启动后
/etc/docker/mysql子目录会同步mysql的数据卷,并且可以通过3307端口登录root用户,密码123注意:自定义mysql端口需要给容器配置文件中指定
port=3307
修改mysql时区:
- 进入容器:
docker exec -it 容器名 bash - 查看当前系统时区:
date -R - 修改时区:
cp /usr/share/zoneinfo/PRC /etc/localtime - 退出容器后重启容器:
docker restart 容器名
redis容器案例
1 | docker run \ |
自定义镜像
镜像结构
- 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成
Dockerfile
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer
案例:基于Ubuntu镜像构建一个新镜像,运行一个java项目
简化:基于java:8-alpine镜像,将一个Java项目构建为镜像
DockerCompose
- Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器
- Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行
安装Docker Compose
下载安装Docker Compose
1
2安装
curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose或者通过上传本地的docker-compose到
/user/local/bin目录修改文件权限:添加可执行权限
1
chmod +x docker-compose
Bash自动补全命令
1
2补全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose- 可能需要修改hosts:
echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts
- 可能需要修改hosts:
案例:部署微服务集群
要求:将cloud-demo的order、user微服务项目利用Docker Compose部署
Docker镜像仓库
常见镜像仓库服务
镜像仓库(Docker Registry)有公共的和私有的两种形式:
- 公共仓库:例如Docker官方的DockerHub,国内也有一些云服务商提供类似于DockerHub的公开服务,例如网易云镜像服务、DaoCloud镜像服务、阿里云镜像服务等
- 私有仓库:用户可以在本地搭建私有Dcoker Registry。
搭建镜像仓库
简化版镜像仓库
Docker官方的Docker Registry是一个基础版本的Docker镜像仓库,具备仓库管理的完整功能,但是没有图形化界面。搭建方式比较简单,命令如下:
1 | docker run -d \ |
命令中挂载了一个数据卷registry-data到容器内的/var/lib/registry 目录,这是私有镜像库存放数据的目录。
访问http://YourIp:5000/v2/_catalog 可以查看当前私有镜像服务中包含的镜像
带有图形化界面版本
使用DockerCompose部署带有图形界面的DockerRegistry,命令如下:
1 | version: '3.0' |
由于私服采用的是http协议,默认不被Docker信任,所以需要做一个配置:
1 | 打开要修改的文件 |
部署成功后访问:ip:8080即可访问Docker Registry UI
在私有镜像仓库推送或拉取镜像:
Kubernetes
介绍
应用程序部署方式的演变
- 物理机部署:应用程序直接部署在物理机上
- 缺点:很难合理分配资源,应用程序之间容易产生影响
- 虚拟机部署:在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境
- 应用程序之间独立,但浪费了系统资源
- 容器化部署:与虚拟机类似,但是共享了操作系统
- 优点:
- 可以保证每个容器拥有自己的文件系统、CPU、内存、进程空间等
- 运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦
- 容器化的应用程序可以跨云服务商、跨Linux操作系统版本进行部署
- 优点:
容器化部署方式的问题:
- 一个容器故障停机,怎么样让另一个容器立刻启动去替补停机的容器
- 当并发访问量变大的时候,怎么做到横向扩展容器数量
这些容器管理的问题统称为容器编排问题,为了解决这些容器编排问题,产生了一些容器编排的软件:
- Swarm:Docker自己的容器编排根据
- Mesos:Apache的一个资源统一管控的工具,需要和Marathon结合使用
- Kubernetes:Google开源的容器编排工具
Kubernetes简介
Kubernetes是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器——Borg系统的一个开源版本,于2014年9月发布第一个版本,2015年7月发布第一个正式版本
Kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。它的目的是实现资源管理的自动化,主要提供了以下功能:
- 自我修复:一旦某个容器崩溃,能够在1秒左右迅速启动新的容器
- 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
- 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
- 负载均衡:如果一个服务启动了多个容器,能够自动实现请求的负载均衡
- 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
- 存储编排:可以根据容器自身的需求自动创建存储卷
Kubernetes组件
一个Kubernetes集群主要是由**控制节点(master)、工作节点(node)**构成。每个节点上都会安装不同的组件。
- master:集群的控制平面,负责集群的决策
- ApiServer:资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
- Scheduler:负责集群资源调度,按照预订的调度策略将Pod调度到相应的node节点上
- ControllerManager:负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等
- Etcd:负责存储集群中各种资源对象的信息
- node:集群的数据平面,负责为容器提供运行环境
- Kubelet:负责维护容器的生命周期,即通过控制docker来创建、更新、销毁容器
- KubeProxy:负责提供集群内部的服务发现和负载均衡
- Docker:负责节点上容器的各种操作