DevOps持续集成-Jenkins(4)

❤️作者简介:2022新星计划第三季云原生与云计算赛道Top5🏅、华为云享专家🏅、云原生领域潜力新星🏅

💛博客首页:C站个人主页🌞

💗作者目的:如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门,共同进步!

文章目录

    • DevOps
      • DevOps概述
      • Jenkins流水线任务入门⭐
        • Jenkins流水线任务的Hello World体验⭐
        • Jenkins流水线语法例子
        • Jenkins流水线语法生成器⭐
      • Jenkins实战4:构建pipeline(流水线)的Jenkins项目⭐
        • 项目架构图
        • Jenkins实战4的初步流水线模板(功能全部都未实现)⭐
        • Jenkinsfile配置⭐
          • 在项目中编写Jenkinsfile来维护pipeline模板(以后我们的pipeline语法都放在这个文件上)⭐
          • 在Jenkins中配置Jenkinsfile在gitlab上的地址⭐
          • 测试构建,看看Jenkinsfile是否能生效
        • 架构图第2步案例:将gitlab上面的项目代码拉取到Jenkins中⭐
        • 架构图第3步案例:利用Maven构建项目的jar包⭐
        • 架构图第4步案例:给Jenkins的pipeline任务配置SonarQube自动进行代码质量检测⭐
        • 架构图第5步案例:Jenkins制作自定义镜像并上传到Harbor⭐
        • 架构图第6-7步案例:通知目标服务器可以从Harbor上拉取镜像,并运行容器(注意:这里有个坑!)⭐
        • Jenkins流水线整合钉钉:在构建完成后通知信息(新增⭐)
          • 下载安装钉钉,并且注册账号(电脑版和手机版都行)⭐
          • 在Jenkins中下载钉钉插件(DingTalk 2.4.7版本)⭐
          • 在钉钉创建一个企业(不然无法申请项目群)⭐
          • 在钉钉创建一个新的项目群⭐
          • 在钉钉的项目群里创建一个机器人⭐
          • 在Jenkins中配置这个机器人⭐
          • Jenkinsfile配置钉钉⭐
        • 实战4的Jenkinsfile全部代码⭐

DevOps

DevOps概述

软件开发最初是由两个团队共同组成:(没有采用DevOps之前)

  • 开发团队:从头开始设计和整体系统的构建(编写代码)。需要系统不停的迭代更新。
  • 运维团队:将开发团队的代码进行测试通过后再部署上线。确保系统稳定运行。

没有采用DevOps的缺点:

  • 这看似两个目标不同的团队需要协同完成一个软件的开发。在开发团队指定好计划并完成编写代码后,需要把代码交给运维团队。运维团队向开发团队反馈需要修复的BUG以及一些需要返工的任务。这时开发团队需要经常等待运维团队的反馈。这无疑会延长整个软件开发的周期。

采用DevOps的优点?

  • DevOps的方式可以让公司能够更快地应对更新和市场发展变化,开发可以快速交付,部署也更加稳定。核心就在于简化Dev和Ops团队之间的流程,使整体软件开发过程更快速。说白了就是DevOps有利于快速完成项目,不会浪费时间)

整体的软件开发流程:

  • PLAN:开发团队根据客户的目标制定开发计划
  • CODE:根据PLAN开始编码过程,需要将不同版本的代码存储在一个库中。
  • BUILD:编码完成后,需要将代码构建并且运行。
  • TEST:成功构建项目后,需要测试代码是否存在BUG或错误。
  • DEPLOY:代码经过手动测试和自动化测试后,认定代码已经准备好部署并且交给运维团队。
  • OPERATE:运维团队将代码部署到生产环境中。
  • MONITOR:项目部署上线后,需要持续的监控产品。
  • INTEGRATE:然后将监控阶段收到的反馈发送回PLAN阶段,整体反复的流程就是DevOps的核心即持续集成、持续部署。

为了保证整体流程可以高效的完成,各个阶段都有比较常见的工具,如下图:

Jenkins流水线任务入门⭐

Jenkins流水线任务的Hello World体验⭐

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Jenkins流水线语法例子
// 所有脚本命令包含在pipeline{}中
pipeline {  // 指定任务在哪个Jenkins集群节点中执行(Jenkins是支持分布式)// 这里的agent any是指该任务可以在任何Jenkins集群节点上执行。agent any// 声明全局变量,格式为:key='value'environment{host = '192.168.184.80'}// 存放所有任务的合集stages {// 单个任务1stage('任务1') {// 实现任务的具体流程steps {echo '做任务1'}}// 单个任务2stage('任务2') {// 实现任务的具体流程steps {echo '做任务2'}}// 单个任务3stage('任务3') {// 实现任务的具体流程steps {echo '做任务3'}}}
}
Jenkins流水线语法生成器⭐

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

