使用Jenkins实现Windows服务器下C#应用程序发布

news/2025/2/27 6:45:01

背景

在现代化的软件开发流程中,持续集成和持续部署(CI/CD)已经成为不可或缺的一部分。

Jenkins作为一款开源的自动化运维工具,能够帮助我们实现这一目标。

本文将详细介绍如何在Windows服务器下使用Jenkins来自动化发布C#应用程序。

下载与安装

访问官方网站 https://www.jenkins.io/zh/download/。

点击上图红框中的windows,则会下载windows安装包jenkins.msi,拷贝到服务器,双击进行安装。

安装环节会提示选择JDK,要求版本17或21,下载一个17版本的JDK,放到磁盘目录,填写对应路径即可。

初始化

使用谷歌浏览器,访问http://localhost:38080/,打开初始化界面,如下图:

按照提示找到管理员密码,填充后点击继续按钮,弹出如下界面:

因服务器无法访问公网,所以显示离线,点击跳过插件安装,进入创建管理员账号界面,如下图:

点击“保存并完成”按钮,弹出提示,如下图:

再点击“保存并完成”按钮,提示安装完成,Jenkins就绪,如下图:

此时已完成Jenkins的初始化工作,并创建了管理员账号。

登录

使用ip地址+默认的38080端口访问,进入登录页面,如下图所示:

使用初始化过程中创建的账号及密码,登录,进入系统首页。

插件安装

Jenkins采用了内核+插件的模式来保持系统功能的扩展性,大量功能是通过插件来完成的。

服务器如能直接访问公网环境,直接使用在线插件管理即可,可以方便地下载、安装、更新、卸载等操作。

如服务器无法直接访问公网,则插件需要采用离线安装的方式,以常用的使用SSH协议传输文件到远程服务器的插件Publish Over SSH为例,步骤如下:

  1. 访问插件地址:https://plugins.jenkins.io/publish-over-ssh/releases/

  1. 点击上图中的版本号,下载对应该版本的文件 publish-over-ssh.hpi。
  2. 通过如下菜单和功能,上传插件后安装。

点击Deploy按钮后,提示该插件安装成功,但是有报错,查看installed plugins,是因为该插件有其他四个依赖插件需要安装,如下图:

按同样方法安装上述依赖的插件,发现还有进一步的依赖,如下图:

继续上述过程,前后一共下载11个插件,且有2个插件需要版本升级,如下图:

将所有依赖的插件都安装后,重启jenkins,进入已安装插件列表,显示所有插件无报错,正常加载状态。

以上方式过于繁琐,安装1个插件耗时长,工作量大,推荐更简便的方式,在能连接公网的电脑上安装同版本的Jenkins,将所需插件都安装完成后,将C:\ProgramData\Jenkins.jenkins\plugins目录下的所有文件,拷贝到内网服务器对应目录下覆盖,然后重启Jenkins生效。

SSH安装

要实现远程文件拷贝,仅仅在Jenkins服务器上安装插件是不够的,还需要在程序运行的远程服务器上安装一个SSH服务端,这里推荐OpenSSH。

OpenSSH 是一款用于安全远程连接和计算机管理的工具套件,它通过加密技术来保障通信安全,其主要功能包括远程登录、命令执行、文件传输和端口转发等。

OpenSSH 包含客户端和服务器两部分,其中:

  • 客户端:用于连接远程服务器。
  • 服务器:在远程服务器上运行,接受客户端的连接请求。

OpenSSH 最初是为 Linux 系统开发的,现在也支持包括 Windows 和 macOS 在内的多种操作系统。

windows Server 2016需要单独下载OpenSSH-Win64-v9.8.1.0.msi并安装,windows Server2019及以上服务器直接通过添加服务器功能的方式来实现,参考地址:https://learn.microsoft.com/zh-cn/windows-server/administration/openssh/openssh_install_firstuse?utm_source=ld246.com&eqid=ccf6b3510033b2e9000000026577e875&tabs=gui&pivots=windows-server-2019https://github.com/PowerShell/Win32-OpenSSH/releases

远程服务器配置

我们的目的是通过Jenkins实现程序的发布,因此准备工作之一就是维护一下程序运行的远程服务器地址、身份认证等信息。

访问Manage Jenkins>System,拉到最下方的SSH Servers区域,如下图所示:

点击上图中的Add按钮,添加远程服务器信息,如下:

