当前位置: 首页 > news >正文

SpringBoot-21 SpringBoot微服务的发布与部署(3种方式)

基于 SpringBoot 的微服务开发完成之后,现在到了把它们发布并部署到相应的环境去运行的时候了。

SpringBoot 框架只提供了一套基于可执行 jar 包(executable jar)格式的标准发布形式,但并没有对部署做过多的界定,而且为了简化可执行 jar 包的生成,SpringBoot 提供了相应的 Maven 项目插件:

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin> <!-- 其他插件定义 --></plugins>
</build> 

然后只要我们运行 mvn package,当前 SpringBoot 项目就会被打包成一个包含了其所有项目依赖以及该项目本身的可执行 jar 包,通过 scp 或者 rsync 等方式将这个可执行 jar 包部署到目标环境的服务器之后,就可以通过 java-jar your-project.jar 启动 SpringBoot 应用了。

整个流程看起来很简单,也很符合大部分开发人员的认知,但是,相对于一套较为严谨的软件交付流程来说,以上流程则难免过于粗糙了。

软件的发布和部署可以有多种不同的形式,这更多由软件项目的属性决定,比如:

  • 这个项目使用的是什么语言?
  • 这个项目属于类库项目还是可独立运行的项目?
  • 这个项目是面向什么平台和环境的项目?

此外,我们希望使用什么样的形式进行软件的交付,这里则涉及生态管理以及技术选型的喜好等因素,所以,为了降低讲解的复杂度,我们还是先将发布和部署分开来说吧。

首先,大家应该都知道,发布并不等于部署,这是两个阶段的事情,如图 1 所示。

发布与部署示意图

图 1 发布与部署示意图

发布一般是将项目以指定的格式打包成某种可直接交付的形式,然后放置到预先指定的交付地点。

比如对于 Java 类库(Java Library)来说,我们一般将其打包成 jar 包,然后 mvn deploy 到公司内部的 Maven 仓库中(Maven Repository),像 Nexus Repository Manager 或者 JFrog Artifactory 以及 Apache Archiva。

而对于可独立运行的程序,比如 SpringBoot 微服务或者一般的 Java Standalone 程序,我们既可以将它们打包成 RPM、DEB 等面向特定目标系统的发布形式,也可以将它们制作成一个个的 docker images,然后将制作完成的发布成品存储到相应的仓库中(Repository)去。

部署一般紧接着发布完成之后进行,它的主要职能就是将已经发布好的成品从仓库中拿出来,然后分发到目标环境的指定资源池(比如物理机结点,虚拟机结点,docker 宿主机等),并最终启动服务。

软件成品分发的手段和工具可以有很多种,从最常见的 scp、rsync,到 Chef、Puppet,进而再到最新的 saltstack、ansible 等,一般根据团队对这些工具的把控力度和喜好进行选型。

下面我们就几种典型的发布和部署形式跟大家一起探索相应的实践。

spring-boot-starter 的发布与部署方式

spring-boot-starter(s)属于 Java 类库性质的组件,只被其他可独立运行的程序依赖使用,自身不可独立运行,对于这种性质的软件实体,我们一般将其发布到公司内部的软件仓库或者以开源形式发布到 Maven 的中央仓库(Maven Central Repository)。

下面我们就以 spring-boot-starter-metrics 为例,向大家展示如何将类似 spring-boot-starter-metrics 这样的 Java 类库发布到自己公司内部搭建的 Nexus 服务器上。

首先,你要有一套已经搭建完成并运行的 Nexus 服务器,然后我们需要对 spring-boot-starter-metrics 的 pom.xml 附加一点儿发布相关的内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.keevol</groupId><artifactId>spring-boot-starter-metrics</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>spring-boot-starter-metrics</name><description>auto configuration module for dropwizard metrics</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.0.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><distributionManagement><repository><id>deployment</id><name>internal repository for releases</name><url>http://{内部nexus服务器地址}/nexus/content/repositories/ releases/</url></repository><snapshotRepository><id>deployment</id><name>internal repository for snapshots</name><url>http://{内部nexus服务器地址}/nexus/content/repositories/ snapshots/</url></snapshotRepository></distributionManagement><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version><metrics.version>3.1.2</metrics.version></properties> <!--其他配置 --><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.dropwizard.metrics</groupId><artifactId>metrics-core</artifactId><version>${metrics.version}</version></dependency><dependency><groupId>io.dropwizard.metrics</groupId><artifactId>metrics-annotation</artifactId><version>${metrics.version}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.7</version></dependency></dependencies>
</project>

主要关注我们添加的 distributionManagement 相关内容,用于将我们的当前项目与内部的 Nexus 服务器进行关联,这样,就可以将当前项目不同阶段的成品(比如 SNAPSHOT 版本或者 RELEASE 版本)发布到特定的仓库路径下。

