39.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--调整发布脚本
这篇文章,我们要调整发布脚本。之所以要调整发布脚本,是因为现在我们的项目有三个环境:本地(Local)、开发(Development)、生产(Production)。
Tip:我们的项目虽然是实战项目,但是对于测试部分并不会增加测试环境(Test),这是因为微服务的测试实战内容很多,不是三四篇文章可以讲完了,并且我们的实战专栏核心是微服务应用的开发,所以我们不设置测试环境。
一、三个环境讲解
设置三个环境的目的,是为了让我们在不同的环境下,能够有不同的配置文件。比如说,我们在本地开发的时候,可能会使用本地的数据库,而在生产环境中,我们就需要使用生产环境的数据库。在这一小节,我们来讲解一下这三个环境的具体含义。
1.1 本地(Local)
本地环境是指我们在本地开发时使用的环境。在这个环境中,我们可以使用本地的数据库、缓存等资源。通常情况下,本地环境的配置文件会包含详细的调试信息,以便于我们在开发过程中进行调试,日志也会很详细。
在本地环境下,开发者可以自由地修改代码、重启服务、调试功能,而不会影响到其他开发者或线上用户。常见的做法是将数据库连接指向本地的数据库实例,缓存服务也可以部署在本地,甚至可以使用一些模拟服务来代替真实的第三方依赖。此外,本地环境通常会开启详细的日志记录和错误提示,方便定位和解决问题。
本地环境的安全性和性能要求相对较低,主要关注开发效率和调试便利性。因此,某些生产环境下的安全策略和性能优化措施,在本地环境中可以不启用。
1.2 开发(Development)
开发环境是指团队在协作开发和联调过程中使用的环境。在该环境下,项目会连接到专门的开发数据库和缓存服务等,这些资源通常与生产环境隔离,便于多人协作和问题排查。开发环境的配置文件一般保留必要的调试信息,但日志级别和详细程度会低于本地环境,以减少无关信息干扰。
在开发环境中,开发者可以进行前后端联调、多模块集成测试,以及服务端的自动化测试。该环境通常会尽量模拟生产环境的部署方式和依赖配置,以便提前发现集成和部署中的潜在问题。开发环境的数据库和服务通常为团队成员共享,便于协作开发,但访问权限会受到一定限制,仅限开发人员使用。
开发环境对服务器性能和安全性的要求适中,主要关注功能完整性和调试便利性。与本地环境相比,开发环境更接近实际生产环境,但仍保留一定的灵活性,支持开发和测试工作。
1.3 生产(Production)
生产环境是最终用户实际访问和使用的环境。在该环境下,项目会连接到正式的生产数据库、缓存等核心资源,这些资源经过严格的测试和验证,确保数据安全和服务稳定。生产环境的配置文件会关闭调试信息,优化日志级别,以提升系统性能并保障敏感信息安全。
在生产环境中,服务的高可用性、性能和安全性是首要目标。所有代码和配置的变更都必须经过完整的测试和审批流程,确保不会影响用户体验。日志记录通常仅保留必要的信息,避免泄露敏感数据,同时减少对系统性能的影响。
生产环境的访问权限严格受控,仅限授权人员操作。数据库和服务实例与其他环境完全隔离,确保数据的完整性和安全。任何变更操作通常会选择在业务低峰期进行,以最大程度降低对用户的影响。
Tip:在我们的孢子记账项目中,由于仅有一个台服务器,因此开发环境和生产环境是共用的。我们会在发布脚本中根据不同的环境来选择不同的配置文件。
二、调整发布脚本
在上一篇文章中,我们为每个微服务都创建Github Action工作流,但是这些工作流都是针对单一环境的。现在,我们要调整发布脚本,让它能够根据不同的环境来选择不同的配置文件。我们以用户配置服务(SP.ConfigService
)为例,来讲解如何调整发布脚本。
2.1 配置launchSettings.json
要配置本地环境,我们需要修改 launchSettings.json
文件。launchSettings.json
文件位于 ASP.NET Core 项目的 Properties
文件夹下,主要用于配置项目的启动和调试参数。它允许为不同的启动方式(如 IIS Express、本地运行、Docker 等)定义多个启动配置(profile),并在每个配置中设置环境变量(如 ASPNETCORE_ENVIRONMENT)、端口号、命令行参数以及是否自动打开浏览器等选项。通过合理配置 launchSettings.json
,可以方便地在本地开发环境下切换不同的运行模式,实现针对本地、开发或生产环境的调试和测试需求。Visual Studio 和 dotnet run
命令都会读取该文件,从而为开发者提供灵活的本地启动体验。
由于我们在开发功能时是在各自的本地电脑上开发的,因此我们需要将 ASPNETCORE_ENVIRONMENT
环境变量设置为 Local
。我们打开 SP.ConfigService
项目的 Properties/launchSettings.json
文件,找到 profiles
节点下的 SP.ConfigService
节点,然后将 ASPNETCORE_ENVIRONMENT
的值修改为 Local
,修改后的内容如下所示:
{"$schema": "http://json.schemastore.org/launchsettings.json","iisSettings": {"windowsAuthentication": false,"anonymousAuthentication": true,"iisExpress": {"applicationUrl": "http://localhost:45810","sslPort": 44303}},"profiles": {"http": {"commandName": "Project","dotnetRunMessages": true,"launchBrowser": true,"launchUrl": "swagger","applicationUrl": "http://localhost:5116","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Local"}},"https": {"commandName": "Project","dotnetRunMessages": true,"launchBrowser": true,"launchUrl": "swagger","applicationUrl": "https://localhost:7108;http://localhost:5116","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Local"}}}
}
在上面的配置中,我们将 ASPNETCORE_ENVIRONMENT
的值修改为 Local
,这样我们在本地运行项目时,就会使用 appsettings.Local.json
配置文件。
2.2 创建appsettings.Local.json
接下来,我们创建 appsettings.Local.json
文件,并添加本地环境的配置内容,配置如下:
{"nacos": {"ServerAddresses": [ "http://14.103.224.141:8848" ],"Namespace": "a8f01c53-b0b2-4046-b0f8-850e24738b23","ServiceName": "SPConfigService","GroupName": "DEFAULT_GROUP","ClusterName": "DEFAULT","Username": "SP_ADMIN","Password": "123*asdasd","Weight": 100,"ConfigUseRpc": true,"NamingUseRpc": true,"RegisterEnabled": true,"InstanceEnabled": true,"Ephemeral": true,"GrpcReconnectInterval": 5000,"ConnectionTimeOut": 10000,"Listeners": [{"Optional": false,"DataId":"SP.ConfigService","Group":"DEFAULT_GROUP"},{"Optional": false,"DataId":"Common","Group":"DEFAULT_GROUP"}]}
}
在这个配置文件中,我们配置了 Nacos 的相关信息,这些信息是我们在本地开发时使用的,其中Namespace
是我们在Nacos中创建的本地命名空间的ID。
Tip:同样,我们也可以为开发环境创建
appsettings.Development.json
文件,为生产环境创建appsettings.Production.json
文件,配置内容和上面的类似,只是Namespace
的值不同,分别对应我们在Nacos中创建的开发命名空间和生产命名空间的ID。
2.2 修改Dockerfile配置
接着我们需要修改 Dockerfile
文件,使其能够支持多环境部署。我们打开 SP.ConfigService
项目的 Dockerfile
文件,删除原有的环境变量设置命令 ENV ASPNETCORE_ENVIRONMENT=Production
,让环境变量的设置交由外部传递。这样做的好处是,ASPNETCORE_ENVIRONMENT
环境变量可以在容器启动时通过命令行参数或 CI/CD 发布脚本动态指定。例如,在使用 docker run
启动容器时,可以通过 -e
参数传递环境变量:
docker run -e ASPNETCORE_ENVIRONMENT=Development your-image-name
或者在 GitHub Actions、Jenkins 等自动化部署脚本中,根据不同的环境传递不同的环境变量值,实现灵活的多环境部署。最终,Dockerfile
文件无需硬编码环境变量,环境的切换完全交由外部控制,便于后续扩展和维护。
Tip:不建议为每个环境单独维护一份
Dockerfile
,这样会增加维护成本且容易出错。通过外部传递环境变量的方式,可以让同一个镜像适配不同的环境配置,既简化了镜像管理,也提升了部署的灵活性。
2.3 修改Github Action 工作流
最后,我们需要修改 SP.ConfigService
项目的 GitHub Action 工作流文件,使其能够根据不同的环境来选择不同的配置文件。我们打开 deploy-config-service.yml
文件,我们需要新增workflow_dispatch
和Set deployment environment
步骤,以及修改Deploy to Server
步骤的docker 运行命令。以下是修改后的内容:
name: Deploy Config Serviceon:push:branches: [ Microservices ]paths:- 'SP.ConfigService/**'workflow_dispatch:jobs:deploy:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v3- name: Set up Docker Buildxuses: docker/setup-buildx-action@v2- name: Login to Docker Hubuses: docker/login-action@v2with:username: ${{ secrets.DOCKER_USERNAME }}password: ${{ secrets.DOCKER_PASSWORD }}- name: Build and push Docker imageuses: docker/build-push-action@v4with:context: .file: ./SP.ConfigService/Dockerfilepush: truetags: ${{ secrets.DOCKER_USERNAME }}/sp-config-service:latest- name: Set deployment environmentrun: |if [ "${{ github.event_name }}" == "push" ]; thenecho "ENVIRONMENT=Development" >> $GITHUB_ENVelseecho "ENVIRONMENT=Production" >> $GITHUB_ENVfi- name: Deploy to Serveruses: appleboy/ssh-action@masterwith:host: ${{ secrets.SERVER_HOST }}username: ${{ secrets.SERVER_USERNAME }}key: ${{ secrets.SERVER_SSH_KEY }}script: |docker pull ${{ secrets.DOCKER_USERNAME }}/sp-config-service:latestdocker stop sp-config-service || truedocker rm sp-config-service || truedocker run -d --name sp-config-service -p 5101:80 -e ASPNETCORE_ENVIRONMENT=${{ env.ENVIRONMENT }} ${{ secrets.DOCKER_USERNAME }}/sp-config-service:latest
在上面的代码中,我们新增了 workflow_dispatch
事件,这样我们就可以手动触发工作流,并选择要部署的环境。同时,我们新增了 Set deployment environment
步骤,根据触发事件来设置环境变量 ENVIRONMENT
的值。最后,在 Deploy to Server
步骤中,我们将 ASPNETCORE_ENVIRONMENT
环境变量的值设置为 ${{ env.ENVIRONMENT }}
,这样就可以根据不同的环境来选择不同的配置文件。
三、总结
通过以上的调整,我们实现了在不同环境下使用不同的配置文件。现在,当我们在本地开发时,使用的是 appsettings.Local.json
配置文件;当我们在开发环境部署时,使用的是 appsettings.Development.json
配置文件;当我们在生产环境部署时,使用的是 appsettings.Production.json
配置文件。这样做的好处是,我们可以在不同的环境下使用不同的配置,避免了在同一个配置文件中混合不同环境的配置,从而减少了出错的可能性。