输入名称、ip地址、服务器操作系统用户名和密码,点击右下角的测试按钮,可验证连通性,最后点击保存按钮。

重复上面步骤,添加另一台服务器219。

实战案例——备份

程序发布具有一定风险性,发布过程中出错或者发布后验证环节发现问题,且短时间内无法解决时,需要回滚到先前版本,因此通常在发布之前需要进行备份。

传统手工操作模式是将程序目录拷贝到备份目录,我们使用Jenkins来实现一键备份功能。

任务配置

在Jenkins首页,点击左侧导航中的New Item菜单,如下图所示:

输入名称,创建一个自由风格的任务,如下:

进入配置页面,在构建步骤中选择**Send files or execute commands over SSH**,然后指定批处理脚本的位置,如下图所示:

最后点击保存按钮。

批处理脚本编制

在远程服务器219上,编制批处理脚本如下:

@echo off
:: 设置源文件夹和目标备份文件夹路径
set "sourceFolder=D:\LimsWebApi"
set "backupFolderBase=D:\dev\backup\LimsWebApi"

:: 获取当前日期和时间
for /f "tokens=2 delims==" %%a in ('wmic os get localdatetime /value') do set datetime=%%a
set "year=%datetime:~0,4%"
set "month=%datetime:~4,2%"
set "day=%datetime:~6,2%"
set "hour=%datetime:~8,2%"
set "minute=%datetime:~10,2%"
set "second=%datetime:~12,2%"

:: 创建目标备份文件夹名称
set "backupFolder=%backupFolderBase%\Backup_%year%%month%%day%_%hour%%minute%%second%"

:: 创建目标备份文件夹
if not exist "%backupFolder%" mkdir "%backupFolder%"

:: 复制文件到目标备份文件夹
xcopy "%sourceFolder%\*" "%backupFolder%" /E /I /Y

其主要逻辑是设置要备份的目录,然后根据脚本执行时间生成备份文件夹名称,放到预定义的位置,拷贝所有文件夹和文件。

任务执行

在任务详情页面,点击构建,如下图:

点击上图左下角的构建记录,通过Console Output可以看到执行过程及结果,如下图:

多台备份

上面过程展示了单台服务器应用程序的备份,可以在任务配置中设置多台备份,特别是在集群部署的应用场景下。

我们修改上面的任务配置,增加220服务器的备份,如下:

再次执行任务,控制台输出如下:

实战案例——发布

传统手工操作模式需要通过远程桌面登录到各台服务器,然后分别停止IIS,拷贝覆盖发布内容,启动IIS,我们使用Jenkins来实现一键发布功能。

任务配置

在Jenkins首页,点击左侧导航中的New Item菜单,创建一个自由风格的任务,Jenkins支持复制新增功能,我们可以拷贝上文中的备份任务,在其基础上修改,如下:

修改配置,程序发布涉及到了文件传输了,如下图所示:

这里有个默认设定,源文件路径位于C:\ProgramData\Jenkins.jenkins\workspace下。

我们先执行一次,让其自动生成任务项目文件夹。

然后source files的默认起始路径,实际是C:\ProgramData\Jenkins.jenkins\workspace\lims-webapi-publish-qas。

Remote dictionary,即拷贝到远程服务器的默认起始路径是C:\Users\administrator\

我们把需要发布的程序文件放到该目录下,在Source files中使用“**”通配符代表拷贝所有的文件,包括子文件夹和子文件,在Remote dictionary输入LimsWebApi,如下图:

我们新建一个文本文档测试,执行任务,发现已经成功实现了远程文件传输,如下图:

批处理脚本编制

在远程服务器219上,编制批处理脚本如下:

@echo off
C:\Windows\System32\inetsrv\appcmd.exe stop site "LimsWebApi"
xcopy "C:\Users\administrator\LimsWebApi\*" "D:\LimsWebApi\" /E /I /Y
C:\Windows\System32\inetsrv\appcmd.exe start site "LimsWebApi"

如果该服务器上只发布了一个web站点,则可以使用net stop iisadmin和net start iisadmin 进行停止和启动整个iis服务。

不过,当该服务器上基于IIS,创建了多个web站点时,为了避免影响其他站点,使用上述脚本来实现针对特定站点的启停服务。

任务执行

在任务详情页面,点击构建,使用Console Output可以看到执行过程及结果,如下图:

实战优化——通过视图功能分离测试与生产任务

虽然我们可以通过后缀名的方式,来区分测试还是生产,但是放在同一个列表中,容易误操作,如下图所示:

我们可以使用Jenkins自带的视图功能,将测试与生产环境分离,如下图:

创建测试视图QAS,如下图:

勾选需要放到该视图中的任务,如下图:

保存后,效果如下:

同理,我们创建一个生产视图PRD,将生产相关的两个任务放进去,如下图:

通过该方式,可以方便地分离测试与生产环境的任务,避免误操作。

实战优化——使用FTP解决文件传输问题

Jenkins放在远程服务器,发布程序的时候,读取的是该服务器上的文件,也就是还需要一个步骤,把要更新的文件,从开发电脑上拷贝到Jenkins服务器上,如果这一步采用远程桌面的方式,仍然有点繁琐。

一种解决思路是采用共享文件夹的模式,将Jenkins服务器的C:\ProgramData\Jenkins.jenkins\workspace目录设置为共享。

但是由于之前局域网共享会被病毒利用,域策略默认强行关闭了文件夹共享的445端口,该方式走不通。

另一种解决思路就是通过ftp协议了,直接用IIS配置一个ftp站点出来,指向上面的workspace地址,如下图所示:

然后在开发笔记本上,通过ftp协议,直接粘贴要更新的文件即可。

这样就省去了远程桌面到Jenkins服务器的麻烦,直接复制粘贴文件,然后浏览器访问Jenkins的界面,执行任务处理即可。

常见问题

403报错

进行保存操作时,报错如下:HTTP ERROR 403 No valid crumb was included in the request

这是因为安全设置问题,按照下图,进入安全设置,将默认未勾选的Enable proxy compatibility勾选上,然后点击保存按钮,如下图:

最后,还需要重新加载一下配置使其生效。


http://www.niftyadmin.cn/n/5869673.html

相关文章

minio多主机分布式部署

Minio多主机分布式 docker-compose 集群部署_minio docker-compose-CSDN博客

WebStorm 安装配置(详细教程)

文章目录 一、简介二、优势三、下载四、安装4.1 开始安装4.2 选择安装路径4.3 安装选项4.4 选择开始菜单文件夹4.5 安装完成 五、常用插件5.1 括号插件(Rainbow Brackets)5.2 翻译插件(Translation)5.3 代码缩略图(Cod…

仿12306购票系统(3)

前面完成了乘车人登录功能的实现,本篇主要是控制台方面的管理 对于整体的控制台的设计,为了能够快速的检验,不进行登录拦截,在控制台的这个模块的controller层增加admin,以及在登录界面的拦截器排除掉admin. 车站 即…

【机器学习】 [代码篇] 30. KNN - sklearn 以及 自定义KNN 的实现

KNN - sklearn 以及 自定义KNN 的实现 前言Github 链接使用SKlearn 库完成KNN的训练以及预测1. 导入需要的库2. 加载数据2.1. 输出数据信息 3. 分割训练集和测试集4. 可视化5. 创建模型并预测 2. 自定义KNN模型并预测 前言 前面写完了理论篇,接下来补充代码。 机器…

应对现代生活的健康养生指南

在科技飞速发展的现代社会,人们的生活方式发生了巨大改变,随之而来的是一系列健康问题。快节奏的生活、高强度的工作以及电子产品的过度使用,让我们的身体承受着前所未有的压力。因此,掌握正确的健康养生方法迫在眉睫。 针对久坐不…

PCL源码分析:曲面法向量采样

文章目录 一、简介二、源码分析三、实现效果参考资料一、简介 曲面法向量点云采样,整个过程如下所述: 1、空间划分:使用递归方法将点云划分为更小的区域, 每次划分选择一个维度(X、Y 或 Z),将点云分为两部分,直到划分区域内的点少于我们指定的数量,开始进行区域随机采…

传递指针给函数的用法

在 C 语言中,将指针传递给函数是一种常见且重要的编程技巧,它可以让函数直接操作调用者提供的内存区域,实现数据的修改、避免数据的复制开销等。下面为你提供几个不同场景下传递指针给函数的例子。 1. 修改调用者的变量值 通过传递变量的指针…

归纳总结一下Tensorflow、PaddlePaddle、Pytorch构建神经网络基本流程,以及使用NCNN推理的流程

使用Tensorflow构建神经网络,这里使用keras API,采用Sequential方式快速构建 import tensorflow as tf from tensorflow.keras.datasets import mnist from tensorflow.keras.utils import to_categorical# 加载数据集 (train_images, train_labels), (t…