但是,只是在项目的 pom.xml 中添加 distributionManagement 相关内容还不够,对发布服务器的安全管控等敏感信息不能与 pom.xml 一同公开,所以,还需要在 ~/.m2/settings.xml 配置文件中添加 Nexus 服务器访问和认证信息:

<server><id>deployment</id><username>deployment</username><password>********</password>
</server>

因为我们前面 distributionManagement 定义的 repository 和 snapshotRepository 的 id 都是 deployment,所以,这里的 server 的 id 也是匹配性地指定为 deployment,至于 username 和 password,则完全是我们内部的 nexus 服务器对应的安全认证用的用户名和密码啦。

将内部 Nexus 服务器的认证信息放到 maven 的 settings.xml 中并非什么好的实践,纯粹是为了便利性而牺牲安全性,二者之间需要根据情况做出权衡,如果对安全性要求比较高的公司或者组织,最好将这些认证信息移除,并只在管控的范围内使用。

比如将这些认证信息回收到发布和部署平台这一可控的小范围环境中,而所有开发人员使用的 settings.xml 属于“消毒”后无安全认证等敏感信息的版本。

当 pom.xml 中的 distributionManagement 以及 settings.xml 中对应的 server 设定都准备好之后,我们就可以直接 mvn deploy 将 spring-boot-starter-metrics 或者类似的 Java Library 项目发布到内部 Nexus 仓库了。

对于 Java 类库类型的项目来说,并无明确的部署过程,如果说有,也是存在于可独立运行项目的开发过程中,比如使用 lib 目录或者结合 Ant“部署”为项目的依赖,或者直接享受 maven、gradle、sbt 等编译工具提供的“透明”的依赖部署过程。

基于RPM的发布与部署方式

部署的目标服务器从硬件到系统软件,一般情况下都应该是尽量相同,这与软件的标准化目的相同,一个是可以减少应对不同类型实体的复杂度,另一个就是标准化硬件和软件之后,就可以通过工具批量化以“边际成本递减”近乎为 0 的做法来提升效率,减少成本。

所以,对于大部分互联网公司来说,在硬件标准化的基础上,还会使操作系统尽量统一,比如大多数都是使用稳定性和可靠性经过长期验证过的 Red Hat CentOS 系统,而 CentOS 本身经过长期的沉淀也有一套自己的系统管理工具,比如像 YUM 或者 RPM 这样的系统包依赖管理器(Debian/Ubuntu 等 Linux 发行版也有对应的 deb 形式的包管理器)。

像 RPM 这样的包管理器对系统软件包的依赖和配置提供了很好的支持,如果我们的微服务等可独立执行实体要部署到像 CentOS 这样的目标环境中,使用 RPM 完成微服务的发布和部署,对于运维人员来说几乎就是无缝衔接的。

而且,对于 SpringBoot 微服务来说,单单一个可执行的 jar 包实际上是远远无法达到发布和部署要求的,如果只是发布一个可执行的 jar 包,那就意味着在部署阶段,运维要做更多的事情来弥补某些缺失,比如:

  • 启动参数是否调整?
  • 配置文件是否修改?
  • 安装部署结构如何规范?
  • 资源的对接和映射要不要做?

但是,如果我们能够将整个软件交付体系标准化和规范化,然后通过 RPM 这样的发布形式将这些标注和规范固化到发布包中,那么,整个部署过程就可以简化为一条命令,这其实也是使用 RPM 这种系统原生包管理工具完成交付部署的好处:自动化的 orcherstration,减少不必要的人工干预中间环节。

使用 RPM 发布 SpringBoot 微服务,我们简单将这一个过程划分为几步,如图 2 所示。

使用RPM交付的SpringBoot微服务发布流程图

图 2 使用 RPM 交付的 SpringBoot 微服务发布流程图

首先,我们需要有一个特定的编译和项目构建环境,可以不管这个编译和项目构建环境是搭建在本地(比如你的开发机上),还是搭建在特定的一台服务器上,但这个编译和项目构建环境需要安装 rpmbuild,用来构建 rpm 包。

其次,我们不推荐 RPM 编译和构建的过程使用某些定义在项目编译脚本中的插件来完成,这样会让一些通用的逻辑散落在所有需要发布的项目中而不好治理。所以,我们建议使用一个外部化的独立的编译服务器完成整个 SpringBoot 微服务的 RPM 发布和部署。

SpringBoot 微服务的 rpmbuild 脚本构建过程主要分几个主要步骤(如图 2 中 1 所标注):

1)调用标准的 mvn package 完成可执行 jar 包的打包。

2)根据软件交付规范,构建标准发布格式的 rpm 包,如下所示:

  • 使用 bin 目录存放根据脚本模板以及环境变量生成的启停脚本。
  • 使用 config 目录(SpringBoot 默认文件系统中的配置目录名)或者 conf 目录存放特定的配置文件。
  • 使用 docs 目录存放文档。
  • 使用 agents 目录存放某些 javaagent。
  • ……