Jenkins实战4:构建pipeline(流水线)的Jenkins项目⭐

项目架构图

在这里插入图片描述

Jenkins实战4的初步流水线模板(功能全部都未实现)⭐
pipeline {agent any// 存放所有任务的集合stages {stage('拉取Git仓库代码') {steps {echo '拉取Git仓库代码 - SUCCESS'}}stage('通过maven构建项目') {steps {echo '通过maven构建项目 - SUCCESS'}}stage('通过SonarQube做代码质量检测') {steps {echo '通过SonarQube做代码质量检测 - SUCCESS'}}stage('通过Docker制作自定义镜像') {steps {echo '通过Docker制作自定义镜像 - SUCCESS'}}stage('将自定义镜像推送到Harbor仓库') {steps {echo '将自定义镜像推送到Harbor仓库 - SUCCESS'}}stage('通过Publish Over SSH通知目标服务器') {steps {echo '通过Publish Over SSH通知目标服务器 - SUCCESS'}}}
}
Jenkinsfile配置⭐
在项目中编写Jenkinsfile来维护pipeline模板(以后我们的pipeline语法都放在这个文件上)⭐
  • 注意:该文件名一定要为:Jenkinsfile
  • Jenkinsfile文件内容放在了上面,可以直接复制!

在这里插入图片描述

在Jenkins中配置Jenkinsfile在gitlab上的地址⭐

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试构建,看看Jenkinsfile是否能生效

在这里插入图片描述

架构图第2步案例:将gitlab上面的项目代码拉取到Jenkins中⭐
  • 1:配置git参数:(根据tag去拉取代码)
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 2:生成拉取git代码的流水线语法:

    • 生成的语法代码块如下:(注意:下面有个地方(branches的name从原来是/main被我改成了${tag},如果安装默认生成的话,则是拉取最新版本代码,我们这个意思就是安装tag去拉取对应代码)和系统生成的语法不一样!!)*
    checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.184.70:8929/root/mytest.git']]])
    

在这里插入图片描述在这里插入图片描述

  • 3:把生成的pipeline语法放到Jenkinsfile文件的指定位置:

在这里插入图片描述

  • 4:测试构建:

在这里插入图片描述

架构图第3步案例:利用Maven构建项目的jar包⭐
  • 1:生成流水线语法:(生成如下)
    • 注意:/var/jenkins_home/maven/bin/mvn要改成你的maven的mvn地址。
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'

在这里插入图片描述

  • 2:将上面生成的语法放到Jenkinsfile的对应位置上去,然后上传到gitlab即可。(省略!)
架构图第4步案例:给Jenkins的pipeline任务配置SonarQube自动进行代码质量检测⭐
  • 1:生成流水线语法:(生成如下)
    • 注意:下面的-Dsonar.login要用自己的SonarQube的token
    • 注意:/var/jenkins_home/sonar-scanner/bin/sonar-scanner要改成你的sonar-scanner地址
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7ad2200f7cca90c37a909fdba8db049ac700909f'

在这里插入图片描述

  • 2:将上面生成的语法放到Jenkinsfile的对应位置上去,然后上传到gitlab即可。(省略!)
架构图第5步案例:Jenkins制作自定义镜像并上传到Harbor⭐
  • 1:生成制作自定义镜像的流水线语法(生成如下):
sh '''mv ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/'''

在这里插入图片描述

  • 2:在Jenkinsfile文件定义全局变量environment:(记得要把下面的内容改成你自己的!)
    • harborAddress是harbor地址
    • harborRepo是harbor仓库名
    • harborUser是harbor账号
    • harborPasswd是Harbor密码
    environment{harborAddress = '192.168.184.80:80'harborRepo = 'repo'harborUser = 'admin'harborPasswd = 'Harbor12345'}
  • 3:生成将镜像上传到Harbor仓库的流水线语法(生成如下):
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''

