.Net C# 解放自己从部署服务开始( 类似 jenkins,等发布工具)

主要面对的环境是测试环境,你需要把服务整到测试环境去,但是,测试环境,没有自动化这一套,但是,你又不得不去干这件事情,主要是 ,这件事情是重复的,可以被程序替代的。

我做出来的时候,跟网友讨论,他们说可以用jenkins来部署啊,githook啥的来部署啊,第一么,我对它们稍微熟悉,第二么,我想用c#实现的服务来搞,加深自己对自动化发布这件事情的深入。

好了。现在说下他们的架构吧。

【新版本 脑图】

 【老版本 脑图】

脑图也根据群友的沟通改了一版,大家可以说说哪种好,我可以尽量参考(简单化的框架设计的话)。

基本就是这个架构了

环境不用说,都是我们常见的一个环境。

架构么,

先从客户端开始讲:

客户端的职责就是按照我自己的一个配置情况,对其进行git 拉取代码,然后 VS生成代码,最后,发布到服务端

    /// <summary>
    /// 类型
    /// </summary>
    public enum ProjectType
    {
        /// <summary>
        /// dotNet
        /// </summary>
        DotNet
    }

这个下面是按照项目走的,这个就是dotnet项目。项目的类型已经固定。

 这个是具体的类型需要干的事情

 比如 dotnet 整个命令可能需要干这些事情.

为啥不直接用git pull呢,因为 git pull 是内部调用的其他的命令,导致 输出捕获不到。

不利于及时发现问题。

以下是具体任务的结构,ID 用来跟踪服务的处理情况,CMDName用于关联处理命令的具体前置任务,路径是用来作为工作目录过去执行命令的,服务信息是,如果这个服务需要启动,那么,可能有一个或者多个服务会被启动,那么它自己就会先关闭,然后,覆盖文件,然后,启动。

在覆盖文件的时候,有一条配置文件是不用覆盖甚至复制的。

最后,修改记录是否完成。用于客户端提示。

 用到的压缩工具是.net 自带的 zipfile

方法如下:

    public class ZipFileHelper
    {
        public static ZipFileHelper Instance = new ZipFileHelper();

        public CompressType CompressType { get { return CompressType.System; } }

        public bool CompressDirectory(string directoryName, string CompressFile, string password = "")
        {
            try
            {
                ZipFile.CreateFromDirectory(directoryName, CompressFile, CompressionLevel.Fastest, true);
                return true;
            }
            catch (Exception)
            {
            }
            return false;
        }

        public bool Decompression(string CompressFile, string targetAddress, string password = "")
        {
            try
            {
                ZipFile.ExtractToDirectory(CompressFile, targetAddress, true);
                return true;
            }
            catch (Exception)
            {
            }
            return false;
        }
    }

用来请求服务端的方法如下

            using (var client = new HttpClient())
            {
                HttpResponseMessage response = client.GetAsync(url).Result;
                if (response.IsSuccessStatusCode)
                {
                    var result = response.Content.ReadAsStringAsync().Result;
                    return !string.IsNullOrEmpty(result);
                }
            }
                using (var client = new HttpClient())
                {
                    client.Timeout = new TimeSpan(0, 10, 0);
                    var multipartFormDataContent = new MultipartFormDataContent()
                    {
                        {
                            new ByteArrayContent(File.ReadAllBytes(R7zPath)),    // 文件流
                            "files",                                             // 对应 服务器 WebAPI 的传入参数
                            Path.GetFileName(R7zPath)                            // 上传的文件名称
                        }
                    };
                    HttpResponseMessage response = client.PostAsync(url, multipartFormDataContent).Result;
                    if (response.IsSuccessStatusCode)
                    {
                        var result = response.Content.ReadAsStringAsync().Result;
                    }
                }

服务端的职责是:

收到客户端上传来的压缩文件,解压压缩文件,获取任务信息,根据任务来对内容进行,具体的操作。

接口大致的样子

        [HttpPost]
        public IActionResult Upload(List<IFormFile> files)
        {

        }
用 Process.GetProcessesByName(name) 来获取具体的进程,另外用 Process.MainModule.FileName 来判断是否与启动的exe地址一致。

另外一个重要的点是,在文件的保存上,IFormFile保存的时候,我这边经常会提示,被另外一个进程使用。

所以,我采用的方式是

                        //保存文件
                        var stream = formFile.OpenReadStream();
                        // 把 Stream 转换成 byte[] 
                        byte[] bytes = new byte[stream.Length];
                        stream.Read(bytes, 0, bytes.Length);
                        // 设置当前流的位置为流的开始 
                        stream.Seek(0, SeekOrigin.Begin);
                        // 把 byte[] 写入文件 
                        FileStream fs = new(RFilePath, FileMode.Create);
                        BinaryWriter bw = new(fs);
                        bw.Write(bytes);
                        bw.Close();
                        fs.Close();

核心代码已经全部晒出来了。做出来应该不是啥子问题呦!

最后看下效果

 

 最后,只花费了28秒,但是,然我手动操作,最少得 5-10分钟,才能操作一次,毕竟,打开远程服务器,拉代码,编译,复制项目到远程,开启和关闭相关服务,服务越多,越慢。眼花缭乱的。

 所以,这还是很客观的,现在业务部分一声吼,我只需要双击,就搞定了。

posted @ 2022-03-27 09:53  蓝创精英团队  阅读(4)  评论(0)    收藏  举报  来源