项目上线部署 - 多环境

什么是多环境?

字面上理解,多即是很多,环境就是区分使用人的地方。

从需求开发到功能上线,需要经历过程序员、测试人员、产品经理验收、用户使用等,但是程序员开发完就直接将功能重新部署到用户使用的网页上吗?

需要考虑以下问题:

  • 如果程序员写bug了,是不是影响到用户体验。
  • 那你说,我写的代码没问题,那原型需求不清晰,导致功能不完善怎么办?
  • 项目要用到数据库吧,你测试用的数据库环境和用户用的是同一个吗,如果要修改数据库的东西,影响到线上的东西,怎么办?

很明显,这样是达咩的!
在这里插入图片描述

那么怎么解决呢?

既然我们开发、测试、验收、用户体验,都是不同的人群,那么我们根据不同的人群区分不同的使用环境不就一样,从而达到无感的效果,开发是一个环境,测试、验收、用户不需要知道,同理,用户不需要知道其他环境,只需要知道我现在用的东西是好的就可以了。

多环境分类

  • 本地环境:这是开发者自己的机器上运行的环境。在此环境中,开发者会对代码进行编写、修改和初步测试。确实,需要将数据库配置改为连接到本地数据库,以避免影响其他环境的数据。此外,本地环境还可能包括各种开发工具、模拟数据等,以便于开发工作。
  • 开发环境:这是一个共享的环境,通常比本地环境更接近实际部署环境。团队成员会将代码合并到这里进行更进一步的集成测试,确保新功能与现有系统兼容。数据库配置和其他设置应反映生产环境的特征,但数据可以是测试数据。
  • 测试环境:主要用于质量保证团队进行系统的全面测试,包括功能测试、性能测试、安全测试等。这个环境应该尽可能地模拟生产环境,包括使用真实的数据库配置(但数据仍为测试数据),以发现潜在问题。
  • 预发布环境:也称为UAT(用户验收测试)环境,它是生产环境的最终演练场。预发布环境在配置上与生产环境几乎完全相同,用于最终的测试验证、用户培训、演示或最后的审核确认,确保一切准备就绪再上线。这里的数据库和所有配置都应该是接近生产级别的,有时甚至会定期同步一部分真实生产数据来进行测试。
  • 生产环境:这是实际向用户提供服务的环境,要求高度稳定和安全。所有代码更改、配置调整在此环境上都非常谨慎,通常经过严格的审批流程。生产环境的数据库包含真实用户数据,任何错误都可能导致实际的业务影响。

总结来说,多环境的划分是为了在软件开发生命周期的不同阶段提供合适的条件,确保应用的稳定性和可靠性,同时便于开发、测试和运维工作的高效进行。

注意:
并非都有这些环境,只有大公司才有这么多环境,小公司一般只有开发环境、生产环境,最多加个本地环境,自己配置的,灵活度高。

在这里插入图片描述

如何实现多环境

思路

既然是多个环境,很明显就是通过某个东西去判断,从而项目选择哪个配置文件去启动。
那么什么东西?怎么判断?

说到判断,if -else if ?
在这里插入图片描述
哈哈,当然不是,但是思路是差不多的,一般都是通过抽象配置类配置文件化注入环境参数。

抽象配置类

将项目代码中需要根据环境的变化而更改的变量整理到一个或多个配置类中,集中管理。

举个例子,连接数据库时,我们需要数据库 IP、端口、配置等信息,代码如下:

// 数据库基本信息
DB db = new DB();
db.setIp("10.0.0.1");
db.setPort(3306);
// 数据库连接配置
DBConnection c = new DBConncetion();
c.setTimeout(1000);

我们可以将这些代码中写死的值全部替换成变量,将同类变量放到一个类中:

// 数据库配置类
class DBConfig {
  String ip = "10.0.0.1";
  int port = 3306;
  long timeout = 1000L;
}

然后从这个类中读取变量的值:

DB db = new DB();
DBConfig cf= new DBConfig() 
// 从类中获取
db.setIp(cf.getIp());
db.setPort(cf.getPort());
DBConnection c = new DBConncetion();
c.setTimeout(cf.getTimeout());

这样的好处是,如果代码中还有其他地方用到了这些变量,也都可以从同一个类去获取,而不是把 死值 重复写多次,难以维护。

配置文件化

我们可以用专门的配置文件来维护配置,从而让用户修改配置更方便,不用再去找代码、改代码。

常见的配置文件格式有 properties、yaml、yml、json 等,比如新建一个数据库配置文件 db.properties :

db.ip=10.0.0.1
db.port=3306
db.timeout=1000

接下来在初始化数据库时,就可以将配置文件中的值加载到上一步写好的配置类中,然后读取啦:

// 从文件读取配置的值
DBConfig cf = new DBConfig("db.properties");
db.setIp(cf.getIp());
db.setPort(cf.getPort());

其实只不过是把配置的值从代码中移到了文件中而已~