在这里插入图片描述

  • 4:防止Jenkins内部不能使用Docker,所以重新设置一下权限:(有时候即使设置了权限也会自动变回来,导致pipeline报错)

    • 切换目录到/var/run/:
    [root@centos7-jenkins harbor]# cd /var/run/
    
    • 修改docker.sock文件的所属组:
    [root@centos7-jenkins run]# chown root:root docker.sock
    
    • 修改docker.sock文件的权限:
    [root@centos7-jenkins run]# chmod o+rw docker.sock
    
  • 5:将上面生成的语法放到Jenkinsfile的对应位置上去,然后上传到gitlab即可。

在这里插入图片描述在这里插入图片描述

  • 6:执行构建即可。
  • 7:进入Harbor可视化界面,查看pipeline镜像是否push成功:

在这里插入图片描述

架构图第6-7步案例:通知目标服务器可以从Harbor上拉取镜像,并运行容器(注意:这里有个坑!)⭐
  • 1:在所有目标服务器上都放一份shell脚本文件:(原理是:Jenkins通知目标服务器去执行shell脚本文件,从而让目标服务器在Harbor上面拉取指定镜像。)
    • 原来的架构图上是把Dockerfile传到目标服务器,让目标服务器通过docker build构建镜像(缺点是当目标服务器有多台,那每一台目标服务器都需要build构建一次,n台服务器就是n次,这样十分浪费服务器资源)。
    • 现在的架构图是把镜像在Jenkins容器内构建,然后把镜像push到Harbor上,Jenkins通知所有目标服务器(不管有多少台),然后目标服务器就会执行下面的shell脚本,会从Harbor拉取指定镜像,这样一来,不管有多少台目标服务器都只是build构建一次,节省了很多资源。
vi /root/deploy.sh

内容如下:

harbor_addr=$1
harbor_repo=$2
project=$3
version=$4
host_port=$5
container_port=$6imageName=$harbor_addr/$harbor_repo/$project:$versioncontainerId=`docker ps -a | grep ${project} | awk '{print $1}'`
if [ "$containerId" != "" ] ; thendocker stop $containerIddocker rm $containerId
fitag=`docker images | grep ${project} | awk '{print $2}'`if [[ "$tag" =~ "$version" ]] ; thendocker rmi -f $imageName
fidocker login -u admin -p Harbor12345 $harbor_addrdocker pull $imageNamedocker run -d -p $host_port:$container_port --name $project $imageNameecho "SUCCESS"
  • 2:给deploy.sh权限:
chmod a+x /root/deploy.sh
  • 3:把所有目标服务器的deploy.sh都放到/usr/bin下:
[root@centos7-jenkins ~]# mv /root/deploy.sh /usr/bin/
  • 4:配置Jenkins参数:

在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 5:生成流水线语法:

    • 提示Exec command:
    deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 6:将生成的语法放到Jenkinsfile的对应位置上去,然后上传到gitlab即可。(⭐注意这里有个坑!⭐)

    • 坑坑坑!!!:sshPublisher的execCommand要用双引号,默认是单引号。(一定要改成双引号,否则语法无法生效!⭐)

    ⭐下面的是修改之后的,并且是测试通过的流水线语法!!:

sshPublisher(publishers: [sshPublisherDesc(configName: 'mytest', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
  • 7:最后测试构建即可(省略!)
Jenkins流水线整合钉钉:在构建完成后通知信息(新增⭐)
下载安装钉钉,并且注册账号(电脑版和手机版都行)⭐

钉钉下载官网

在Jenkins中下载钉钉插件(DingTalk 2.4.7版本)⭐

在这里插入图片描述

在钉钉创建一个企业(不然无法申请项目群)⭐

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在钉钉创建一个新的项目群⭐

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在钉钉的项目群里创建一个机器人⭐

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

在Jenkins中配置这个机器人⭐

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Jenkinsfile配置钉钉⭐
  • 1:编写流水线语法:
    • 注意:robot的值就是我们在Jenkins的系统配置所设置的机器人id!!(一定要进行修改)
post {success {dingtalk (robot: 'Jenkins-dingding',type:'MARKDOWN',title: "success: ${JOB_NAME}",text: ["- 成功构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"])}failure {dingtalk (robot: 'Jenkins-dingding',type:'MARKDOWN',title: "fail: ${JOB_NAME}",text: ["- 失败构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"])}}
  • 2:将上面的语法放到Jenkinsfile的stages外面,并上传gitlab:

在这里插入图片描述

  • 3:点击构建Jenkins

在这里插入图片描述

  • 4:查看钉钉项目群:

在这里插入图片描述

实战4的Jenkinsfile全部代码⭐
pipeline {agent anyenvironment{harborAddress = '192.168.184.80:80'harborRepo = 'repo'harborUser = 'admin'harborPasswd = 'Harbor12345'}// 存放所有任务的集合stages {stage('拉取Git仓库代码') {steps {checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.184.70:8929/root/mytest.git']]])}}stage('通过maven构建项目') {steps {sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'}}stage('通过SonarQube做代码质量检测') {steps {sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7ad2200f7cca90c37a909fdba8db049ac700909f'}}stage('通过Docker制作自定义镜像') {steps {sh '''mv ./target/*.jar ./docker/docker build -t ${JOB_NAME}:${tag} ./docker/'''}}stage('将自定义镜像推送到Harbor仓库') {steps {sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''}}stage('通过Publish Over SSH通知目标服务器') {steps {sshPublisher(publishers: [sshPublisherDesc(configName: 'mytest', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}}}post {success {dingtalk (robot: 'Jenkins-dingding',type:'MARKDOWN',title: "success: ${JOB_NAME}",text: ["- 成功构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"])}failure {dingtalk (robot: 'Jenkins-dingding',type:'MARKDOWN',title: "fail: ${JOB_NAME}",text: ["- 失败构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"])}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/169787.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【刷题-PTA】堆栈模拟队列(代码+动态图解)

【刷题-PTA】堆栈模拟队列(代码动态图解) 文章目录 【刷题-PTA】堆栈模拟队列(代码动态图解)题目输入格式:输出格式:输入样例:输出样例: 分析题目区分两栈解题思路伪代码动图演示代码测试 题目 题目描述 : 设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。 …

css-渐变色矩形

效果图&#xff1a; 代码&#xff1a; html: <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content"initial-scale1.0, user-scalableno" /><title></title><link …

ES6初步了解生成器

生成器函数是ES6提供的一种异步编程解决方案&#xff0c;语法行为与传统函数完全不同 语法&#xff1a; function * fun(){ } function * gen(){console.log("hello generator");}let iterator gen()console.log(iterator)打印&#xff1a; 我们发现没有打印”hello…

Leetcode-Easy题解1-回文数字

目录 解法1解法2 解法1 自己的想法,直接转成字符串首尾俩下标同时遍历比较 class Solution {public boolean isPalindrome(int x) {if(x<0){return false;}String strString.valueOf(x);int i0;for (;i<str.length()>>1;i){if(str.charAt(i)!str.charAt(str.leng…

DAY33 1005. K次取反后最大化的数组和 + 134. 加油站 + 135. 分发糖果

1005. K次取反后最大化的数组和 题目要求&#xff1a;给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#xff1a;我们选择某个索引 i 并将 A[i] 替换为 -A[i]&#xff0c;然后总共重复这个过程 K 次。&#xff08;我们可以多次选择同一个索引 i。&#xff09; …

Godot 官方2D C#重构(3):TileMap使用

文章目录 前言Godot Tilemap使用Tilemap使用TileSet和TilemapTilemap 图片资源添加TileSet&#xff0c;开始切图导入图片切图 简单添加TileMap如何使用 Auto Tilemap使用Auto Tilemap 前言 Godot 官方 教程 Godot 2d 官方案例C#重构 专栏 Godot 2d 重构 github地址 Godot Tilem…

互联网Java工程师面试题·Spring篇·第三弹

目录 ​编辑 4、注解 4.1、什么是基于注解的容器配置 4.2、如何在 spring 中启动注解装配&#xff1f; 4.3、Component, Controller, Repository,Service 有何区别&#xff1f; 4.4、Required 注解有什么用&#xff1f; 4.5、Autowired 注解有什么用&#xff1f; 4.6、…

当前JavaEE初阶的阶段知识总结

当前JavaEE初阶的阶段知识总结 多线程 文件IO 文件系统操作 ~~ File类. 文件内容操作 ~~ 读文件,写文件. IO 流对象. 流(Stream),形象的比喻,读取文件,就像水流一样,读写文件的时候,和水流类似,读100字节,可以一次读1个字节,100次完成;也可以一次读10个字节,10次完成…… 在…

Pillow(PIL)库的主要方法介绍

Pillow&#xff08;Python Imaging Library&#xff09;是Python中一个强大的图像处理库&#xff0c;它允许你进行图像的创建、打开、编辑、保存和显示等操作。Pillow 是 PIL&#xff08;Python Imaging Library&#xff09;的分支&#xff0c;支持多种图像格式&#xff0c;并提…

LVS+keepalived高可用负载均衡集群

keepalived介绍 keepalived为LVS应运而生的高可用服务。LVS的调度器无法做高可用&#xff0c;于是keepalived这个软件。实现的是调度器的高可用。 但是keepalived不是专门为LVS集群服务的&#xff0c;也可以做其他代理服务器的高可用。 LVS高可用集群的组成 主调度器备调度器&…

Java IDEA controller导出CSV,excel

Java IDEA controller导出CSV&#xff0c;excel 导出excel/csv&#xff0c;亲测可共用一个方法&#xff0c;代码逻辑里判断设置不同的表头及contentType&#xff1b;导出excel导出csv 优化&#xff1a;有数据时才可以导出参考 导出excel/csv&#xff0c;亲测可共用一个方法&…

javaEE -6(10000详解文件操作)

一&#xff1a;认识文件 我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进行数据保存时&#xff0c;往往不是保存成一个整体&#xff0c;而是独立成一个个的单位进行保存&#xff0c;这个独立的单位就被抽象成文件的概念&#xff0c…

四个内存函数

文章目录 memcpy函数(拷贝)模拟实现memcpy函数memcpy的升级memmove 之前的拷贝或赋值等都是对字符串操作的&#xff0c;而对内存中其它数据如结构体&#xff0c;数组中的数据的拷贝&#xff0c;都是要用内存函数来完成的。 memcpy函数(拷贝) 第一个参数为目标地址&#xff0c;第…

DJYROS产品:基于DJYOS的国产自主割草机器人解决方案

基于都江堰泛计算操作系统的国产自主机器人操作系统即将发布…… 1、都江堰机器人操作系统命名&#xff1a;DJYROS 2、机器人算法&#xff1a;联合行业自主机器人厂家&#xff0c;构建机器人算法库。 3、机器人芯片&#xff1a;联合行业机器人AI芯片公司&#xff0c;构建专用…

《红蓝攻防对抗实战》八.利用OpenSSL对反弹shell流量进行加密

前文推荐&#xff1a; 《红蓝攻防对抗实战》一. 隧道穿透技术详解《红蓝攻防对抗实战》二.内网探测协议出网之TCP/UDP协议探测出网《红蓝攻防对抗实战》三.内网探测协议出网之HTTP/HTTPS协议探测出网《红蓝攻防对抗实战》四.内网探测协议出网之ICMP协议探测出网《红蓝攻防对抗…

华为ERP,包含哪些内容?技术的先进性体现在哪里?

华为作为全球领先的信息和通信技术&#xff08;ICT&#xff09;解决方案提供商&#xff0c;其企业资源规划&#xff08;ERP&#xff09;系统是一个高度复杂且集成的管理软件平台&#xff0c;用于优化公司内部的业务流程和资源分配。华为ERP系统包括一系列模块和功能&#xff0c…

PHP MySQL 交互 笔记/练习

PHP 与 MySQL 交互 交互函数 函数名作用mysqli_connect()与MySQL 数据库建立连接。mysqli_close()关闭与MYSQL 数据库建立的连接。mysqli_connect_errno()与MySQL 数据库建立连接时&#xff0c;发生错误时的错误编号。mysqli_connect_error()与MySQL 数据库建立连接时&#x…

软件测试进阶篇----自动化测试脚本开发

自动化测试脚本开发 一、自动化测试用例开发 1、用例设计需要注意的点 2、设计一条测试用例 二、脚本开发过程中的技术 1、线性脚本开发 2、模块化脚本开发&#xff08;封装线性代码到方法或者类中。在需要的地方进行调用&#xff09; 3、关键字驱动开发&#xff1a;selen…

Ubuntu - sudo apt update 报错源问题解决方案

sudo apt update 报错…lease’ does not have a Release file. 反正就是觉得是网络的问题 尝试添加国内清华源、阿里源 不行 尝试DNS 为8.8.8.8&#xff0c;114.114.114.114 还是不行 解决方案&#xff1a;设置里面让 Ubuntu 找到适合自己的源 1、Settings -> About…

webpack中常见的Loader解决了什么问题?

一、是什么 loader 用于对模块的"源代码"进行转换&#xff0c;在 import 或"加载"模块时预处理文件 webpack做的事情&#xff0c;仅仅是分析出各种模块的依赖关系&#xff0c;然后形成资源列表&#xff0c;最终打包生成到指定的文件中。如下图所示&#…