SpringBoot项目分离与分层方式之容器化部署

embedded/2025/1/11 21:40:22/

SpringBoot项目分离与分层方式之容器化部署

文章目录

  • 1.前言
  • 2.deom项目工程结构
  • 3.分离容器部署
    • 3.1父工程pom
    • 3.2子模块3的Dockerfile
    • 3.3子模块3的target
    • 3.4构建启动docker命令
  • 4.分层容器部署
    • 4.1父工程pom
    • 4.2子模块3的Dockerfile
    • 4.3子模块3的target
    • 4.4构建启动docker命令
  • 5.jekines脚本
  • 6.总结

1.前言

  之前也分享过分离与分层方式部署,本文只不过将之前的那两种方式放到了容器中来部署运行,里面多多少少还是有点坑在里面的,要相对简单一点直接使用如下命令部署:

java">nohup java -jar xxxx.jar --spring.profiles.active=xx ,,,,, > xxxx.log &

  使用容器部署方式就比这种更高级优雅一点,根据个人喜好去选择适合自己的部署方式。

  之前的文章链接如下:

https://blog.csdn.net/qq_34905631/article/details/126616809?spm=1001.2014.3001.5501
https://mp.weixin.qq.com/s/OTZ-VVn_VimHNcSdEaLYJw
https://blog.csdn.net/qq_34905631/article/details/126574085?spm=1001.2014.3001.5501
https://mp.weixin.qq.com/s/5mhF1ge_yYUA6tMCYi77Og

2.deom项目工程结构

image-20250110000123743

3.分离容器部署

3.1父工程pom

  这里只展示build的配置

