阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

基于Jenkins Pipeline的ASP.NET Core持续集成实践

505次阅读
没有评论

共计 11165 个字符,预计需要花费 28 分钟才能阅读完成。

最近在公司实践持续集成,使用到了 Jenkins 的 Pipeline 来提高团队基于 ASP.NET Core API 服务的集成与部署效率,因此这里总结一下。

一、关于持续集成与 Jenkins Pipeline

1.1 持续集成相关概念

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称 CI)。

持续集成指的是,频繁地 (一天多次) 将代码集成到主干

它的好处主要有两个:

(1)快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。

(2)防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。

持续集成的目的,就是 让产品可以快速迭代,同时还能保持高质量

Martin Fowler 说:“持续集成并不能消除 Bug,而是让它们非常容易发现和改正。”

与持续集成相关的,还有持续交付和持续部署。

持续交付指的是:频繁地将软件的新版本,交付给质量团队或者用户,以供评审 。如果评审通过,代码就进入生产阶段。它强调的是, 不管怎么更新,软件是随时随地可以交付的

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

持续部署是持续交付的下一步,指的是 代码通过评审以后,自动部署到生产环境 。它强调的是 代码在任何时刻都是可部署的,可以进入生产阶段

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

1.2 Jenkins Pipeline

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

Jenkins 是一款流行的开源持续集成(CI)与持续部署(CD)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。有关 Jenkins 的安装,可以参考我的这一篇文章进行安装 https://www.linuxidc.com/Linux/2019-09/160627.htm。

相信很多童鞋都已经在使用 Jenkins 或者计划使用 Jenkins 来代替传统的人工发布流程了,因此我们创建了很多自由风格(Free Style)的构建任务用于多个 Job,而我们经常会听到说流水线任务,那么流水线是什么呢?

流水线 Pipeline 是一套运行于 Jenkins 上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的 复杂流程编排与可视化。下图是一个 Jenkins Pipeline 的实例效果:

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

Pipeline:Build => Test => Deploy

这里涉及到 Pipeline 中的几个重要概念,需要了解一下:

  • Stage: 阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作。注意,Stage 是一个逻辑分组的概念,可以跨多个 Node。如上图所示,Build,Test 和 Deploy 就是 Stage,代表了三个不同的阶段:编译、测试和部署。
  • Node: 节点,一个 Node 就是一个 Jenkins 节点,或者是 Master,或者是 Slave,是执行 Step 的具体运行期环境。
  • Step: 步骤,Step 是最基本的操作单元,小到创建一个目录,大到构建一个 Docker 镜像,由各类 Jenkins Plugin 提供。

二、准备 ASP.NET Core Docker 环境

2.1 安装 Docker 环境

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

可以参考我的这一篇《.NET Core 微服务之 ASP.NET Core on Docker》来安装和配置 Docker 环境,建议在 Linux 环境下配置。

2.2 安装 SFTP 服务

在 Linux 下,SSH 服务默认会安装,而在 Windows Server 下,需要单独安装,可以借助 FreeSSHD 这个免费工具来实现。由于我的物理机都是 Windows Server,物理机上的 VM 是 Linux(Docker 运行环境),所以需要给物理机配置 FreeSSHD,用来实现从 CI 服务器发布 Release 到物理服务器中的 VM。

至于如何安装配置 FreeSSHD,可以参考这一篇《freeSSHD 在 windows 环境下搭建 SFTP 服务器》。

三、配置 Jenkins Pipeline 流水线任务

3.1 总体目标

(1)持续集成:实现编译 + 单元测试的自动运行

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

这里我要实现的目标是:当有人 push 代码到 git server 中(这里我使用的 git server 是 Gogs,需要给 Gogs 设置一个 Webhook,如下图所示,需要注意的是设置的密钥文本要和在 Pipeline 中填写的一致,否则 Jenkins 无法正确接收 Web 钩子),git server 会触发一个 webhook 发送一个 post 的请求给 CI server,CI server 会触发 Pipeline 任务的构建,一路 pull 代码 + 编译 + 单元测试。

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

(2)持续发布:实现编译 + 发布到具体的测试环境

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

由于在开发阶段,我不需要每次 Push 都进行发布,因此我这里设置的是手动在 Jenkins 中触发发布任务来实现自动化发布。

3.2 全局设置

首先,肯定是 Jenkins 的插件安装了。

(1)Generic WebHook Trigger => 触发 WebHook 必备

(2)Gogs Plugin => 因为我使用的 Git Server 是 Gogs 搭建的

(3)MSBuild Plugin => 进行 sln、csproj 项目文件的编译

(4)MSTest & xUnit => 进行基于 MSTest 或基于 xUnit 的单元测试

