Jenkins+Docker+SpringCloud微服务持续集成项目优化和微服务集群

Jenkins+Docker+SpringCloud微服务持续集成项目优化和微服务集群

  • Jenkins+Docker+SpringCloud部署方案优化
    • Jenkins+Docker+SpringCloud集群部署流程说明
      • 修改所有微服务配置
    • 设计Jenkins集群项目的构建参数
    • 编写多选项遍历脚本
      • 多项目提交进行代码审查
      • 多个项目打包及构建上传镜像
      • 把Eureka注册中心集群部署到多台服务器
      • 配置远程部署服务器
        • 报错问题排查
    • Nginx+Zuul集群实现高可用网关

Jenkins+Docker+SpringCloud部署方案优化

基于 Jenkins+Docker+SpringCloud微服务持续集成 作优化

上面部署方案存在的问题:

  1. 一次只能选择一个微服务部署
  2. 只有一台生产者部署服务器
  3. 每个微服务只有一个实例,容错率低

Jenkins+Docker+SpringCloud集群部署流程说明

在这里插入图片描述
优化方案:

  1. 在一个Jenkins工程中可以选择多个微服务同时发布
  2. 在一个Jenkins工程中可以选择多台生产服务器同时部署
  3. 每个微服务都是以集群高可用形式部署

服务器列表

服务器名称IP地址安装软件硬件配置系统
代码托管服务器192.168.100.240Gitlab-12.9.92核4GCentOS Linux release 7.5.1804
持续集成服务器192.168.100.241Jenkins 2.401.2,JDK 11,JDK 1.8,Maven 3.8.8,Git 1.8.3.1,Docker 20.10.24-ce2核4GCentOS Linux release 7.5.1804
代码审查服务器192.168.100.242mysql 5.7.43,sonarqube 6.7.71核2GCentOS Linux release 7.5.1804
Harbor仓库服务器192.168.100.251Docker 20.10.24-ce,Harbor 1.9.21核2GCentOS Linux release 7.5.1804
生产部署服务器192.168.100.252Docker 20.10.24-ce1核2GCentOS Linux release 7.5.1804
生产部署服务器192.168.100.253Docker 20.10.24-ce1核2GCentOS Linux release 7.5.1804

修改所有微服务配置

eureka配置
在这里插入图片描述
让eureka集群实现一个互相注册的功能!

# 集群版
spring:application:name: EUREKA-HA---
server:port: 10086
spring:# 指定profile=eureka-server1profiles: eureka-server1
eureka:instance:# 指定当profile=eureka-server1时,主机名是eureka-server1hostname: 192.168.100.252client:service-url:# 将自己注册到eureka-server1、eureka-server2这个Eureka上面去defaultZone: http://192.168.100.252:10086/eureka,http://192.168.100.253:10086/eureka---
server:port: 10086
spring:profiles: eureka-server2
eureka:instance:hostname: 192.168.100.253client:service-url:defaultZone: http://192.168.100.252:10086/eureka,http://192.168.100.253:10086/eureka

在启动微服务的时候,加入参数:spring.profiles.active 来读取对应的配置

其他微服务配置

除了Eureka注册中心以外,其他微服务配置都需要加入所有Eureka服务

# Eureka配置
eureka:client:service-url:  defaultZone: http://192.168.100.252:10086/eureka,http://192.168.100.253:10086/eureka # Eureka访问地址instance:prefer-ip-address: true

tensquare_zuul配置
在这里插入图片描述tensquare_admin_service配置
在这里插入图片描述
tensquare_gathering配置
在这里插入图片描述
把代码提交到Gitlab中
在这里插入图片描述

设计Jenkins集群项目的构建参数

因为要进行多项选择,安装Extended Choice Parameter插件
在这里插入图片描述
创建流水线项目(集群版)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
添加参数化构建
选择字符串参数
在这里插入图片描述
在这里插入图片描述
添加多选项目参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用jdk1.8构建项目
在这里插入图片描述
在这里插入图片描述
点击构建查看效果
在这里插入图片描述

编写多选项遍历脚本

多项目提交进行代码审查