3)在标准发布格式的基础上,生成从标准发布格式到具体目标环境的映射。

比如原来应用的日志是默认打印到当前项目部署目录,而根据要求,我们希望打印到 /var/logs/{projectId}/ 或者其他服务器磁盘容量分配更大的分区,这个时候,可以在 rpmbuild 过程中指定安装类似的安装规则。

下面是一个简化的 SpringBoot 微服务的 rpmbuild 脚本定义:

Summary: metrics autoconfigure module for spring boot
applicationName: spring-boot-starter-metricsVersion: {version}Release: 1Copyright: ...Group: Applications/ProductivitySource: ...URL: ...Distribution: Vendor: KEEp eVOLution, Inc.Packager: Darren <afoo@keevol.com>%description%prep%buildgit clone ....
# 检出代码到本地cd {project folder}mvn package ...%install%clean%files/{install_location}/{projectId}/bin/start.sh/{install_location}
/{projectId}/bin/stop.sh/{install_location}/{projectId}/agents/jolokia-jvm-1.3.1-agent.jar...%attr(755, user, group) /{install_location}/{projectId}/agents/jolokia-jvm-1.3.1-agent.jar...%doc%changelog

然后需要调用 rpmbuild 的 spec 定义完成最终 rpm 包的构建:

rpmbuild -bb {projectId}.spec#

然后 scp or sftp 生成的 rpm 包到指定的 rpm 仓库 我们可以像上面那样直接执行 rpmbuild 命令完成最终的 rpm 包构建,也可以将这些逻辑纳入编译构建脚本并部署到像 Jenkins 这样现成的持续集成服务器上,总之,执行完成后,打包好的 rpm 就发布到目标环境对应的 rpm 仓库了。

rpm 包发布到 rpm 仓库之后,就可以执行部署,比如通过 Salt 或者 ansible 在目标环境执行 rpm 或者 yum 命令,但具体的部署行为可能因为不同开发者的习惯和理念而有所不同。

有的开发者喜欢将不同目标环境的配置都一股脑地打包到发布包中,然后通过配置文件的命名和启动程序时单独指定一个环境变量来决定如何启用哪一个配置文件,对于这种做法,只需要打一个 rpm 包,同时也只需要搭建一个内部的 rpm 仓库,部署的时候,则需要运维人员根据具体的操作环境传递相应的环境变量来启停程序。

有的开发者则认为,一个软件实体发布的时候就应该是针对目标环境“装配”完备的,rpm 包中的各项配置都是针对特定目标环境配置好的,只要将 rpm 包部署到目标环境,就可以直接启动,启停完全无差别操作,唯一的差别是,rpm 包分别是根据目标环境发布和部署到不同的 rpm 仓库的,如图 3 所示。

“根据不同交付目标环境,设置不同RPM仓库作为交付地点”示意图

图 3 “根据不同交付目标环境,设置不同RPM仓库作为交付地点”示意图

以上两种策略并无优劣之分,但却有各自适合的场景:

1)在团队小,以人为本的时候,前者更适合,原因在于,整个软件交付链路更多是通过开发人员来协调和完成的。所以,开发、测试、运维一把抓,即使是不同环境的配置文件,也都是为了开发人员方便,直接放到了项目目录下一起管理和修改。

当到了线上,开发人员同时担当运维人员的角色,启停程序的可控性也很高,所以,可以在熟知自身程序的前提下,很好地完成整个链路的工作。

2)随着团队规模的扩张,职能更加明确,交付链路要承担的关注点也更多的时候,为了保证整个软件的交付质量,需要引入规范化的流程来关联和约束整个链路上各个环节和团队之间的工作。

这个时候,开发人员的职责范围将缩小到明确的范围,测试团队、安全团队、应用运维团队等也将加入并根据流程各司其职,每个团队之间的工作需要横向关联的同时,又需要垂直隔离。

这个时候,我们就需要从交付的源头一直到发布和部署,根据环境进行隔离,每个人即使只关注自己负责的事情,也可以让整个软件交付链路很好地工作,这考虑的是规范和流程对整体粒度上的把控和支撑。

对于小团队来说,微服务并不是什么太好的选择,高内聚的应用开发和部署单元,对整个交付链路的要求没那么高,也不需要更多自动化和平台化层面的投入和支持。

而一旦你选择了微服务的软件交付策略,数量庞大的微服务治理将耗费更多资源在支撑整个交付链路的自动化和平台化建设层面。否则,如此数量上的差异化的实体管理,单纯还靠人工拼苦劳是“捞不着好果子吃的”。

所以,我们要标准化和规范化微服务的开发、交付、部署以及运维,从而收敛整条链路的治理复杂度,以近乎无差别的方式,完成各个环节上的工作。这个时候,规范、流程、平台是核心,对人的要求则适当降低。