(5)Nuget Plugin => 拉取 Nuget 包必备

(6)Pipeline => 实现 Pipeline 任务必备,建议将 Pipeline 相关插件都安装上

(7)Powershell Plugin => 如果你的 CI 服务器是基于 Windows 的,那么安装一下 Powershell 插件来执行命令吧

(8)Publish Over SSH => 远程发布 Release 必备

(9)WallDisplay => 电视投屏构建任务列表必备

其次,为了提示邮件,也要 Email 插件(Email Extension)的支持,并进行以下配置:

(1)第一处:Jenkins Location

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

(2)第二处:Email 扩展插件全局变量设置

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

这里主要是需要设置 Subject 和 Content,就可以在各个 Pipeline 中使用了。因此,这里贴出我的 Default Content 内容:

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="UTF-8">  
<title>${ENV, var="JOB_NAME"}- 第 ${BUILD_NUMBER}次构建日志</title>  
</head>  
  
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"  
    offset="0">  
    <table width="95%" cellpadding="0" cellspacing="0"  style="font-size: 11pt; font-family: Microsoft YaHei, Tahoma, Arial, Helvetica">  
        <tr>  
            <td>各位同事,大家好,以下为 ${PROJECT_NAME} 构建任务信息</td>  
        </tr>  
        <tr>  
            <td><br />  
            <b style="font-weight:bold; color:#66cc00">构建信息</b>  
            <hr size="2" width="100%" align="center" /></td>  
        </tr>  
        <tr>  
            <td>  
                <ul>  
                    <li>任务名称:${PROJECT_NAME}</li>  
                    <li>构建编号:第 ${BUILD_NUMBER}次构建</li>  
                    <li>触发原因:${CAUSE}</li>  
                    <li>构建状态:<span style="font-weight:bold; color:#FF0000">${BUILD_STATUS}</span></li>  
                    <li>构建日志:<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>  
                    <li>构建  Url:<a href="${BUILD_URL}">${BUILD_URL}</a></li>  
                    <li>工作目录:<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>  
                    <li>项目  Url:<a href="${PROJECT_URL}">${PROJECT_URL}</a></li>  
                </ul>  
            </td>  
        </tr>  
    </table>  
</body>  
</html>

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

为了能够发给更多的人,建议勾选以上两个选项。

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

这里是 Email 通知必填的 SMTP 服务器配置。

最后,是 SSH 服务器的声明,指定可以进行 SSH 发布的服务器有哪些,IP 又是多少:

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

3.3 新增 Pipeline 脚本

(1)持续集成 Pipeline

首先,填写 Webhook 的密钥文本:

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

其次,Build Triggers 的时机选择“Build when a change is pushed to Gogs”,即有人 push 代码到仓库就触发。当然,这里需要提前在 Gogs 设置 Webhook。

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

其次,编写 Pipeline 脚本,各个 Stage 写清楚职责:

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

具体的 Pipeline 脚本在下边:

 

pipeline{
    agent any
    stages {stage('XDP Core Services Checkout') {
            steps{checkout([$class: 'GitSCM', branches: [[name: '*/dev-xds']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '35b9890b-2338-45e2-8a1a-78e9bbe1d3e2', url: 'http://192.168.18.150:3000/EDC.ITC.XDP.Core/EDC.XDP.Core.git']]])
             echo 'Core Services Checkout Done' 
            }
        }
        stage('XDP Core Services Build') {
            steps{bat  '''cd "D:\\Jenkins\\workspace\\XDS.Dev.CI.Pipeline\\src\\services\\EDC.XDP.Core\\"
              dotnet build EDC.XDP.Core-All.sln'''echo'Core Services Build Done' 
            }
        }
        stage('Core Delivery Service Unit Test') {
            steps{bat  '''cd "D:\\Jenkins\\workspace\\XDS.Dev.CI.Pipeline\\src\\services\\EDC.XDP.Core\\Services\\EDC.XDP.Core.Delivery.UnitTest"
                dotnet test -v n --no-build EDC.XDP.Core.Delivery.UnitTest.csproj'''echo'Core Delivery Service Unit Test Done'  
            }
        }
        stage('XDS Delivery Service Checkout') {
            steps{checkout([$class: 'GitSCM', branches: [[name: '*/dev-service']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '35b9890b-2338-45e2-8a1a-78e9bbe1d3e2', url: 'http://192.168.18.150:3000/EDC.ITC.XDP.XDS/EDC.XDP.XDS.git']]])
             echo 'Core Delivery Service Checkout Done' 
            }
        }
        stage('XDS Delivery Service Build') {
            steps{bat  '''cd "D:\\Jenkins\\workspace\\XDS.Dev.CI.Pipeline\\src\\services\\EDC.XDP.XDS"
               dotnet build EDC.XDP.XDS.sln'''echo'XDS Service Build Done' 
            }
        }
        stage('XDS Delivery Service Unit Test') {
            steps{bat  '''cd "D:\\Jenkins\\workspace\\XDS.Dev.CI.Pipeline\\src\\services\\EDC.XDP.XDS\\EDC.XDP.XDS.Delivery.UnitTest"
                dotnet test -v n --no-build EDC.XDP.XDS.Delivery.UnitTest.csproj'''echo'XDS Service Unit Test Done'  
            }
        } 
    }
    post{
        failure {
            emailext (subject: '${DEFAULT_SUBJECT}',
                body: '${DEFAULT_CONTENT}',
                to: "edisonchou@qq.com,xxxxx@qq.com")
        }
    }
}

