Docker构建go-web应用
https://www.liwenzhou.com/posts/Go/deploy-in-docker/#c-0-4-0
本文介绍了如何使用Docker以及Docker Compose部署我们的 Go Web 程序。
Docker部署示例
准备代码
这里我先用一段使用net/http库编写的简单代码为例讲解如何使用Docker进行部署,后面再讲解稍微复杂一点的项目部署案例。
package mainimport ("fmt""net/http"
)func main() {http.HandleFunc("/", hello)server := &http.Server{Addr: ":8888",}fmt.Println("server startup...")if err := server.ListenAndServe(); err != nil {fmt.Printf("server startup failed, err:%v\n", err)}
}func hello(w http.ResponseWriter, _ *http.Request) {w.Write([]byte("hello liwenzhou.com!"))
}
上面的代码通过8888端口对外提供服务,返回一个字符串响应:hello liwenzhou.com!
创建Docker镜像
镜像(image)包含运行应用程序所需的所有东西——代码或二进制文件、运行时、依赖项以及所需的任何其他文件系统对象。
或者简单地说,镜像(image)是定义应用程序及其运行所需的一切。
编写Dockerfile
要创建Docker镜像(image)必须在配置文件中指定步骤。这个文件默认我们通常称之为Dockerfile。(虽然这个文件名可以随意命名它,但最好还是使用默认的Dockerfile。)
现在我们开始编写Dockerfile,具体内容如下:
注意:某些步骤不是唯一的,可以根据自己的需要修改诸如文件路径、最终可执行文件的名称等
FROM golang:alpine# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64# 移动到工作目录(镜像中):/build
WORKDIR /build# 将代码复制到容器中(当前目录是/build)
COPY . .# 将我们的代码编译成二进制可执行文件app
RUN go build -o app .# 移动到用于存放生成的二进制文件的 /dist 目录
WORKDIR /dist# 将二进制文件从 /build 目录复制到这里
RUN cp /build/app .# 声明服务端口
EXPOSE 8888# 启动容器时运行的命令
CMD ["/dist/app"]
Dockerfile解析
From
我们正在使用基础镜像golang:alpine来创建我们的镜像。这和我们要创建的镜像一样是一个我们能够访问的存储在Docker仓库的基础镜像。这个镜像运行的是alpine Linux发行版,该发行版的大小很小并且内置了Go,非常适合我们的用例。有大量公开可用的Docker镜像,请查看https://hub.docker.com/_/golang
Env
用来设置我们编译阶段需要用的环境变量。
WORKDIR,COPY,RUN
这几个命令做的事都写在注释里了,很好理解。
EXPORT,CMD
最后,我们声明服务端口,因为我们的应用程序监听的是这个端口并通过这个端口对外提供服务。并且我们还定义了在我们运行镜像的时候默认执行的命令CMD [“/dist/app”]。
构建镜像
在项目目录下,执行下面的命令创建镜像,并指定镜像名称为goweb_app:
docker build . -t goweb_app
等待构建过程结束,输出如下提示:
...
Successfully built 90d9283286b7
Successfully tagged goweb_app:latest
现在我们已经准备好了镜像,但是目前它什么也没做。我们接下来要做的是运行我们的镜像,以便它能够处理我们的请求。运行中的镜像称为容器。
执行下面的命令来运行镜像:
docker run -p 8888:8888 goweb_app
标志位-p用来定义端口绑定。由于容器中的应用程序在端口8888上运行,我们将其绑定到主机端口也是8888。如果要绑定到另一个端口,则可以使用-p $HOST_PORT:8888
。例如-p 5000:8888。
现在就可以测试下我们的web程序是否工作正常,打开浏览器输入http://127.0.0.1:8888
就能看到我们事先定义的响应内容如下:
hello liwenzhou.com!
分阶段构建示例
我们的Go程序编译之后会得到一个可执行的二进制文件,其实在最终的镜像中是不需要go编译器的,也就是说我们只需要一个运行最终二进制文件的容器即可。
Docker的最佳实践之一是通过仅保留二进制文件来减小镜像大小,为此,我们将使用一种称为多阶段构建的技术,这意味着我们将通过多个步骤构建镜像。
FROM golang:alpine AS builder# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64# 移动到工作目录:/build
WORKDIR /build# 将代码复制到容器中
COPY . .# 将我们的代码编译成二进制可执行文件 app
RUN go build -o app .###################
# 接下来创建一个小镜像
###################
FROM scratch# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/app /# 需要运行的命令
ENTRYPOINT ["/app"]
使用这种技术,我们剥离了使用golang:alpine作为编译镜像来编译得到二进制可执行文件的过程,并基于scratch生成一个简单的、非常小的新镜像。我们将二进制文件从命名为builder的第一个镜像中复制到新创建的scratch镜像中。有关scratch镜像的更多信息,请查看https://hub.docker.com/_/scratch
附带其他文件的部署示例
这里以我之前《Go Web视频教程》中的小清单项目为例,项目的Github仓库地址为:https://github.com/Q1mi/bubble。
如果项目中带有静态文件或配置文件,需要将其拷贝到最终的镜像文件中。
我们的bubble项目用到了静态文件和配置文件,具体目录结构如下:
bubble
├── README.md
├── bubble
├── conf
│ └── config.ini
├── controller
│ └── controller.go
├── dao
│ └── mysql.go
├── example.png
├── go.mod
├── go.sum
├── main.go
├── models
│ └── todo.go
├── routers
│ └── routers.go
├── setting
│ └── setting.go
├── static
│ ├── css
│ │ ├── app.8eeeaf31.css
│ │ └── chunk-vendors.57db8905.css
│ ├── fonts
│ │ ├── element-icons.535877f5.woff
│ │ └── element-icons.732389de.ttf
│ └── js
│ ├── app.007f9690.js
│ └── chunk-vendors.ddcb6f91.js
└── templates├── favicon.ico└── index.html
我们需要将templates、static、conf三个文件夹中的内容拷贝到最终的镜像文件中。更新后的Dockerfile如下
FROM golang:alpine AS builder# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64# 移动到工作目录:/build
WORKDIR /build# 将代码复制到容器中
COPY . .# 下载依赖信息
RUN go mod download# 将我们的代码编译成二进制可执行文件 bubble
RUN go build -o bubble .###################
# 接下来创建一个小镜像
###################
FROM scratch# 从builder镜像中把静态文件拷贝到当前目录
COPY ./templates /templates
COPY ./static /static# 从builder镜像中把配置文件拷贝到当前目录
COPY ./conf /conf# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/bubble /# 需要运行的命令
ENTRYPOINT ["/bubble", "conf/config.ini"]
简单来说就是多了几步COPY的步骤,大家看一下Dockerfile中的注释即可。
Tips: 这里把COPY静态文件的步骤放在上层,把COPY二进制可执行文件放在下层,争取多使用缓存。
Docker 提供了一种机制来缓存镜像层以加快构建速度,这就是所谓的层缓存。Dockerfile 中的每个指令都会创建一个新的镜像层,如果在后续构建中这一层的内容没有发生变化,Docker 会重用之前构建的层,而不是从头开始构建。
为了使层可以被重用,你需要确保这一层中的文件内容不会改变。以下是一些在 Dockerfile 中使用缓存的最佳实践:
将频繁变化的文件放在不同的目录中,或者在不同的复制指令中。
将不变的依赖放在一起,并且尽可能地保持 Dockerfile 的顺序。
使用 .dockerignore 文件来排除不需要的文件。
使用标签指定版本,如 RUN apt-get update && apt-get install -y package=1.2.3。
不要在构建过程中进行全局更新,比如 RUN apt-get update。
关联其他容器
又因为我们的项目中使用了MySQL,我们可以选择使用如下命令启动一个MySQL容器,它的别名为mysql8019;root用户的密码为root1234;挂载容器中的/var/lib/mysql到本地的/Users/q1mi/docker/mysql目录;内部服务端口为3306,映射到外部的13306端口。
docker run --name mysql8019 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -v /Users/q1mi/docker/mysql:/var/lib/mysql -d mysql:8.0.19
这里需要修改一下我们程序中配置的MySQL的host地址为容器别名,使它们在内部通过别名(此处为mysql8019)联通。
[mysql]
user = root
password = root1234
host = mysql8019
port = 3306
db = bubble
修改后记得重新构建bubble_app镜像:
docker build . -t bubble_app
我们这里运行bubble_app容器的时候需要使用–link的方式与上面的mysql8019容器关联起来,具体命令如下:
docker run --link=mysql8019:mysql8019 -p 8888:8888 bubble_app
Docker Compose模式
除了像上面一样使用–link的方式来关联两个容器之外,我们还可以使用Docker Compose来定义和运行多个容器。
Compose是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,你可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
使用Compose基本上是一个三步过程:
- 使用Dockerfile定义你的应用环境以便可以在任何地方复制。
- 定义组成应用程序的服务,docker-compose.yml 以便它们可以在隔离的环境中一起运行。
- 执行 docker-compose up命令来启动并运行整个应用程序。
我们的项目需要两个容器分别运行mysql和bubble_app,我们编写的docker-compose.yml文件内容如下:
# yaml 配置
version: "3.7"
services:mysql8019:image: "mysql:8.0.19"ports:- "33061:3306"command: "--default-authentication-plugin=mysql_native_password --init-file /data/application/init.sql"environment:MYSQL_ROOT_PASSWORD: "root1234"MYSQL_DATABASE: "bubble"MYSQL_PASSWORD: "root1234"volumes:- ./init.sql:/data/application/init.sqlbubble_app:build: .command: sh -c "./wait-for.sh mysql8019:3306 -- ./bubble ./conf/config.ini"depends_on:- mysql8019ports:- "8888:8888"
这个 Compose 文件定义了两个服务:bubble_app 和 mysql8019。其中:
bubble_app
使用当前目录下的Dockerfile文件构建镜像,并通过depends_on指定依赖mysql8019服务,声明服务端口8888并绑定对外8888端口。
mysql8019
mysql8019 服务使用 Docker Hub 的公共 mysql:8.0.19 镜像,内部端口3306,外部端口33061。
注意:
这里有一个问题需要注意,我们的bubble_app容器需要等待mysql8019容器正常启动之后再尝试启动,因为我们的web程序在启动的时候会初始化MySQL连接。这里共有两个地方要更改,第一个就是我们Dockerfile中要把最后一句注释掉:
# Dockerfile
...
# 需要运行的命令(注释掉这一句,因为需要等MySQL启动之后再启动我们的Web程序)
# ENTRYPOINT ["/bubble", "conf/config.ini"]
第二个地方是在bubble_app下面添加如下命令,使用提前编写的wait-for.sh脚本检测mysql8019:3306正常后再执行后续启动Web应用程序的命令:
command: sh -c "./wait-for.sh mysql8019:3306 -- ./bubble ./conf/config.ini"
当然,因为我们现在要在bubble_app镜像中执行sh命令,所以不能在使用scratch镜像
构建了,这里改为使用debian:stretch-slim,同时还要安装wait-for.sh脚本用到的netcat,最后不要忘了把wait-for.sh脚本文件COPY到最终的镜像中,并赋予可执行权限哦。更新后的Dockerfile内容如下:
FROM golang:alpine AS builder# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64# 移动到工作目录:/build
WORKDIR /build# 将代码复制到容器中
COPY . .# 下载依赖信息
RUN go mod download# 将我们的代码编译成二进制可执行文件 bubble
RUN go build -o bubble .###################
# 接下来创建一个小镜像
###################
FROM debian:stretch-slim# 从builder镜像中把脚本拷贝到当前目录
COPY ./wait-for.sh /# 从builder镜像中把静态文件拷贝到当前目录
COPY ./templates /templates
COPY ./static /static# 从builder镜像中把配置文件拷贝到当前目录
COPY ./conf /conf# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/bubble /RUN set -eux; \apt-get update; \apt-get install -y \--no-install-recommends \netcat; \chmod 755 wait-for.sh# 需要运行的命令
# ENTRYPOINT ["/bubble", "conf/config.ini"]
所有的条件都准备就绪后,就可以执行下面的命令跑起来了:
docker-compose up
完整版代码示例,请查看我的github仓库:https://github.com/Q1mi/deploy_bubble_using_docker
网络
连接外部服务
以mysql为例,mysql可能在我们的内网服务器上
也可能单独起一个mysql容器
面对第一种情况,因为 Docker 默认会将容器连接到宿主机的 Docker0 网桥上,容器和宿主机是可以直接通信的,所以直接连就行了
面对第二种情况,单独起的mysql容器和我们的项目容器是可以互相连接的
但是我们不知道对方的ip地址
使用一般不会使用默认网络的
而是使用自建网络,创建容器的时候指定容器的ip地址
创建网络
docker network create --subnet=10.1.0.0/24 my-network
创建容器用自建网络
这里我用之前的centos容器测试
docker run -itd --name c2 --ip 10.1.0.2 --network my-network fengfengzhidao/centos7-ssh:v1
docker run -itd --name c3 --ip 10.1.0.3 --network my-network fengfengzhidao/centos7-ssh:v1
然后再把这个知识和上面的项目部署结合起来,什么问题都可以搞定
相关文章:
Docker构建go-web应用
https://www.liwenzhou.com/posts/Go/deploy-in-docker/#c-0-4-0 本文介绍了如何使用Docker以及Docker Compose部署我们的 Go Web 程序。 Docker部署示例 准备代码 这里我先用一段使用net/http库编写的简单代码为例讲解如何使用Docker进行部署,后面再讲解稍微复杂…...
人工智能100问☞第4问:人工智能与机器学习、深度学习的区别?
目录 一、通俗解释 二、专业解析 三、权威参考 人工智能(AI)是目标:让机器具备智能(如建造一辆车);机器学习(ML)是引擎:提供动力方法(如燃油发动机);深度学习(DL)是涡轮增压:提升引擎性能(如处理复杂路况)。三者协同驱动技术发展,如同车辆需要…...
电子电器架构 --- 智能座舱的定义
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...
JavaScript Map 对象深度解剖
JavaScript Map 对象深度解剖 一、Map 核心特性 1.1 什么是 Map? 通俗解释: Map 就像是一个“超级版对象”,它用更灵活的方式存储键值对。举个生活例子: 普通对象(Object)像一本传统电话簿,…...
zlm启用webrtc交叉编译指南
zlm启用webrtc交叉编译指南 一、交叉编译openssl 下载openssl-1.1.1k版本,其他版本可能会有问题 $ wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz $ tar -xvzf openssl-1.1.1k.tar.gz $ cd openssl-1.1.1k $ ./config no-asm shared --openssld…...
树莓派超全系列教程文档--(23)内核参数
内核参数 内核命令行 (cmdline.txt)命令行选项标准条目设置KMS显示模式 其他条目 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 内核命令行 (cmdline.txt) Linux 内核在启动过程中接受一系列命令行参数。在 Raspberry Pi 上,该命令…...
机器学习 从入门到精通 day_05
1. 线性回归 前面介绍了很多分类算法,分类的目标变量是标称型数据,回归是对连续型的数据做出预测。 标称型数据(Nominal Data)是统计学和数据分析中的一种数据类型,它用于分类或标记不同的类别或组别,数据点之间并没有…...
读者、写者问题优化
#include <stdio.h> #include <time.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #define NUM_READERS 5 #define NUM_WRITERS 5 // 定义信号量和全局变量 sem_t sdata, srcount; int rea…...
DeepSeek-V3与DeepSeek-R1架构原理及应用对比分析
DeepSeek-V3与DeepSeek-R1架构原理及应用对比分析 DeepSeek作为中国人工智能领域的重要参与者,推出了V3和R1两款大模型,它们在架构设计和应用场景上各有侧重。本文将深入分析这两款模型在架构原理上的核心差异,并探讨它们如何分别应对复杂推…...
OpenCV图像增强实战教程:从理论到代码实现
OpenCV图像增强实战教程:从理论到代码实现 🔥🚀 📚 想要掌握图像增强的核心技术?本文手把手教你使用OpenCV实现多种图像增强技术,从基础的线性变换到高级的频域滤波,全方位提升你的图像处理能力…...
一文介绍关于多模态的基础知识 !!
文章目录 前言 一、机器学习 二、深度学习 三、应用领域 前言 多模态不再局限于单一类型的数据处理,它融合图像、文本和音频等多种信息源。其基础知识涵盖机器学习、深度学习及其在多模态领域的应用。机器学习部分包含分类、回归、聚类和降维等四类算法;…...
mysql DQL
一.基本查询 1.查询多个字段 2.查看所有字段 3.设置别名 4.去除重复记录 二.条件查询 1.大于小于等于 2.查询 身份证为空的 没有所以没有记录 3.在15到20这个区间范围内 4.or/in 或者 4.like 匹配 (_匹配单个字符 %匹配多个字符) 查询员工信…...
Android Studio 项目文件夹结构详解
文章目录 一、项目视图概览1. Android 视图(简化视图)2. Project 视图(完整物理结构) 二、核心目录详解1. 项目根目录文件2. app 模块目录(主模块)2.1 manifests/2.2 java/2.3 res/ - 资源目录2.4 assets/2…...
Linux系统常见磁盘扩容操作(Common Disk Expansion Operations in Linux Systems)
Linux系统常见磁盘扩容操作 目录说明 一、准备工作:获取目标磁盘信息 (1)确认分区表格式和文件系统 二、扩容已有MBR分区 (1)分区后扩容 ext为例 xfs为例 三、扩容已有GPT分区 (1)分区…...
【UE5 C++】“ProceduralMeshComponent”的使用记录
效果 如下所示,通过“ProceduralMeshComponent”创建了一个自定义形状的Mesh,并且该Mesh包含碰撞信息,然后2s后更新Mesh形状。 步骤 1. 在“xxx.Build.cs”中引入“ProceduralMeshComponent”模块 2. 新建一个Actor类,这里命名为…...
源代码加密之零日攻击
# SDC沙盒:有效防御零日攻击的多层防护体系 在当今复杂多变的网络安全环境中,零日攻击已成为企业面临的重大威胁之一。零日攻击利用尚未被公众发现或尚未被软件供应商修复的漏洞进行攻击,具有极高的隐蔽性和破坏性。SDC沙盒作为一种先进的数…...
Vue2 集成VTK.js 并显示3D影像
Vue2 集成VTK.js 并显示3D影像(核心代码) 作者:coder_fang vtk.js目前官网只有vue3的示例,对于已有vue2系统的集成,需要使用指定版本的vtk,itk等库并修改部分配置即可。 需要的主要库和版本: vue:2.3.4; vtk-v32.9.0.min.js,itk-wasm.min.…...
本地git操作
一、初始化与基础操作 1. 初始化仓库 git init # 当前目录新建仓库 git init <目录名> # 指定目录初始化 2. 查看状态 git status # 显示工作区和暂存区状态 git status -s # 简洁版状…...
AI的出现,是否能替代IT从业者?
*AI在IT领域中的应用已成趋势,IT 从业者们站在这风暴之眼,面临着一个尖锐问题:AI 是否会成为 “职业终结者”?有人担忧 AI 将取代 IT 行业的大部分工作,也有人坚信 IT 从业者的专业技能与创新思维无可替代。那么&#…...
3、组件:魔法傀儡的诞生——React 19 组件化开发全解析
一、开篇:魔法傀儡的觉醒 "每个React组件都像一具魔法傀儡,"邓布利多校长挥动魔杖,空中浮现出闪烁的代码字符,"它们能自主思考、协同工作,甚至能跨越时空(服务器与客户端)执行任…...
Vue 解决 Error: please transfer a valid prop path to form item!
在 Vue.js 中使用表单验证库(如 VeeValidate 或 Element UI 的表单组件时),遇到错误信息 "please transfer a valid prop path to form item!" 通常指的是在表单项的属性绑定中,路径(prop path)不…...
day29 第八章 贪心算法 part03
134. 加油站 “可以换一个思路,首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。 每个加油站的剩余量rest[i]为gas[i] - cost[i]。 i从0开始累加rest[i],和记为curSum…...
贪心算法(19)(java)重构字符串
题目:给定一个字符串 s ,检查是否能重新排布其中的字母,使得两相邻的字符不同。 返回 s 的任意可能的重新排列。若不可行,返回空字符串 "" 。 示例 1: 输入: s "aab" 输出: "aba"示例 2: 输入:…...
Linux下C语言与OpenGL游戏开发指南
1. 为什么选择 Linux C OpenGL? 跨平台兼容性:OpenGL 是跨平台的图形 API,编写的代码稍作修改即可在 Windows/macOS 上运行。 性能控制:C 语言提供底层内存管理和硬件访问能力,适合高性能游戏开发。 开源生态&…...
深入 Java 正则表达式源码:透视 Matcher.group(int) 的分组提取机制
在 Java 中,正则表达式无疑是文本处理的重要工具。而 Matcher.group(int group) 是其中非常关键的一个方法,它用于提取正则中的分组内容。今天我们不仅通过一个例子来看它的使用方法,还会结合底层源码,深入理解它背后的机制。 实…...
解决 Spring Boot 启动报错:数据源配置引发的启动失败
启动项目时,控制台输出了如下错误信息: Error starting ApplicationContext. To display the condition evaluation report re-run your application with debug enabled. 2025-04-14 21:13:33.005 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporte…...
【深度学习的骨架与脉搏】语义分割的卷积神经网络·U-Net
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀《深度学习理论直觉三十讲》_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 …...
ELK+Filebeat 深度部署指南与实战测试全解析
一、介绍 ELK: ELasticsearch ,Logstash,Kibana三大开源框架首字母简写,市面上也被称为Elastic Stack。 Elasticsearch 是一个基于 Lucene 的分布式搜索平台框架,通过 Restful 方式进行交互,具备近实时搜索能力。像百度、Google 这类大数据全…...
Java设计模式之中介者模式:从入门到架构级实践
一、什么是中介者模式? 中介者模式(Mediator Pattern)是一种行为型设计模式,其核心思想是通过引入一个中介对象来封装多个对象之间的交互关系。这种模式将原本复杂的网状通信结构转换为星型结构,类似于现实生活中的机…...
L2TP通道基础实验
目录 实验拓扑: 一、需求配置LAC设置: 界面设置: 编辑LNS设置: 建立静态路由:编辑 策略配置: 二、测试 通讯测试: 实验拓扑: 一、需求配置 LAC设置: [LAC]l2…...
关于字节跳动旗下的豆包(DouBao)软件的详解、核心功能以及与同类产品的对比分析
以下是关于豆包(DouBao)软件的详解、核心功能以及与同类产品的对比分析: 一、豆包(DouBao)详解 豆包是字节跳动推出的一款多功能人工智能助手,主打“智能助手场景化工具”结合,覆盖日常生活、…...
如何在本地修改 Git 项目的远程仓库地址
✅ 场景说明 你当前的 Git 项目地址是: http://192.168.0.16/xxx.git你希望把它改成: http://192.168.0.22:8099/xxx.git🧩 操作步骤 步骤 ①:进入项目所在目录 你已经在正确路径下了: cd C:\Develop\xxx确认这个…...
Gitea 1.23.7 速配
复用容器内的postgresql CREATE USER gitea WITH PASSWORD gitea; CREATE DATABASE gitea; GRANT ALL PRIVILEGES ON DATABASE gitea TO gitea; docker-compose.yml 内容 gitea:image: gitea/gitea:latestcontainer_name: giteaenvironment:- GITEA__server__HTTP_ADDR0.0.0.…...
JavaScript — 函数定义
介绍 JavaScript函数是执行特定任务的代码块,可通过多种方式定义。传统函数声明使用function关键字,后接函数名和参数列表,这种声明会被提升至作用域顶部。函数表达式则将匿名或具名函数赋值给变量,遵循变量作用域规则࿰…...
Allure安装与使用【macOS】
安装: brew install allure 安装插件: pip install allure-pytest2.8.16 生成一个html格式的报告,步骤: 执行生成json,制定结果保存目录 pytest --alluredirreport test_demo.py 查看测试保报告方式 将json转成h…...
FireCrawl爬虫工具, Craw4ai
FireCrawl是一款开源的AI爬虫工具,专门用于Web数据提取,并将其转换为Markdown格式或其他结构化数据。FireCrawl特别适合处理使用JavaScript动态生成的网站,能够自动抓取网站及其所有可访问的子页面内容,并将其转换为适合大语言…...
【Python爬虫】详细入门指南
目录 一、简单介绍 二、详细工作流程以及组成部分 三、 简单案例实现 一、简单介绍 在当今数字化信息飞速发展的时代,数据的获取与分析变得愈发重要,而网络爬虫技术作为一种能够从互联网海量信息中自动抓取所需数据的有效手段,正逐渐走入…...
Cesium.Cesium3DTileset设置贴地,tileset.readyPromise.then报错
tileset.readyPromise.then(function(tileset) { }); 用的readyPromise函数,却报错了,通过参考别人的博客内容发现最终修改的是 modelMatrix这个参数的内容,所以直接舍弃使用readyPromise函数,在代码中等 viewer.scene.primitiv…...
卫星电话扬帆智慧海洋,构筑蓝海通信新生态
海洋,承载着全球90%的贸易运输量,更是我国“向海图强”战略的核心战场。但是,全球95%的海洋区域仍处于蜂窝网络覆盖的“真空地带”,近海信号不稳、远洋通信中断的难题长期制约着海洋经济的纵深发展。技术革新是推动发展的强大引擎…...
大模型不是在推理,只是在复述??
目的 看见一篇论文Recitation over Reasoning: How Cutting-Edge Language Models Can Fail on Elementary School-Level Reasoning Problems?,论文中建立了一个推理题库,通过将推理问题进行改写(通过只改写几个字,颠覆整个问题…...
安全编码课程 实验7 并发
实验项目:C 多线程中的数据竞争与同步机制 实验要求: 1. 编写基础代码:模拟账户余额取款 创建一个全局共享变量 int balance 100,表示初始余额; 创建两个线程 Thread A 和 Thread B,尝试各自取出 100 元&a…...
【vue】2.16简单案例
一、高亮显示点击文字 使用vue绑定页面 设置默认样式 使用for循环数组数据展示,并取得索引 创建点击事件并传承,创建num变量 方法中num传进来的参数, 在内容中使用:class和三元运算符,当numkey时是true显示,…...
多线程进阶知识篇(一)
文章目录 一、开启线程1. start()2. run() 二、单核/多核CPU1. 单核CPU2. 多核CPU3.烧水问题 三、操作线程的命令四、并发的本质五、线程上下文切换1. 定义2. 原因 一、开启线程 1. start() 调用 start() 方法会启动一个新的线程,每次调用 start(),线程…...
【benepar】benepar安装会自动更新pytorch
直接pip install benepar,安装benepar0.2.0时会自动更新torch的版本 解决方法:去https://pypi.org/project/benepar/0.1.3/找历史版本 我的适配版本:python3.9,torch1.11.0(cuda11.3),对应的ben…...
智能云图库-1-项目初始化
项目中的异常处理 自定义异常 在exception包下新建错误码枚举类: Getter public enum ErrorCode {SUCCESS(0, "ok"),PARAMS_ERROR(40000, "请求参数错误"),NOT_LOGIN_ERROR(40100, "未登录"),NO_AUTH_ERROR(40101, "无权限&q…...
每日算法-250414
每日算法学习记录 - 240414 记录今天学习和解决的两道 LeetCode 算法题,主要涉及二分查找的应用。 162. 寻找峰值 题目描述 思路分析 核心思想:二分查找 题目要求找到数组中的任意一个峰值。峰值定义为比其相邻元素都大的元素。题目还隐含了一个条件…...
鸿蒙NEXT开发格式化工具类(ArkTs)
import { i18n } from kit.LocalizationKit;/*** 格式化工具类* 提供电话号码格式化、归属地查询、字符转换等功能。* author: 鸿蒙布道师* since: 2025/04/14*/ export class FormatUtil {/*** 判断传入的电话号码格式是否正确。* param phone - 待验证的电话号码* param coun…...
HarmonyOS 第2章 Ability的开发,鸿蒙HarmonyOS 应用开发入门
第2章 Ability的开发 本章内容 本章介绍HarmonyOS的核心组件Ability的开发。 2.1 Ability概述 2.2 FA模型介绍 2.3 Stage模型介绍 2.4 Ability内页面的跳转和数据传递 2.5 Want概述 2.6 实战:显式Want启动Ability 2.7 实战:隐式Want打开应用管理 2.8 小结 2.9 习题 2.1 Abili…...
CS5346 - Interactivity in Visualization 可视化中的交互
文章目录 Visualization representation interactionInteraction (交互)Benefits (好处)Typical Interaction Techniques(交互技术)SelectFilteringAbstract / Elaborate几何放缩(Geometric zoom)语义放缩࿰…...
AI与我共创WEB界面
记录一次压测后的自我技术提升 这事儿得从机房停电说起。那天吭哧吭哧做完并发压测,正准备截Zabbix监控图写报告,突然发现监控曲线神秘失踪——系统组小哥挠着头说:“上次停电后,zabbix服务好像就没起来过…” 我盯着空荡荡的图表界面,大脑的CPU温度可能比服务器还高。 其…...