说了这么多,其实就一点,如果团队要转向微服务的交付策略,那么,标准化、单一化的微服务发布和部署行为是大家努力的方向,虽然我们在说基于 RPM 这种特定的微服务发布和部署形式,但并不意味着我们只应该关注这一点或者这单一环节,只有系统的从整体的微服务交付链路和体系层面考虑,才能够在各个单一环节落地的时候选择合适的方案。

基于 RPM 的发布与部署方式就说这么多,希望对大家有所启发。

基于 Docker 的发布与部署方式

随着资源虚拟化技术的持续精进,一种基于容器(container)的方式开始风行,Docker 就属于当下这个风口上最耀眼的明星,而且,很多微服务相关的文章也是言必提 Docker,好像没有 Docker 的微服务就不是正宗的微服务了,所以,我们自然也要适当提及一下如何结合 Docker 发布和部署我们的 SpringBoot 微服务。

我们知道,RPM 包的构建是使用系统的 rpmbuild 工具完成的,该工具需要一个构建描述文件,即 .spec 文件,rpmbuild 工具读取 .spec 构建描述文件之后,根据构建描述文件生成一个 rpm 包,然后我们就可以把 rpm 包发布到相应的 RPM 仓库(RPM Repository)。

使用 Docker 其实也是类似的过程,如图 4 所示。

基于Docker的SpringBoot微服务发布流程图

图 4 基于Docker的SpringBoot微服务发布流程图

我们需要提供一个 Dockerfile 用于描述 Docker 发布成品的构建过程,这类似于 rpmbuild 需要的 .spec 文件。

在编写好要使用的 Dockerfile 之后,我们使用 docker build 命令读取 Dockerfile 开始构建一个 Docker 的 image,docker build 完成 rpmbuild 类似的功能,Docker 的 image 则类似于 rpm 包,即 Docker 的软件发布成品。

有了 docker image 之后,我们就可以将其发布到一个 Docker 的 image registry,这里的 image registry 就类似于 RPM 仓库(RPM Repository),而将 docker image 发布到 image registry 的过程,可以通过 docker push 完成。

所以,假设要以 Docker 的形式发布我们的汇率查询 SpringBoot 微服务,首先需要编写一个对应的 Dockerfile 来构建相应的 docker image:

FROM java:8MAINTAINER AFOO <afoo@afoo.me>LABEL
groupId=...LABEL artifactId=...LABEL
version=...LABEL ...USER deployerEXPOSE 8080ENV
{key}={value}...VOLUME ...RUN mkdir /{group}/{projectId}/configRUN mkdir /{group}/{projectId}/agentRUN mkdir /{group}/{projectId}/docsRUN mkdir /{group}/{projectId}/libCOPY target/docker-springboot-chapter4-0.0.1-SNAPSHOT.jar /{group}/{projectId}/lib/docker-springboot-chapter4-0.0.1-SNAPSHOT.jarCOPY conf/application.properties /{group}/{projectId}/config/application.propertiesCOPY agent/jolokia-jvm-1.3.3-agent.jar /{group}/{projectId}/jolokia-jvm-1.3.3-agent.jar...ENTRYPOINT ["java", "...", "-jar", "lib/docker-springboot-chapter4-0.0.1-SNAPSHOT.jar"] 

之后,我们就可以使用这个 dockerfile 来进行构建并发布了:

$ docker build . -t "{groupId}/{artifactId}:{version}

$ docker push 基于 Docker 的微服务部署与 RPM 类似,都是从发布仓库中拉取发布的成品,并在目标环境安装部署,一般情况下我们也同样是使用 Salt 或者 Ansible 之类的工具执行如下类似的命令完成基于 Docker 的微服务的部署:

$ ansible {cluster} -m shell -a "cd /microservices/{groupId}/{artifactId}; docker pull"

为了简化基于 Docker 的发布和部署流程,实际上,以上演示的只是单人单微服务项目的方法,在讲究集团军作战的微服务场景下,我们希望的是能够快速、批量且标准化的形式完成数量巨大的微服务发布和部署。

这就要求不能只盯着单一项目内部去思考如何实现发布和部署,而应该将视线从单一项目内部抽取出来,以更高的视角来审视如何快速地完成批量微服务的发布和部署。

笔者建议的一个思路是适当地弱化 Docker 属性,将发布和部署逻辑外部化到发布脚本中。

外部化后的发布脚本将集中协调 Docker 基础设施,要发布的微服务上下文信息以及其他中间步骤,将微服务项目与 Docker 挂钩的唯一纽带也仅仅是一个模板化、标注化后的 Dockerfile,整个过程如图 5 所示。

外部化的基于Docker的SpringBoot微服务发布脚步逻辑流程图

图 5 外部化的基于Docker的SpringBoot微服务发布脚步逻辑流程图

如此一来,对于所有希望以 Docker 形式发布的标准化的微服务来说,一套发布脚本即可完成所有微服务的发布和部署,而不需要每一个微服务自己去编写 Dockerfile 甚至发布脚本。