<build><!--特别注意:项目仅仅是为了演示配置方便,直接在parent的build部分做了插件配置和运行定义。但是实际项目中需要把这些定义只放到spring boot模块项目(可优化使用pluginManagement形式),避免干扰其他util、common等模块项目--><plugins><!-- 跳过测试代码  maven版本需要3.6.3及以上版本 jeksion构建时候,maven版本需要3。6.3及以上版本--><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.5.2</version><configuration><skipTests>true</skipTests></configuration></plugin>--><!--Spring Boot模块jar构建--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.12.RELEASE</version><configuration><!-- 指定该Main Class为全局的唯一入口 --><mainClass>xxxx.xxxx.xxxx.xxxApplication</mainClass><!--解决windows命令行窗口中文乱码,该参数配置无效,需要容器启动命令中动态传入该参数才有效--><jvmArguments>-Dfile.encoding=UTF-8</jvmArguments><!--设置为true,以便把本地的system的jar也包括进来--><includeSystemScope>true</includeSystemScope><layout>ZIP</layout><classifier>exec</classifier><addResources>true</addResources><fork>true</fork><!--开启分层编译支持--><!-- <layers><enabled>true</enabled></layers>--><outputDirectory>${project.build.directory}</outputDirectory><skip>true</skip><includes><!-- 不存在的include引用,相当于排除所有maven依赖jar,没有任何三方jar文件打入输出jar--><!-- <include><groupId>null</groupId><artifactId>null</artifactId></include>--><!--这里是填写需要包含进去的jar,必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来如果没有则non-exists ,表示不打包依赖--><include><groupId>non-exists</groupId><artifactId>non-exists</artifactId></include><!--<include><groupId>*</groupId><artifactId>*-dto</artifactId></include>--><!--<include><groupId>xxxxx.xxxxx</groupId><artifactId>xxxx</artifactId></include>--></includes></configuration><executions><execution><goals><goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--></goals></execution></executions></plugin><!--拷贝资源文件--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.2.0</version><executions><execution><id>copy-resources</id><phase>package</phase><goals><goal>copy-resources</goal></goals><configuration><resources><resource><directory>src/main/resources</directory><excludes><exclude>static/**</exclude><exclude>*.xml</exclude><!-- 这里把yml文件排除 dockerfile文件中就不用拷贝yml文件,这种验证是ok的--><exclude>*.yml</exclude></excludes></resource></resources><outputDirectory>${project.build.directory}/resources</outputDirectory></configuration></execution></executions><configuration><nonFilteredFileExtensions><nonFilteredFileExtension>pem</nonFilteredFileExtension></nonFilteredFileExtensions></configuration></plugin><!--生成doc jar包--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-javadoc-plugin</artifactId><version>2.9</version><configuration><attach>true</attach><!-- utf-8读取文件 --><charset>UTF-8</charset><!-- utf-8进行编码代码 --><encoding>UTF-8</encoding><!-- utf-8进行编码文档 --><docencoding>UTF-8</docencoding></configuration><executions><execution><id>attach-javadocs</id><goals><goal>jar</goal></goals><configuration><additionalparam>-Xdoclint:none</additionalparam></configuration></execution></executions></plugin><!--生成源码jar包--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>3.2.1</version><executions><execution><id>attach-sources</id><goals><goal>jar</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.3.0</version><configuration><!-- 不打包资源文件--><excludes><!-- <exclude>static/**</exclude>--><exclude>*.properties</exclude><!--<exclude>*.xml</exclude>--><exclude>*.json</exclude><!-- yaml和yml这两个也可以注释了,dockerfile文件中不拷贝yaml文件[这个验证是ok的]--><!-- <exclude>*.yaml</exclude><exclude>*.yml</exclude>--><exclude>*.png</exclude><exclude>*.txt</exclude></excludes><archive><!--  &lt;!&ndash; 生成的jar中,不要包含pom.xml和pom.properties这两个文件 &ndash;&gt;--><addMavenDescriptor>false</addMavenDescriptor><manifest><!-- 指定程序入口 --><mainClass>xxx.xxxxx.xxxiApplication</mainClass><!-- 打包时 MANIFEST.MF文件不记录的时间戳版本,jar不包含唯一版本 --><useUniqueVersions>false</useUniqueVersions><!--MANIFEST.MF中的Class-Path加前缀--><addClasspath>true</addClasspath><!-- 服务依赖的jar包放在lib目录下 --><classpathPrefix>lib/</classpathPrefix><!--<addDefaultImplementationEntries>true</addDefaultImplementationEntries>--></manifest><manifestEntries><!-- &lt;!&ndash;有些非官方三方的诸如sdk jar在pom中是以systemPath方式引入的,maven-jar-plugin组件没有直接参数声明包含指定scope的组件通过使用额外定义 Class-Path 值来追加指定依赖组件列表,在子模块按实际情况指定 jar-manifestEntries-classpath 值即可例如(注意前面个点字符及各空格分隔符):. lib/xxx-1.0.0.jar lib/yyy-2.0.0.jar详见各子模块中 boot-jar-output 属性定义示例&ndash;&gt;--><Class-Path>./resources/</Class-Path><!--这里是一个坑,外部jar依赖分离打包需要在这里配置一下,有多个就配置多个--><Class-Path>lib/xxxxxx.xxxxx.jar lib/xxxxxx.xxxx.jar </Class-Path></manifestEntries></archive><outputDirectory>${project.build.directory}</outputDirectory></configuration></plugin><!-- 拷贝项目所有依赖jar文件到构建lib目录下 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>3.6.0</version><executions><execution><id>copy-dependencies</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><!--各子模块按照实际层级定义各模块对应的属性值,检查所有微服务模块依赖jar文件合并复制到同一个目录详见各子模块中 boot-jar-output 属性定义--><type>jar</type><includeTypes>jar</includeTypes><!-- 存放服务依赖的jar包,存放在服务相同目录的lib文件夹下 --><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin><!-- 跳过deploy --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version><configuration><skip>true</skip></configuration></plugin><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.1.0</version><configuration><failOnMissingWebXml>false</failOnMissingWebXml><warName>${project.artifactId}</warName></configuration></plugin>--></plugins><finalName>${project.artifactId}</finalName></build>

3.2子模块3的Dockerfile

FROM xxx基础镜像
VOLUME /resources
WORKDIR /app
ADD target/xxx.jar /app/app.jar
ADD target/lib /app/lib/
ADD target/resources/* /app/resources/
# COPY target/resources/*.yml /app/config/ 这种方式是将boostrap.yml文件拷贝到config,提升了加载优先级别,否则找不到这个yml
RUN echo "Asia/Shanghai" > /etc/timezone
EXPOSE xxx对外暴露监听端口
ENTRYPOINT java ${JAVA_OPTS} ${JAVA_PARAMETERS} ${SERVER_NAME}  -Xss1m -jar /app/app.jar

  容器中工作路径下有app.jar、config。resources这几项.

3.3子模块3的target

  子模块3打包之后target下文件如图所示:

image-20250110001324717

3.4构建启动docker命令

#进入到子模块三路劲中
docker build -t xx:v2.0.0 .
docker run -itd -p xxx:xxx --ip=本机ip(连接wifi的ip) -e JAVA_OPTS="-Xms200m -Xmx200m -Xss256K -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=jvm远程调试监听端口 -Dfile.encoding=UTF-8" --name xxx-xxxx-server xx:v2.0.0

4.分层容器部署

4.1父工程pom

  这里只展示build的配置

<build><!--特别注意:项目仅仅是为了演示配置方便,直接在parent的build部分做了插件配置和运行定义。但是实际项目中需要把这些定义只放到spring boot模块项目(可优化使用pluginManagement形式),避免干扰其他util、common等模块项目--><plugins><!-- 跳过测试代码  maven版本需要3.6.3及以上版本--><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.5.2</version><configuration><skipTests>true</skipTests></configuration></plugin>--><!--Spring Boot模块jar构建--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.12.RELEASE</version><configuration><mainClass>xxxlx.xxxx.xxxApplication</mainClass><includeSystemScope>true</includeSystemScope><!--&lt;!&ndash; 指定该Main Class为全局的唯一入口 &ndash;&gt;<mainClass>xxxx.xxxxx.xxApplication</mainClass>&lt;!&ndash;解决windows命令行窗口中文乱码,该参数配置无效,需要容器启动命令中动态传入该参数才有效&ndash;&gt;<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>&lt;!&ndash;设置为true,以便把本地的system的jar也包括进来&ndash;&gt;<includeSystemScope>true</includeSystemScope><layout>ZIP</layout><classifier>exec</classifier><addResources>true</addResources><fork>true</fork>--><!--开启分层编译支持--><layers><enabled>true</enabled></layers><!--<outputDirectory>${project.build.directory}</outputDirectory><skip>true</skip><includes>&lt;!&ndash; 不存在的include引用,相当于排除所有maven依赖jar,没有任何三方jar文件打入输出jar&ndash;&gt;&lt;!&ndash; <include><groupId>null</groupId><artifactId>null</artifactId></include>&ndash;&gt;&lt;!&ndash;这里是填写需要包含进去的jar,必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来如果没有则non-exists ,表示不打包依赖&ndash;&gt;<include><groupId>non-exists</groupId><artifactId>non-exists</artifactId></include>&lt;!&ndash;<include><groupId>*</groupId><artifactId>*-dto</artifactId></include>&ndash;&gt;&lt;!&ndash;<include><groupId>xxxxx.xxxxx</groupId><artifactId>xxxx</artifactId></include>&ndash;&gt;</includes>--></configuration><executions><execution><goals><goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--></goals></execution></executions></plugin><!--拷贝资源文件--><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.2.0</version><executions><execution><id>copy-resources</id><phase>package</phase><goals><goal>copy-resources</goal></goals><configuration><resources><resource><directory>src/main/resources</directory><excludes><exclude>static/**</exclude><exclude>*.xml</exclude>&lt;!&ndash; 这里把yml文件排除 dockerfile文件中就不用拷贝yml文件,这种验证是ok的&ndash;&gt;<exclude>*.yml</exclude></excludes></resource></resources><outputDirectory>${project.build.directory}/resources</outputDirectory></configuration></execution></executions><configuration><nonFilteredFileExtensions><nonFilteredFileExtension>pem</nonFilteredFileExtension></nonFilteredFileExtensions></configuration></plugin>--><!--生成doc jar包--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-javadoc-plugin</artifactId><version>2.9</version><configuration><attach>true</attach><!-- utf-8读取文件 --><charset>UTF-8</charset><!-- utf-8进行编码代码 --><encoding>UTF-8</encoding><!-- utf-8进行编码文档 --><docencoding>UTF-8</docencoding></configuration><executions><execution><id>attach-javadocs</id><goals><goal>jar</goal></goals><configuration><additionalparam>-Xdoclint:none</additionalparam></configuration></execution></executions></plugin><!--生成源码jar包--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>3.2.1</version><executions><execution><id>attach-sources</id><goals><goal>jar</goal></goals></execution></executions></plugin><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.3.0</version><configuration>&lt;!&ndash; 不打包资源文件&ndash;&gt;<excludes>&lt;!&ndash; <exclude>static/**</exclude>&ndash;&gt;<exclude>*.properties</exclude>&lt;!&ndash;<exclude>*.xml</exclude>&ndash;&gt;<exclude>*.json</exclude>&lt;!&ndash; yaml和yml这两个也可以注释了,dockerfile文件中不拷贝yaml文件[这个验证是ok的]&ndash;&gt;&lt;!&ndash; <exclude>*.yaml</exclude><exclude>*.yml</exclude>&ndash;&gt;<exclude>*.png</exclude><exclude>*.txt</exclude></excludes><archive>&lt;!&ndash;  &lt;!&ndash; 生成的jar中,不要包含pom.xml和pom.properties这两个文件 &ndash;&gt;&ndash;&gt;&lt;!&ndash; <addMavenDescriptor>false</addMavenDescriptor>&ndash;&gt;<manifest>&lt;!&ndash; 指定程序入口 &ndash;&gt;<mainClass>com.lq.invoice.LeQiApplication</mainClass>&lt;!&ndash; 打包时 MANIFEST.MF文件不记录的时间戳版本,jar不包含唯一版本 &ndash;&gt;<useUniqueVersions>false</useUniqueVersions>&lt;!&ndash;MANIFEST.MF中的Class-Path加前缀&ndash;&gt;<addClasspath>true</addClasspath>&lt;!&ndash; 服务依赖的jar包放在lib目录下 &ndash;&gt;<classpathPrefix>lib/</classpathPrefix>&lt;!&ndash;<addDefaultImplementationEntries>true</addDefaultImplementationEntries>&ndash;&gt;</manifest><manifestEntries>&lt;!&ndash; &lt;!&ndash;有些非官方三方的诸如sdk jar在pom中是以systemPath方式引入的,maven-jar-plugin组件没有直接参数声明包含指定scope的组件通过使用额外定义 Class-Path 值来追加指定依赖组件列表,在子模块按实际情况指定 jar-manifestEntries-classpath 值即可例如(注意前面个点字符及各空格分隔符):. lib/xxx-1.0.0.jar lib/yyy-2.0.0.jar详见各子模块中 boot-jar-output 属性定义示例&ndash;&gt;&ndash;&gt;<Class-Path>./resources/</Class-Path><Class-Path>lib/spire.pdf.free-9.13.0.jar</Class-Path></manifestEntries></archive><outputDirectory>${project.build.directory}</outputDirectory></configuration></plugin>&lt;!&ndash; 拷贝项目所有依赖jar文件到构建lib目录下 &ndash;&gt;<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>3.6.0</version><executions><execution><id>copy-dependencies</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration>&lt;!&ndash;各子模块按照实际层级定义各模块对应的属性值,检查所有微服务模块依赖jar文件合并复制到同一个目录详见各子模块中 boot-jar-output 属性定义&ndash;&gt;<type>jar</type><includeTypes>jar</includeTypes>&lt;!&ndash; 存放服务依赖的jar包,存放在服务相同目录的lib文件夹下 &ndash;&gt;<outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin>--><!-- 跳过deploy --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version><configuration><skip>true</skip></configuration></plugin><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.1.0</version><configuration><failOnMissingWebXml>false</failOnMissingWebXml><warName>${project.artifactId}</warName></configuration></plugin>--></plugins><finalName>${project.artifactId}</finalName></build>

  这个是用之前的分离打包的build改的,测试是ok的

4.2子模块3的Dockerfile

FROM xxxx基础镜像 AS builder
VOLUME /resources
WORKDIR /app
# 配置参数
ARG JAR_FILE=target/xxxx.jar
# 将编译构建得到的jar文件复制到镜像空间中
COPY ${JAR_FILE} /app/app.jar
#ADD target/lib /app/lib/
#ADD target/resources/* /app/resources/
# COPY target/resources/*.yml /app/config/
# 通过工具spring-boot-jarmode-layertools从application.jar中提取拆分后的构建结果
RUN java -Djarmode=layertools -jar app.jar extract
RUN echo "Asia/Shanghai" > /etc/timezone
# 正式构建镜像
FROM xxxx基础镜像
WORKDIR /app
# 前一阶段从jar中提取除了多个文件,这里分别执行COPY命令复制到镜像空间中,每次COPY都是一个layer
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./EXPOSE xxx对外暴露监听端口
ENTRYPOINT ["java","-Xms200m","-Xmx200m","-Xss256K","-Xdebug", "-Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=xxxxjvm远程调试监听端口", "-Dfile.encoding=UTF-8", "org.springframework.boot.loader.JarLauncher"]

  这种方式是用一个胖jar包来提取分层镜像构建的,缺点是不能动态传递启动参数,必须在ENTRYPOINT中写死。

4.3子模块3的target

  这种方式是一个正常的java胖jar包,所有的都打入到这个胖jar中,这里就不展示了。

4.4构建启动docker命令

#进入到子模块三路劲中
docker build -t xx:v2.0.0 .
docker run -itd -p xxx:xxxx --ip=本机ip(wifi连接的ip) --name lq-invoice-server xx:v2.0.0

5.jekines脚本

pipeline {agent anyenvironment {image_tag="xxxxx/xxxxx/xxxxxx:v1.0.${BUILD_NUMBER}"git_address="http://xxxx/xxxx/xx.git"git_branch="xxx"port=xxxxxgit_auth="xxxxxx"registry_name="xxxxx"registry_pwd="xxxx"container_name="xxxxxxxx"JAVA_OPTS="-javaagent:/agent/skywalking-agent.jar -Dskywalking.agent.service_name=[xxxx-xxxx-xxx] -Dskywalking.trace.ignore_path=/actuator/** -Xms512m -Xmx512m -Xss256K -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=xxxxxx"}stages {stage("拉取代码") {steps {git branch: "${git_branch}", credentialsId: "${git_auth}",url: "${git_address}"}}stage('质量扫描') {steps {echo '跳过扫描'}}stage('maven编译') {steps {sh 'mvn -B -f ./pom.xml clean install -DskipTests'}}stage('编译镜像') {steps {sh '''cd 子模块三路劲/cp target/*.jar ./docker build -t ${image_tag} .'''sh 'docker login --username=${registry_name} --password=${registry_pwd} xxxx.xxxx.xxxx私服域名'sh 'docker push ${image_tag}'sh 'docker rmi ${image_tag}'}}stage('部署服务') {steps {echo '自动部署'sh '''ssh root@服务器ip << remotesshdocker stop ${container_name}docker rm ${container_name}docker pull ${image_tag}docker run -d -p ${port}:${port} --net=host -e SERVER_PORT=${port} -e JAVA_OPTS="${JAVA_OPTS}" --name ${container_name} ${image_tag}exitremotessh'''}}}
}

  这个构建分离的是没有啥问题的,构建分层的这个docker run 需要修改一下,参数不能动态传了,直接修改为4.4构建启动docker命令的docker run命令部署即可。

6.总结

  这两种方式是之前分享之后的酝酿灵感思路融合实践总结,上面两种方式是互斥的,任选一种即可,希望我的分享对你有所启发和帮助,请一键三连,么么么哒!


http://www.ppmy.cn/embedded/153130.html

相关文章

2025年新出炉的MySQL面试题

&#x1f3a5; 作者简介&#xff1a; CSDN\阿里云\腾讯云\华为云开发社区优质创作者&#xff0c;专注分享大数据、Python、数据库、人工智能等领域的优质内容 &#x1f338;个人主页&#xff1a; 长风清留杨的博客 &#x1f343;形式准则&#xff1a; 无论成就大小&#xff0c;…

scrapy爬取图片

scrapy 爬取图片 环境准备 python3.10scrapy pillowpycharm 简要介绍scrapy Scrapy 是一个开源的 Python 爬虫框架&#xff0c;专为爬取网页数据和进行 Web 抓取而设计。它的主要特点包括&#xff1a; 高效的抓取性能&#xff1a;Scrapy 采用了异步机制&#xff0c;能够高效…

使用 `rsync + inotify` 实现实时文件同步:简单又高效

使用 rsync inotify 实现实时文件同步&#xff1a;简单又高效 在日常的运维工作中&#xff0c;文件的实时同步是一个非常常见的需求&#xff0c;比如&#xff1a; 网站更新&#xff1a;同步静态资源到多台服务器。备份数据&#xff1a;将生产数据实时备份到异地存储。日志传…

Vue3初学之插槽(slot)使用

在 Vue 3 中&#xff0c;插槽&#xff08;Slots&#xff09;是一种强大的内容分发机制&#xff0c;允许你在组件中定义可替换的内容区域&#xff0c;从而使组件更加通用和灵活。以下是 Vue 3 中插槽的几种常见用法&#xff1a; 默认插槽 默认插槽是最基本的插槽类型&#xff0…

IEC61850遥控-增强安全选控是什么?

摘要&#xff1a;遥控服务是IEC61850协议中非常重要的一项服务&#xff0c;其通常会被应用在电源开关、指示灯、档位调节等器件的操作。 遥控是一类比较特殊的操作&#xff0c;其通过远程方式操作指定的设备器件&#xff0c;在一些重要的场景中需要有严谨的机制来进行约束&…

力扣904.水果成篮

题目 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必须按照要求采摘水…

[CTF/网络安全] 攻防世界 Training-WWW-Robots 解题详析

[网络安全] 攻防世界 Training-WWW-Robots 解题详析 在这个小训练挑战中&#xff0c;你将学习 Robots_exclusion_standard&#xff08;机器人排除标准&#xff09;。 robots.txt 文件是由网络爬虫用来检查是否允许他们爬行和索引你的网站或仅部分内容。有时这些文件揭示目录结构…

网络安全-防火墙

0x00 前言 最近由于工作原因&#xff0c;需要详细如今各类网络安全设备&#xff0c;所以开了此系列文章&#xff0c;希望通过对每个网络安全设备进行整理总结&#xff0c;来详细了解各类网络安全设备作用功能以及实现原理、部署配置方法等。 0x01 定义&#xff1a;防火墙指的…