// 定义变量以及引用变量,这样维护性好一点
// 引用凭证ID最好使用双引号 ""// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.100.251:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭证ID
def harbor_auth = "5785fbf3-a0f0-4234-8961-c866ca1e7046"node {// 获取当前选择的项目名称 ,调用split方法 以逗号切割项目名称 返回的变量是一个数组def selectedProjectNames = "${project_name}".split(",")stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {//for(int i=0;i<selectedProjectNames.length;i++){// 遍历selectedProjectNames后取出每个元素里的内容,就是project_name 项目信息def projectInfo = selectedProjectNames[i];// 取出项目名字 , 以@符号切割 [0] 为第一个参数 tensquare_eurekadef currentProjectName = "${projectInfo}".split("@")[0]// 当前遍历的项目端口,取出项目端口def currentProjectPort = "${projectInfo}".split("@")[1]// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${currentProjectName}${scannerHome}/bin/sonar-scanner"""}}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程,上传镜像') {// 项目参数传入的project_name 修改为变量sh "mvn -f ${project_name} clean package dockerfile:build"// 定义镜像名称def imageName = "${project_name}:${tag}"// 对镜像打标签sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"// 把镜像推送到Harbor,项目为私有级别,登录时涉及一个问题,登录harbor需要输入账号和密码,Jenkinsfile需要配置项目目录下,会暴露给所有开发人员,为了安全使用凭证方式withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {// 登录到Harbor,引用如上定义的username和password,就是用户haibo的信息sh "docker login -u ${username} -p ${password} ${harbor_url}"// 镜像上传sh "docker push ${harbor_url}/${harbor_project}/${imageName}"sh "echo 镜像上传成功"}// 部署应用sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project $project_name $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}
}

尝试多选项目进行构建
在这里插入图片描述
控制台输出能够看到进行了两次代码审查,证明Jenkinsfile能够对项目进行遍历审查

但构建结果是失败的,在编译打包的时候无法进行遍历与project_name切割
在这里插入图片描述
在这里插入图片描述

多个项目打包及构建上传镜像