(2)持续发布 Pipeline

持续发布 Pipeline 与持续集成 Pipeline 类似,只是在脚本处有所不同:

pipeline{
    agent any
    stages {stage('Core Delivery Service Checkout') {
            steps{checkout([$class: 'GitSCM', branches: [[name: '*/dev-xds']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '35b9890b-2338-45e2-8a1a-78e9bbe1d3e2', url: 'http://192.168.18.150:3000/EDC.ITC.XDP.Core/EDC.XDP.Core.git']]])
             echo 'Core Delivery Service Dev Branch Checkout Done' 
            }
        }
        stage('Core Delivery Service Build & Publish') {
            steps{bat  '''cd "D:\\Jenkins\\workspace\\XDS.API.Dev.CD.Pipeline\\src\\services\\EDC.XDP.Core"
               dotnet build EDC.XDP.Core-DataServices.sln
               dotnet publish "%WORKSPACE%\\src\\services\\EDC.XDP.Core\\Services\\EDC.XDP.Core.Delivery.API\\EDC.XDP.Core.Delivery.API.csproj" -o "%WORKSPACE%\\EDC.XDP.Core.Delivery.API/publish" --framework netcoreapp2.1
               '''echo'Core Delivery Service Build & Publish Done'
            }
        }
        stage('Core Delivery Service Deploy To 190 Server') {
            steps{sshPublisher(publishers: [sshPublisherDesc(configName: 'XDP-DEV-Server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:'''docker stop xdp_core_deliveryservice; docker rm xdp_core_deliveryservice; docker run --ulimit core=0 --restart=always -v /etc/localtime:/etc/localtime -d -e ASPNETCORE_ENVIRONMENT=dev --privileged=true --name=xdp_core_deliveryservice -p 8010:80 -v /XiLife/publish/EDC.XDP.Core.Delivery.API/:/app -w /app xdp_service_runtime:latest  dotnet EDC.XDP.Core.Delivery.API.dll''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator:'[,]+', remoteDirectory:'EDC.XDP.Core.Delivery.API/', remoteDirectorySDF: false, removePrefix:'EDC.XDP.Core.Delivery.API/publish/', sourceFiles:'EDC.XDP.Core.Delivery.API/publish/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            echo 'Delivery Service Deploy To 190 Done'    
            }
        }
        stage('Core Delivery Service Deploy To 175 Server') {
            steps{sshPublisher(publishers: [sshPublisherDesc(configName: 'XDP-DEV-MT-Server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:'''docker stop xdp_core_deliveryservice; docker rm xdp_core_deliveryservice; docker run --ulimit core=0 --restart=always -v /etc/localtime:/etc/localtime -d -e ASPNETCORE_ENVIRONMENT=devmt --privileged=true --name=xdp_core_deliveryservice -p 8010:80 -v /XiLife/publish/EDC.XDP.Core.Delivery.API/:/app -w /app xdp_service_runtime:latest  dotnet EDC.XDP.Core.Delivery.API.dll''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator:'[,]+', remoteDirectory:'EDC.XDP.Core.Delivery.API/', remoteDirectorySDF: false, removePrefix:'EDC.XDP.Core.Delivery.API/publish/', sourceFiles:'EDC.XDP.Core.Delivery.API/publish/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            echo 'Delivery Service Deploy To 175 Done'    
            }
        }
        stage('XDS Delivery Service Checkout') {
            steps{checkout([$class: 'GitSCM', branches: [[name: '*/dev-service']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '35b9890b-2338-45e2-8a1a-78e9bbe1d3e2', url: 'http://192.168.18.150:3000/EDC.ITC.XDP.XDS/EDC.XDP.XDS.git']]])
             echo 'XDS Delivery Service Checkout Done' 
            }
        }
        stage('XDS Delivery Service Build & Publish') {
            steps{bat  '''cd "D:\\Jenkins\\workspace\\XDS.API.Dev.CD.Pipeline\\src\\services\\EDC.XDP.XDS"
               dotnet build EDC.XDP.XDS.sln
               dotnet publish "%WORKSPACE%\\src\\services\\EDC.XDP.XDS\\EDC.XDP.XDS.Delivery.API\\EDC.XDP.XDS.Delivery.API.csproj" -o "%WORKSPACE%\\EDC.XDP.XDS.Delivery.API/publish" --framework netcoreapp2.1
               '''echo'XDS Delivery Service Build & Publish Done' 
            }
        }
        stage('XDS Delivery Service Deploy To 190 Server') {
            steps{sshPublisher(publishers: [sshPublisherDesc(configName: 'XDP-DEV-Server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:'''docker stop xdp_xds_delivery_service;docker rm xdp_xds_delivery_service; docker run --ulimit core=0 --restart=always -v /etc/localtime:/etc/localtime -d -e ASPNETCORE_ENVIRONMENT=dev --privileged=true --name=xdp_xds_delivery_service -p 9020:80 -v /XiLife/publish/EDC.XDP.XDS.Delivery.API/:/app -w /app xdp_service_runtime:latest  dotnet EDC.XDP.XDS.Delivery.API.dll''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator:'[,]+', remoteDirectory:'EDC.XDP.XDS.Delivery.API/', remoteDirectorySDF: false, removePrefix:'EDC.XDP.XDS.Delivery.API/publish/', sourceFiles:'EDC.XDP.XDS.Delivery.API/publish/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            echo 'XDS Delivery Service Deploy to 190 Done'    
            }
        }
        stage('XDS Delivery Service Deploy To 175 Server') {
            steps{sshPublisher(publishers: [sshPublisherDesc(configName: 'XDP-DEV-MT-Server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:'''docker stop xdp_xds_delivery_service;docker rm xdp_xds_delivery_service; docker run --ulimit core=0 --restart=always -v /etc/localtime:/etc/localtime -d -e ASPNETCORE_ENVIRONMENT=devmt --privileged=true --name=xdp_xds_delivery_service -p 9020:80 -v /XiLife/publish/EDC.XDP.XDS.Delivery.API/:/app -w /app xdp_service_runtime:latest  dotnet EDC.XDP.XDS.Delivery.API.dll''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator:'[,]+', remoteDirectory:'EDC.XDP.XDS.Delivery.API/', remoteDirectorySDF: false, removePrefix:'EDC.XDP.XDS.Delivery.API/publish/', sourceFiles:'EDC.XDP.XDS.Delivery.API/publish/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            echo 'XDS Delivery Service Deploy to 175 Done'    
            }
        }
    }
}

这里由于我的测试环境分为两个,一个是开发人员联调环境 190,另一个是集成测试环境 175,统一在一个 Pipeline 任务中进行发布。

对于 Master 分支,我们还可以将 Web 系统的发布也集成到同一个 Pipeline 任务中,实现一个一条龙的发布流水线任务,由于各个 Web 系统的实现技术不一样,这里就不再贴脚本了。

四、效果演示

(1)持续集成示例

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

(2)持续发布示例

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

(3)构建失败告警

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

(4)构建大屏显示

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

再来一张投屏到工作区域电视屏幕中的效果,大家抬头就可以看到构建结果,是绿了还是红了?当然,我们都喜欢“绿”的,呼呼。

基于 Jenkins Pipeline 的 ASP.NET Core 持续集成实践

五、小结

借助持续集成和持续发布,我们开发人员可以节省很多质量保证和发布部署的时间,从而减少很多因为人为 QA 和 Deploy 造成的失误影响,从另一个层面上,它也可以使我们避免 996(好吧,虽然关联有点牵强)。后续,我还会探索 K8S,到时候希望能够分享一个 ASP.NET Core on K8S 的系列文章,敬请期待。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计11165字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7989998
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-12:开源笔记的进化之路,效率玩家的新选择

星哥带你玩飞牛NAS-12:开源笔记的进化之路,效率玩家的新选择

星哥带你玩飞牛 NAS-12:开源笔记的进化之路,效率玩家的新选择 前言 如何高效管理知识与笔记,已经成为技术...
免费领取huggingface的2核16G云服务器,超简单教程

免费领取huggingface的2核16G云服务器,超简单教程

免费领取 huggingface 的 2 核 16G 云服务器,超简单教程 前言 HuggingFace.co...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
开发者福利:免费 .frii.site 子域名,一分钟申请即用

开发者福利:免费 .frii.site 子域名,一分钟申请即用

  开发者福利:免费 .frii.site 子域名,一分钟申请即用 前言 在学习 Web 开发、部署...
零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face 免费服务器 +Docker 快速部署 HertzBeat 监控平台 ...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...