但这样一来,我们想加载哪个配置文件就能加载哪个!

比如要搞一套测试环境的配置,只需再新建一个 db-test.properties 文件(文件名中加个环境名称),就能在这个文件中编写独立的配置了,然后在代码中加载该文件即可:

new DBConfig("db-test.properties");

无论是前端还是后端,大部分的多环境实现都是这个原理 —— 搞多套配置,所以总能在项目中看到类似的配置文件:
在这里插入图片描述

注入环境参数

到目前为止,其实我们还是在代码中写了死值 ,来告诉程序应该加载哪个名称的配置文件。

比如在本地开发时,加载 db-dev.properties ,开发完成后、正式上线前,再改代码为加载 db-prod.properties。

但这样不仅麻烦,而且可能忘了修改,把开发环境的项目发布到了线上。

最理想的效果应该是:无论项目要切换到哪个环境,整个项目都完全不用修改。

因此,我们可以将 指定环境 这件事放到最后,在通过命令去打包或者启动项目时,将环境参数写进去。

举个例子,我们在启动 java 项目时,给 env 系统变量传递不同参数:

# 测试环境
java -jar -Denv=test dist.jar
# 生产环境
java -jar -Dend=prod dist.jar

示例:
Question:java启动项目的命令是怎么样的,java -jar xxxx,我要指定配置文件和堆栈大小?

Answer:

要在启动Java项目时指定配置文件和堆栈大小,可以使用以下命令格式:

java -Xms<初始堆大小> -Xmx<最大堆大小> -jar <jar文件路径> --spring.config.location=<配置文件路径>

这里有几个参数的解释:

  • -Xms:设置JVM初始堆内存大小。例如,-Xms256m 表示初始堆大小为256MB。
  • -Xmx:设置JVM最大堆内存大小。例如,-Xmx1024m 表示最大堆大小为1GB。
  • -jar:后面跟着你的Java应用程序的jar包路径。
  • --spring.config.location:如果你的项目使用Spring框架,并且想指定配置文件的位置,可以使用这个参数。将<配置文件路径>替换为实际的配置文件路径。注意,如果配置文件名是默认的(比如application.propertiesapplication.yml),并且放在Spring默认会查找的资源目录下,通常不需要这个参数。

举个例子,如果你的jar包名为myapp.jar,想把初始堆大小设为512MB,最大堆大小设为1GB,并且配置文件位于/path/to/config/application.properties,那么命令如下:

java -Xms512m -Xmx1024m -jar myapp.jar --spring.config.location=/path/to/config/application.properties

请根据实际情况调整堆大小值和配置文件路径。


Question:java -Xms512m -Xmx1024m -jar myapp.jar --server.port=8080 --server.profiles.active=prod,这个命令,里面的server是什么?为什么可以写成这样 --server.profiles.active=prod,配置文件的命名是application-prod.yaml,这是springboot约定的吗?

Answer:
在您的命令中,server 是 Spring Boot 应用程序中用于配置嵌入式web服务器(通常是Tomcat、Jetty或Undertow)的属性前缀。Spring Boot 使用一种称为“外部化配置”的机制,允许您通过多种方式(包括命令行参数、环境变量、配置文件等)来覆盖或添加应用的配置。

当您在命令行中使用 --server.port=8080 这样的参数时,您实际上是在设置嵌入式web服务器的端口号为8080。同样,--server.profiles.active=prod 是用来激活特定的配置profile(在这里是"prod",代表生产环境)。配置profile允许您根据不同环境(如开发、测试、生产)来分隔配置,而无需更改应用代码。

至于配置文件命名,确实是Spring Boot的一个约定。当您激活了某个profile(如prod),Spring Boot 会自动查找与该profile对应的配置文件。对于application-prod.yaml,这遵循了Spring Boot的配置文件命名约定,即application-{profile}.yamlapplication-{profile}.properties。当prod profile被激活时,Spring Boot会加载application-prod.yamlapplication-prod.properties中的配置,这些配置会覆盖或补充默认的application.yamlapplication.properties中的设置。

总结来说,命令中的 --server.profiles.active=prod 是用来激活生产环境配置的命令行方式,而application-prod.yaml是根据激活的profile自动加载的配置文件,这些都是Spring Boot框架为了简化配置管理和环境切换而设计的约定。


然后在程序中读取该参数,加载对应的配置即可:

// 读取 env 参数
String env = System.getProperty("env");
new DBConfig("db-" + env + ".properties");

同理,对于前端项目,可以在打包构建时传入环境变量,然后自己在代码中读取,或者交给 Webpack 之类的打包工具处理:

{  "scripts": {    "serve": "env=dev serve",    "build:test": "env=test build"    "build": "env=prod build"  } }

至此,就是项目上线部署 - 多环境的分享,这篇文章都是基于鱼皮的文章 + 自己的理解写的
原文章在此:鱼皮 - 多环境设计

感谢各位,若有不足,尽管提,小弟洗耳恭听。
在这里插入图片描述

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值