上面的 Docker 实践并非 Docker 社区建议的最佳实践方式,这里更多只是为了简化说明和对比,Docker 背后是一套更为庞大完备的体系,比如 Docker 容器的注册和发现,容器的编排及调度等功能和系统,限于篇幅和内容定位,这里不再赘述。

总的来说,其实基于 Docker 的微服务发布和部署与其他形式从本质上来说没有太大差别,唯一的差别只是各自方案特定的实现不同而已。

大部分人选择和认同 Docker 方案,更多是从系统资源利用率以及 Docker 对整个软件交付链路的支撑体系比较完备这些角度考虑的,而微服务自身的很多特点以及需求(比如隔离、轻量),恰好与 Docker 能提供的相互吻合,或许这就是二者经常被“相提并论”的原因。

不过,对于 Java 应用和微服务来说,Docker 能给予的好处可能没有想象的那么多。



喜欢的朋友记得点赞、收藏、关注哦!!!

相关文章:

SpringBoot-21 SpringBoot微服务的发布与部署(3种方式)

基于 SpringBoot 的微服务开发完成之后&#xff0c;现在到了把它们发布并部署到相应的环境去运行的时候了。 SpringBoot 框架只提供了一套基于可执行 jar 包&#xff08;executable jar&#xff09;格式的标准发布形式&#xff0c;但并没有对部署做过多的界定&#xff0c;而且为…...

在occluded Person Re-ID中,选择clip还是ViT作为backbone?

在遮挡行人再识别&#xff08;Occluded Person Re-Identification, Occluded Person Re-ID&#xff09;任务中&#xff0c;使用CLIP&#xff08;Contrastive Language-Image Pre-Training&#xff09;作为backbone和使用Vision Transformer&#xff08;ViT&#xff09;作为back…...

Linuxnat网络配置

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…...