修改Jenkinsfile,注释掉远程发布,查看编译构建和打包效果

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.100.251:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭证ID
def harbor_auth = "5785fbf3-a0f0-4234-8961-c866ca1e7046"node {// 获取当前选择的项目名称 ,调用split方法 以逗号切割项目名称 返回的变量是一个数组def selectedProjectNames = "${project_name}".split(",")stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {//for(int i=0;i<selectedProjectNames.length;i++){// 遍历selectedProjectNames后取出每个元素里的内容,就是project_name 项目信息def projectInfo = selectedProjectNames[i];// 取出项目名字 , 以@符号切割 [0] 为第一个参数 tensquare_eurekadef currentProjectName = "${projectInfo}".split("@")[0]// 当前遍历的项目端口,取出项目端口def currentProjectPort = "${projectInfo}".split("@")[1]// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${currentProjectName}${scannerHome}/bin/sonar-scanner"""}}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程,上传镜像') {for(int i=0;i<selectedProjectNames.length;i++){// 遍历selectedProjectNames后取出每个元素里的内容,就是project_name 项目信息def projectInfo = selectedProjectNames[i];// 取出项目名字 , 以@符号切割 [0] 为第一个参数 tensquare_eurekadef currentProjectName = "${projectInfo}".split("@")[0]// 当前遍历的项目端口,取出项目端口def currentProjectPort = "${projectInfo}".split("@")[1]// 项目参数传入的project_name 修改为变量sh "mvn -f ${currentProjectName} clean package dockerfile:build"// 定义镜像名称def imageName = "${currentProjectName}:${tag}"// 对镜像打标签sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"// 把镜像推送到Harbor,项目为私有级别,登录时涉及一个问题,登录harbor需要输入账号和密码,Jenkinsfile需要配置项目目录下,会暴露给所有开发人员,为了安全使用凭证方式withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {// 登录到Harbor,引用如上定义的username和password,就是用户haibo的信息sh "docker login -u ${username} -p ${password} ${harbor_url}"// 镜像上传sh "docker push ${harbor_url}/${harbor_project}/${imageName}"sh "echo 镜像上传成功"}// 部署应用//sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project $project_name $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时可以发现两个服务都可以进行代码扫描以及进行构建打包和上传至镜像仓库!
在这里插入图片描述

把Eureka注册中心集群部署到多台服务器

配置第二台生产服务器 192.168.100.253

# 卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
# 删除docker的所有镜像和容器
rm -rf /var/lib/docker# 安装基本的依赖包
sudo yum install yum-utils device-mapper-persistent-data lvm2 -y# 设置镜像仓库 Docker yum源
sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 更新yum软件包索引
sudo yum makecache fast# 列出需要安装的版本列表
yum list docker-ce --showduplicates | sort -r# 安装docker-ce-20.10
yum install docker-ce-20.10.* docker-ce-cli-20.10.* containerd -y# 配置Docker镜像仓库加速以及配置Harbor镜像仓库信任
mkdir /etc/docker -p
cat > /etc/docker/daemon.json <<EOF
{"registry-mirrors": ["https://k68iw3ol.mirror.aliyuncs.com"],"insecure-registries": ["192.168.100.251:85"]
}
EOF# 开启内核转发,后续报错排查后回来整理的笔记,重要!!!
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1# 重装使配置生效
sysctl -p /etc/sysctl.confsystemctl daemon-reload && systemctl enable --now docker

配置远程部署服务器

Jenkins服务器拷贝公钥到远程生产服务器02

ssh-copy-id 192.168.100.253

系统配置->添加远程服务器
在这里插入图片描述
Publish over SSH–> 新增一台机器
在这里插入图片描述
项目配置添加参数

配置能够选择多个服务器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
返回项目构建查看效果
在这里插入图片描述
更改Jenkinsfile

添加遍历服务器启动容器配置

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.100.251:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭证ID
def harbor_auth = "5785fbf3-a0f0-4234-8961-c866ca1e7046"node {// 获取当前选择的项目名称,调用split方法切割逗号,意为切开项目名称def selectedProjectNames = "${project_name}".split(",")// 获取当前选择的服务器名称def selectedServers = "${publish_server}".split(",")stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 对项目遍历进行代码审查,定义变量i=0 遍历数组selectedProjectNames 数组长度为lengthfor(int i=0;i<selectedProjectNames.length;i++){// 取出每个元素里的内容 定义变量为projectInfo 就是项目信息,即包含项目名字也包含项目端口def projectInfo = selectedProjectNames[i];// 对 projectInfo 进行切割 引用projectInfo 变量,使用@符号切,当前遍历的项目名字 [0] 为获取的第一个元素 就是项目名字def currentProjectName = "${projectInfo}".split("@")[0]// 当前遍历的项目端口         [1] 就是获取的第二个元素def currentProjectPort = "${projectInfo}".split("@")[1]// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${currentProjectName}${scannerHome}/bin/sonar-scanner"""}}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程,上传镜像') {for(int i=0;i<selectedProjectNames.length;i++){// 取出每个元素里的内容 定义变量为projectInfo 就是项目信息,即包含项目名字也包含项目端口def projectInfo = selectedProjectNames[i];// 对 projectInfo 进行切割 引用projectInfo 变量,使用@符号切,当前遍历的项目名字 [0] 为获取的第一个元素 就是项目名字def currentProjectName = "${projectInfo}".split("@")[0]// 当前遍历的项目端口         [1] 就是获取的第二个元素def currentProjectPort = "${projectInfo}".split("@")[1]// 项目参数传入的project_name 修改为变量sh "mvn -f ${currentProjectName} clean package dockerfile:build"// 定义镜像名称def imageName = "${currentProjectName}:${tag}"// 对镜像打标签sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"// 把镜像推送到Harbor,项目为私有级别,登录时涉及一个问题,登录harbor需要输入账号和密码,Jenkinsfile需要配置项目目录下,会暴露给所有开发人员,为了安全使用凭证方式withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {// 登录到Harbor,引用如上定义的username和password,就是用户haibo的信息sh "docker login -u ${username} -p ${password} ${harbor_url}"// 镜像上传sh "docker push ${harbor_url}/${harbor_project}/${imageName}"sh "echo 镜像上传成功"}// 遍历所有的服务器,分别部署for(int j=0;j<selectedServers.length;j++){// 获取当前遍历的服务器名称def currentServerName = selectedServers[j]// 加上的参数格式:--spring.profiles.active=eureka-server1/eureka-server2def activeProfile = "--spring.profiles.active="// 根据不同的服务器名字来读取不同的eureka配置信息if(currentServerName=="master_server"){activeProfile = activeProfile+"eureka-server1"}else if (currentServerName=="slave_server"){activeProfile = activeProfile+"eureka-server2"}// 部署应用sshPublisher(publishers: [sshPublisherDesc(configName: "${currentServerName}", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deployCluster.sh $harbor_url $harbor_project $currentProjectName $tag $currentProjectPort $activeProfile", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}echo "${currentProjectName}完成编译,构建镜像"}}
}

更改服务器端部署脚本

deploy.sh的基础上再编写一个deployCluster.sh脚本

增加一个变量profile,用来存储新增的位置变量activeProfile,也是传参的$6

vim /opt/jenkins_shell/deployCluster.sh#!/bin/sh
# 接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5
Profile=$6imageName=$harbor_url/$harbor_project_name/$project_name:$tagecho "$imageName"# 查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag}  | awk '{print $1}'`if [ "$containerId" !=  "" ] ; then# 停掉容器docker stop $containerId# 删除容器docker rm $containerIdecho "成功删除容器"
fi# 查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name  | awk '{print $3}'`if [ "$imageId" !=  "" ] ; then# 删除镜像docker rmi -f $imageIdecho "成功删除镜像"
fi# 登录Harbor
docker login -u haibo -p LIUhaibo123 $harbor_url# 下载镜像
docker pull $imageName# 启动容器
docker run -di -p $port:$port $imageName $profileecho "容器启动成功"# 添加执行权限
chmod +x /opt/jenkins_shell/deployCluster.sh

尝试构建项目,部署eureka服务器至两台服务器上
在这里插入图片描述
在这里插入图片描述
eureka集群启动并且使用10086端口
在这里插入图片描述
部署剩下的微服务集群
在这里插入图片描述
在这里插入图片描述
四个微服务都部署完成后通过浏览器查看,并且所有微服务都已经成功注册到eureka服务器也已经形成集群形式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

报错问题排查

第一个报错:eureka服务器容器启动后端口为8080
在这里插入图片描述
容器启动后查看容器日志,发现eureka服务器监听端口为8080,心想我的配置文件设置为10086端口为什么启动后是监听8080端口?
重构Jenkinsfile文件的docker容器启动传参部分

        // 加上的参数格式:--spring.profiles.active=eureka-server1/eureka-server2def activeProfile = "--spring.profiles.active=" //添加等号 = // 根据不同的服务器名字来读取不同的eureka配置信息if(currentServerName=="master_server"){activeProfile = activeProfile+"eureka-server1"}else if (currentServerName=="slave_server"){activeProfile = activeProfile+"eureka-server2"}

于是手动启动容器传参后报错

docker run -di -p 10086:10086 2c37266049d5  --spring.profiles.activeeureka-server2
WARNING: IPv4 forwarding is disabled. Networking will not work.
# 警告:IPv4转发已禁用。网络将不起作用。

添加docker ipv4转发

vim /etc/sysctl.conf
net.ipv4.ip_forward = 1# 重装使配置生效
sysctl -p /etc/sysctl.conf# 重启docker
systemctl restart docker

启动后还是监听8080端口,尝试使用--spring.profiles.active=eureka-server2进行传参后启动成功

docker run -di -p 10086:10086 2c37266049d5  --spring.profiles.active=eureka-server2

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

第二个报错:【已解决】com.mysql.jdbc.exceptions.jdbc4.CommunicationsExcepti:Communications link failure ----mysql连接报错

Nginx+Zuul集群实现高可用网关

在这里插入图片描述
配置nginx

配置负载均衡池,里面地址就是zuul网关地址
proxy_pass 选择不同的zuulServer

# 位于pro02生产服务器进行配置
# 安装Nginx# 修改Nginx配置
vim /etc/nginx/nginx.conf
# http模块添加upstream zuulServer {server 192.168.100.252:10020 weight=1;server 192.168.100.253:10020 weight=1;}vim /etc/nginx/conf.d/default.conf
server {listen       85;server_name  localhost;#access_log  /var/log/nginx/host.access.log  main;root /usr/share/nginx/html;location / {#    root   /usr/share/nginx/html;#    index  index.html index.htm;# 指定服务器负载均衡服务器proxy_pass http://zuulServer/;}# 重启Nginx
systemctl restart nginx

修改前端代码对于Nginx的访问地址
在这里插入图片描述
更改完成后代码上传至Gitlab代码仓库
在这里插入图片描述
构建前端web项目流水线并访问

在这里插入图片描述
在这里插入图片描述
浏览器访问
在这里插入图片描述
在这里插入图片描述
同时也可以新增数据,前后端能互相调用组件工作,实验完成!
在这里插入图片描述

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

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

相关文章

数据库线程池可用线程分析

1.事情的起源 项目在跑的过程中&#xff0c;突然间报没有可用的连接数。这个时候&#xff0c;服务进程还在&#xff0c;但是只要涉及到数据库的操作都会报错。 2.排查的思路 事件发生后&#xff0c;我们重启服务&#xff0c;监控的Connections数是258个&#xff0c;某台机器…

Latex安装与环境配置(TeXlive、TeXstudio与VS code的安装)编译器+编辑器与学习应用

TeXlive 配置Tex排版系统需要安装编译器+编辑器。TeX 的源代码是后缀为 .tex 的纯文本文件。使用任意纯文本编辑器,都可以修改 .tex 文件:包括 Windows 自带的记事本程序,也包括专为 TeX 设计的编辑器(TeXworks, TeXmaker, TeXstudio, WinEdt 等),还包括一些通用的文本编…

行业追踪,2023-08-10

自动复盘 2023-08-10 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

【图像恢复】基于交替乘子方法(ADMM)图像恢复算法研究[固定点收敛和应用](Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

《Python入门到精通》函数详解

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 函数 1、函数的调用2、函数的参数2.1、变量的就近原则2.2、传递参数2.3、形参和实…

易服客工作室:7个优质WordPress LMS线上教育系统插件比较(优点和缺点)

您是否正在为您的 WordPress 网站寻找最好的 LMS 插件&#xff1f;在线学习管理系统 (LMS) 插件允许您使用 WordPress 创建和运行类似 Udemy 的在线课程。 一个完美的 WordPress LMS 插件包括管理在线课程内容、处理订阅、运行和评分测验、接受付款等功能。 在本文中&#xf…

yolov5代码解读之yolo.py【网络结构】

​这个文件阿对于做模型修改、模型创新有很好大好处。 首先加载一些python库和模块&#xff1a; 如果要执行这段代码&#xff0c;直接在终端输入python yolo.py. yolov5的模型定义和网络搭建都用到了model这个类(也就是以下图片展示的东西)&#xff1a;&#xff08;以前代码没…

【学习日记】【FreeRTOS】调度器函数实现详解

写在前面 本文主要是对于 FreeRTOS 中调度器函数实现的详细解释&#xff0c;代码大部分参考了野火 FreeRTOS 教程配套源码&#xff0c;作了一小部分修改。 一、MSP 和 PSP Cortex-M有两种栈空间&#xff0c;主堆栈和进程堆栈。 MSP 用于系统级别和中断处理的堆栈 MSP 用于保…

linux配置上网 linux adsl拨号上网设置

Linux里面配置ADSL上网是件很麻烦的事。但配置完成之后就能开机自动拨号上网&#xff0c;可谓十分的方便。支持的系统有Redhat,CentOS,SuSE,FreeBSD,Ubuntu等常见的Linux。 工具/原料 ADSL网络&#xff0c;电信&#xff0c;网通&#xff0c;移动等常见宽带。 Linux系统的安装光…

MinGW-W64 下载、安装与配置(支持最新版的GCC,目前 GCC 13.2.0)

文章目录 一、简介1. MinGW 和 MinGW-W64 区别和联系2. MSVCRT 和 UCRT 介绍 二、下载1. 从 sourceforge.net 下载2. 从 github 下载3. 从 镜像站点 下载4. 自己编译 三、安装与配置1. 在线安装2. 离线安装3. 环境配置 四、总结 一、简介 1. MinGW 和 MinGW-W64 区别和联系 M…

LinearAlgebraMIT_8_TheRankOfMatrix

这节课中主要讲解根据秩来判断方程组/矩阵的(solvability)解情况&#xff0c;即通过秩来判断(aumented matrix)增广矩阵的解。我们需要直接求解方程组的解就是求解矩阵的解。 x.1 判断(非齐次线性方程组)Axb是否有解 我们以下面这个方程组为例&#xff0c;它具有3个约束条件和…

《OWASP代码审计》学习——跨站脚本注入(XSS)

一、跨站脚本概述 1.什么是跨站脚本 跨站点脚本(XSS)是一种编码注入漏洞。它通常出现在 web 应用程序中。XSS 使攻击者能够向其他用户浏览的网页中注入恶意内容。XSS 允许攻击者绕过访问控制&#xff0c;它是 OWASP Top10 最常见的漏洞之一。XSS 是网络服务器上的第二大漏洞。…

Linux系统性能调优及调试课:Linux Kernel Printk

🚀返回专栏总目录 文章目录 0、printk 说明1、printk 日志等级设置2、屏蔽等级日志控制机制3、printk打印常用方式4、printk打印格式0、printk 说明 在开发Linux device Driver或者跟踪调试内核行为的时候经常要通过Log API来trace整个过程,Kernel API printk()是整个Kern…

Flume拦截器

实现 Interceptor接口 方法1 是初始化: 方法2和3重载 拦截: 方法3 是关闭: 但是flume是通过内部类创建对象的

餐饮管理系统ssm酒店饭店仓库进销存jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 餐饮管理系统ssm 系统有1权限&#xff1a;管理员 二…

Vue中使用qrcode说明

1.安装 npm i qrcode1.5.3 2.导入 import QRCode from qrcode 3.转换 说明&#xff1a;拿到服务器传来的字符串&#xff0c;转换成base64&#xff0c;然后通过img标签展示。 // 字符串转成二维码 let result await this.$API.reqPayInfo(this.orderId); 总结&#xff1a;

Java一般用于postgis空间数据库通用的增删查改sql命令

目录 1 增加 2 删除 3 查询 4 更新 "public"."JGSQGW_Geo"为某模式下得表 一般postgrel有这样的设计模式 1 增加 #前端绘制出的数据插入 INSERT INTO "public"."JGSQGW_Geo" ( "geom","gridone","gridon…

集合Collection-List-ArrayList学习

一、集合 集合是数据容器。相较于数组集合具有以下几个特点&#xff1a; 数组一旦创建&#xff0c;长度不可改变。集合的长度会自动扩容。集合具有很多数组没有的功能函数API数组元素的存储特点单一&#xff0c;不同的集合有不同的存储特点。 1. Collection顶层接口 Collect…

zustand:基于 Flux 模型实现的小型、快速和可扩展的状态管理

目录 ReactStep 1&#xff1a;安装Step 2&#xff1a;Store 初始化Step3&#xff1a;Store 绑定组件&#xff0c;就完成了!效果图 VueStep 1: 安装Step 2: Store 初始化Step 3: Store 绑定组件&#xff0c;就完成了!效果图 微前端为什么你需要 zustand-pub &#xff1f;安装ste…

Centos8上加速git clone

首先通过命令获取域名对应的IP地址 [rootggbond ~]# nslookup github.global.ssl.fastly.net [rootggbond ~]# nslookup github.com 之后如上获取到的IP地址 以IP-域名的格式加入到hosts文件中 [rootggbond ~]# vim /etc/hosts Centos8上更新DNS缓存 [rootggbond ~]# nscd -…