77.WEB渗透测试-信息收集-框架组件识别利用(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;76.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;16&#xff09; java&#xff…...

ExcelJS:轻松实现Excel文件的读取、操作与写入

文章目录 发现宝藏1. 简介2. 安装3. 创建工作簿4. 设置工作簿属性5. 添加工作表6.删除工作表7.访问工作表8. 列操作9. 行操作10. 单元格操作 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝…...

Java 多线程技术详解

文章目录 Java 多线程技术详解目录引言多线程的概念为什么使用多线程&#xff1f;多线程的特征多线程的挑战 多线程的实现方式3.1 继承 Thread 类示例代码&#xff1a; 3.2 实现 Runnable 接口示例代码&#xff1a; 3.3 使用 Executor 框架示例代码&#xff1a; 3.4 使用 Calla…...

一份简单实用的MATLAB M语言编码风格指南

MATLAB M语言编码风格指南 1. 文件命名2. 函数命名3. 注释4. 变量命名5. 布局、注释和文档6. 代码结构7. 错误处理8. 性能优化9. 格式化输出 MATLAB M文件的编码规范对于确保代码的可读性、可维护性和一致性非常重要。下面是一份MATLAB M语言编码规范的建议&#xff0c;可以作为…...

ubuntu 环境下soc 使用qemu

构建vexpress-a9的linux内核 安装依赖的软件 sudo apt install u-boot-tools sudo apt install gcc-arm-linux-gnueabi sudo apt install g-arm-linux-gnueabi sudo apt install gcc#编译内核 下载 linux-5.10.14 linux-5.10.148.tar.gz 配置 sudo tar -xvf linux-5.10.1…...

Centos安装、迁移gitlab

Centos安装迁移gitlab 一、下载安装二、配置rb修改&#xff0c;起服务。三、访问web&#xff0c;个人偏好设置。四、数据迁移1、查看当前GitLab版本2、备份旧服务器的文件3、将上述备份文件拷贝到新服务器同一目录下&#xff0c;恢复GitLab4、停止新gitlab数据连接服务5、恢复备…...

【Python机器学习】朴素贝叶斯——使用Python进行文本分类

目录 准备文本&#xff1a;从文本中构建词向量 训练算法&#xff1a;从词向量计算概率 测试算法&#xff1a;根据现实情况修改分类器 准备数据&#xff1a;文档词袋模型 要从文本中获取特征&#xff0c;需要先拆分文本。这里的特征是来自文本的词条&#xff0c;一个词条是字…...

【linux】Shell脚本三剑客之grep和egrep命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...

Spring条件装配:灵活配置你的应用

文章目录 摘要1. 条件装配概述1.1 什么是条件装配1.2 为什么需要条件装配 2. 使用Conditional注解2.1 Conditional注解简介2.2 编写自定义条件类2.3 应用Conditional注解 3. 内置的条件注解3.1 ConditionalOnClass3.2 ConditionalOnMissingBean3.3 ConditionalOnProperty 4. 使…...

【前端 08】简单学习js字符串

JavaScript中的String对象详解 在JavaScript中&#xff0c;字符串&#xff08;String&#xff09;是一种非常基础且常用的数据类型&#xff0c;用于表示文本数据。虽然JavaScript中的字符串是原始数据类型&#xff0c;但它们的行为类似于对象&#xff0c;因为JavaScript为字符…...

【LLM】-07-提示工程-聊天机器人

目录 1、给定身份 1.1、基础代码 1.2、聊天机器人 2、构建上下文 3、订餐机器人 3.1、窗口可视化 3.2、构建机器人 3.3、创建JSON摘要 利用会话形式&#xff0c;与具有个性化特性&#xff08;或专门为特定任务或行为设计&#xff09;的聊天机器人进行深度对话。 在 Ch…...

AvaloniaUI的学习

相关网站 github:https://github.com/AvaloniaUI/Avalonia 官方中文文档&#xff1a;https://docs.avaloniaui.net/zh-Hans/docs/welcome IDE选择 VS2022VSCodeRider 以上三种我都尝试过&#xff0c;体验Rider最好。VS2022的提示功能不好&#xff0c;VSCode太慢&#xff0c…...

刷题——快速排序

【全网最清晰快速排序&#xff0c;看完快排思想和代码全部通透&#xff0c;不通透你打我&#xff01;-哔哩哔哩】 https://b23.tv/8GxEKIk 代码详解如上 #include <iostream> using namespace std;int getPort(int* a, int low, int high) {int port a[low];while(low…...

VPN,实时数据显示,多线程,pip,venv

VPN和翻墙在本质上是不同的。想要真正实现翻墙&#xff0c;需要选择部署在墙外的VPN服务。VPN也能隐藏用户的真实IP地址 要实现Python对网页数据的定时实时采集和输出&#xff0c;可以使用Python的定时任务调度模块。其中一个常用的库是APScheduler。您可以编写一个函数&#…...

自然语言处理(NLP)

自然语言处理&#xff08;NLP&#xff09;是计算机科学与人工智能领域的一个重要研究方向&#xff0c;它致力于让计算机能够理解、分析、处理和生成人类语言。在NLP领域&#xff0c;存在着许多常见的任务&#xff0c;这些任务通常对应着不同的算法和技术。以下将详细列举几个NL…...

Spring Boot集成Spire.doc实现对word的操作

1.什么是spire.doc? Spire.Doc for Java 是一款专业的 Java Word 组件&#xff0c;开发人员使用它可以轻松地将 Word 文档创建、读取、编辑、转换和打印等功能集成到自己的 Java 应用程序中。作为一款完全独立的组件&#xff0c;Spire.Doc for Java 的运行环境无需安装 Micro…...

在Spring Boot中优化if-else语句

在Spring Boot中&#xff0c;优化if-else语句是提升代码质量、增强可读性和可维护性的重要手段。过多的if-else语句不仅会使代码变得复杂难懂&#xff0c;还可能导致代码难以扩展和维护。以下将介绍七种在Spring Boot中优化if-else语句的实战方法&#xff0c;每种方法都将结合示…...

【Django】开源前端库bootstrap,常用

文章目录 下载bootstrap源文件到本地项目引入bootstrap文件 官网&#xff1a;https://www.bootcss.com/V4版本入口&#xff1a;https://v4.bootcss.com/V5版本入口&#xff1a;https://v5.bootcss.com/ 这里使用成熟的V4版本&#xff0c;中文文档地址&#xff1a;https://v4.b…...

2024后端开发面试题总结

一、前言 上一篇离职贴发布之后仿佛登上了热门&#xff0c;就连曾经阿里的师兄都看到了我的分享&#xff0c;这波流量真是受宠若惊&#xff01; 回到正题&#xff0c;文章火之后&#xff0c;一些同学急切想要让我分享一下面试内容&#xff0c;回忆了几个晚上顺便总结一下&#…...

opencascade AIS_Manipulator源码学习

前言 AIS_Manipulator 是 OpenCASCADE 库中的一个类&#xff0c;用于在3D空间中对其他交互对象或一组对象进行局部变换。该类提供了直观的操控方式&#xff0c;使用户可以通过鼠标进行平移、缩放和旋转等操作。 详细功能 交互对象类&#xff0c;通过鼠标操控另一个交互对象…...

Hadoop、Hive、HBase、数据集成、Scala阶段测试

姓名&#xff1a; 总分&#xff1a;Hadoop、Hive、HBase、数据集成、Scala阶段测试 一、选择题&#xff08;共20道&#xff0c;每道0.5分&#xff09; 1、下面哪个程序负责HDFS数据存储&#xff08; C &#xff09; A. NameNode B. Jobtracher C. DataNode D. Sec…...

go语言day19 使用git上传包文件到github Gin框架入门

git分布式版本控制系统_git切换head指针-CSDN博客 获取请求参数并和struct结构体绑定_哔哩哔哩_bilibili &#xff08;gin框架&#xff09; GO: 引入GIn框架_go 引入 gin-CSDN博客 使用git上传包文件 1&#xff09;创建一个github账户&#xff0c;进入Repositories个人仓…...

Ubuntu升级软件或系统

Ubuntu升级软件或系统 升级Ubuntu系统通常是一个相对简单的过程&#xff0c;但在进行操作之前&#xff0c;请务必备份重要数据以防万一。下面是升级Ubuntu系统的一般步骤&#xff1a; 使用软件更新工具升级系统 打开终端&#xff1a; 按下 Ctrl Alt T 组合键打开终端。 更…...

【Redis】Centos7 安装 redis(详细教程)

查看当前 Redis 版本&#xff1a; 当前的 redis 版本太老了&#xff0c;选择安装 Redis5。 一、使用 yum 安装 1、首先安装 scl 源 yum install centos-release-scl-rh 由于我之前已经安装过了&#xff0c;所以加载速度比较快&#xff0c;且显示已经安装成功&#xff0c;是最…...

Hakuin:一款自动化SQL盲注(BSQLI)安全检测工具

关于Hakuin Hakuin是一款功能强大的SQL盲注漏洞安全检测工具&#xff0c;该工具专门针对BSQLi设计&#xff0c;可以帮助广大研究人员优化BSQLi测试用例&#xff0c;并以自动化的形式完成针对目标Web应用程序的漏洞扫描与检测任务。 该工具允许用户以轻松高效的形式对目标Web应…...

在 Postman 中设置全局 token

目录 问题描述解决方案 问题描述 在使用 Postman 进行接口测试时&#xff0c;经常会遇到在 Header 中添加 token 的情况。当接口数量较多时&#xff0c;需要为每个接口进行设置&#xff0c;而且当 token 失效时需要重新获取并设置&#xff0c;这样一来效率较低。 解决方案 下…...

Linux C编程:打造一个插件系统

title: ‘Linux C编程:打造一个插件系统’ date: 2017-03-07 21:16:36 tags: linux C layout: post comments: true 运行环境&#xff1a;linux 使用语言&#xff1a;c 或者c 插件&#xff0c;很多人用过&#xff0c;比如游戏插件&#xff0c;编辑器插件这些&#xff0c; 最著…...

基于毫米波生物感知雷达+STM32设计的独居老人居家监护系统(微信小程序)(192)

基于毫米波生物感知雷达设计的独居老人居家监护系统(微信小程序)(192) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】60G毫米波生物感知雷达原理【3】ESP8266模块配置【4】供电方式1.3 项目开发背景【1】选题的意义…...

C++——类和对象(下)

目录 一、再探构造函数 1.基本定义以及用法 2.必须在初始化列表初始化的成员变量 3.成员变量声明位置的缺省值&#xff08;C11&#xff09; 4.成员变量初始化顺序 二、隐式类型转换 三、static成员 四、友元 五、内部类 六、匿名对象 七、日期类实现 一、再探构造函数…...

Android中集成前端页面探索(Capacitor 或 Cordova 插件)待完善......

探索目标&#xff1a;Android中集成前端页面 之前使用的webview加载html页面&#xff0c;使用bridge的方式进行原生安卓和html页面的通信的方式&#xff0c;探索capacitor-android插件是如何操作的 capacitor-android用途 Capacitor 是一个用于构建现代跨平台应用程序的开源框…...

玩转CSS:用ul li +JS 模拟select,避坑浏览器不兼容。

玩转CSS&#xff1a;用ul li JS 模拟select&#xff0c;避坑浏览器不兼容。 在前端的工作中&#xff0c;经常会遇到 selcet控件&#xff0c;但我们用css来写它的样式时候&#xff0c;总是不那么令人满意&#xff0c;各种浏览器不兼容啊有没有&#xff1f; 那么&#xff0c;我…...

介绍下PolarDB

业务中用的是阿里云自研的PolarDB&#xff0c;分析下PolarDB的架构。 认识PolarDB 介绍 PolarDB是阿里云自研的&#xff0c;兼容MySQL、PostageSQL以及支持MPP的PolarDB-X的高可用、高扩展性的数据库。 架构 部署 云起实验室 - 阿里云开发者社区 - 阿里云 (aliyun.com) 数…...

基于微信小程序+SpringBoot+Vue的儿童预防接种预约系统(带1w+文档)

基于微信小程序SpringBootVue的儿童预防接种预约系统(带1w文档) 基于微信小程序SpringBootVue的儿童预防接种预约系统(带1w文档) 开发合适的儿童预防接种预约微信小程序&#xff0c;可以方便管理人员对儿童预防接种预约微信小程序的管理&#xff0c;提高信息管理工作效率及查询…...

go语言day15 goroutine

Golang-100-Days/Day16-20(Go语言基础进阶)/day17_Go语言并发Goroutine.md at master rubyhan1314/Golang-100-Days GitHub 第2讲-调度器的由来和分析_哔哩哔哩_bilibili 一个进程最多可以创建多少个线程&#xff1f;-CSDN博客 引入协程 go语言中内置了协程goroutine&#…...

Mindspore框架循环神经网络RNN模型实现情感分类|(六)模型加载和推理(情感分类模型资源下载)

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…...

System类

System类常见方法 ① exit 退出当前程序 public static void main(String[] args) {System.out.println("ok1");//0表示状态&#xff0c;即正常退出System.exit(0);System.out.println("ok2");} ② arraycopy 复制数组元素 复制的数组元素个数必须<原数…...

【前端 02】新浪新闻项目-初步使用CSS来排版

在今天的博文中&#xff0c;我们将围绕“新浪新闻”项目&#xff0c;深入探讨HTML和CSS在网页制作中的基础应用。通过具体实例&#xff0c;我们将学习如何设置图片、标题、超链接以及文本排版&#xff0c;同时了解CSS的引入方式和选择器优先级&#xff0c;以及视频和音频标签的…...

HarmonyOS和OpenHarmony区别联系

前言 相信我们在刚开始接触鸿蒙开发的时候经常看到HarmonyOS和OpenHarmony频繁的出现在文章和文档之中&#xff0c;那么这两个名词分别是什么意思&#xff0c;他们之间又有什么联系呢&#xff1f;本文将通过现有的文章和网站内容并与Google的AOSP和Android做对比&#xff0c;带…...

llama模型,nano

目录 llama模型 Llama模型性能评测 nano模型是什么 Gemini Nano模型 参数量 MMLU、GPQA、HumanEval 1. MMLU(Massive Multi-task Language Understanding) 2. GPQA(Grade School Physics Question Answering) 3. HumanEval llama模型 Large Language Model AI Ll…...

ElasticSearch的应用场景和优势

ElasticSearch是一个开源的分布式搜索和分析引擎&#xff0c;它以其高性能、可扩展性和实时性在多个领域得到了广泛应用。以下是ElasticSearch的主要应用场景和优势&#xff1a; 应用场景 实时搜索&#xff1a; ElasticSearch以其快速、可扩展和实时的特性&#xff0c;成为实…...

git 、shell脚本

git 文件版本控制 安装git yum -y install git 创建仓库 将文件提交到暂存 git add . #将暂存区域的文件提交仓库 git commit -m "说明" #推送到远程仓库 git push #获取远程仓库的更新 git pull #克隆远程仓库 git clone #分支&#xff0c;提高代码的灵活性 #检查分…...

阿里云服务器 篇六:GitHub镜像网站

文章目录 系列文章搭建镜像网站的2种方式使用 Web 抓取工具 (Spider 技术)使用 Web 代理服务器使用 nginx 搭建GitHub镜像网站基础环境搭建添加对 github.com 的转发配置添加对 raw.githubusercontent.com 的转发配置配置更改注意事项(可选)缓存优化为新增设的二级域名配置DN…...

强化学习学习(三)收敛性证明与DDPG

文章目录 证明收敛&#xff1f; Deep RL with Q-FunctionsDouble Q-Learning理论上的解法实际上的解法 DDPG: Q-Learning with continuous actionsAdvanced tips for Q-Learning 证明收敛&#xff1f; 对于Value迭代&#xff1a;不动点证明的思路 首先定义一个算子 B : B V ma…...

培养前端工程化思维,不要让一行代码毁了整个程序

看《阿丽亚娜 5 号&#xff08;Ariane 5&#xff09;火箭爆炸》有感。 1、动手写项目之前&#xff0c;先进行全局性代码逻辑思考&#xff0c;将该做的事情&#xff0c;一些细节&#xff0c;统一建立标准&#xff0c;避免为以后埋雷。 2、避免使用不必要或无意义的代码、注释。…...

电子文件怎么盖章?

电子文件怎么盖章&#xff1f;电子文件盖章是数字化办公中常见的操作&#xff0c;包括盖电子公章和电子骑缝章。以下是针对这两种情况的详细步骤&#xff1a; 一、盖电子公章 方法一&#xff1a;使用专业软件 选择软件&#xff1a;选择一款专业的电子签名或PDF编辑软件&…...

IDEA在编译的时候报Error: java: 找不到符号符号: 变量 log lombok失效问题

错误描述 idea因为lombok的报错: java: You arent using a compiler supported by lombok, so lombok will not work and has been disabled.Your processor is: com.sun.proxy.$Proxy8Lombok supports: sun/apple javac 1.6, ECJ 原因&#xff1a;这是由于Lombok的版本过低的…...

【Python】如何修改元组的值?

一、题目 We have seen that lists are mutable (they can be changed), and tuples are immutable (they cannot be changed). Lets try to understand this with an example. You are given an immutable string, and you want to make chaneges to it. Example >>…...