.gitlab-ci.yml说明
Gitlab官方文档:https://docs.gitlab.com/ee/ci/yaml/README.html
https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html
https://docs.gitlab.com/ee/ci/docker/using_docker_images.html
GitLab CI/CD 是一个内置在GitLab中的工具,用于通过持续方法进行软件开发:
- Continuous Integration (CI) 持续集成
- Continuous Delivery (CD) 持续交付
- Continuous Deployment (CD) 持续部署
持续集成的工作原理是将小的代码块推送到Git仓库中托管的应用程序代码库中,并且每次推送时,都要运行一系列脚本来构建、测试和验证代码更改,然后再将其合并到主分支中。
持续交付和部署相当于更进一步的CI,可以在每次推送到仓库默认分支的同时将应用程序部署到生产环境。
这些方法使得可以在开发周期的早期发现bugs和errors,从而确保部署到生产环境的所有代码都符合为应用程序建立的代码标准。
GitLab CI/CD 由一个名为 .gitlab-ci.yml 的文件进行配置,改文件位于仓库的根目录下。文件中指定的脚本由GitLab Runner执行。
1. GitLab CI/CD 介绍
软件开发的持续方法基于自动执行脚本,以最大程度地减少在开发应用程序时引入错误的机会。从开发新代码到部署新代码,他们几乎不需要人工干预,甚至根本不需要干预。
它涉及到在每次小的迭代中就不断地构建、测试和部署代码更改,从而减少了基于已经存在bug或失败的先前版本开发新代码的机会。
Continuous Integration(持续集成)
假设一个应用程序,其代码存储在GitLab的Git仓库中。开发人员每天都要多次推送代码更改。对于每次向仓库的推送,你都可以创建一组脚本来自动构建和测试你的应用程序,从而减少了向应用程序引入错误的机会。这种做法称为持续集成,对于提交给应用程序(甚至是开发分支)的每项更改,它都会自动连续进行构建和测试,以确保所引入的更改通过你为应用程序建立的所有测试,准则和代码合规性标准。
Continuous Delivery(持续交付)
持续交付是超越持续集成的更进一步的操作。应用程序不仅会在推送到代码库的每次代码更改时进行构建和测试,而且,尽管部署是手动触发的,但作为一个附加步骤,它也可以连续部署。此方法可确保自动检查代码,但需要人工干预才能从策略上手动触发以必输此次变更。
Continuous Deployment(持续部署)
与持续交付类似,但不同之处在于,你无需将其手动部署,而是将其设置为自动部署。完全不需要人工干预即可部署你的应用程序。
1.1. GitLab CI/CD 是如何工作的
为了使用GitLab CI/CD,你需要一个托管在GitLab上的应用程序代码库,并且在根目录中的.gitlab-ci.yml文件中指定构建、测试和部署的脚本。
在这个文件中,你可以定义要运行的脚本,定义包含的依赖项,选择要按顺序运行的命令和要并行运行的命令,定义要在何处部署应用程序,以及指定是否 要自动运行脚本或手动触发脚本。
为了可视化处理过程,假设添加到配置文件中的所有脚本与在计算机的终端上运行的命令相同。
一旦你已经添加了.gitlab-ci.yml到仓库中,GitLab将检测到该文件,并使用名为GitLab Runner的工具运行你的脚本。该工具的操作与终端类似。
这些脚本被分组到jobs,它们共同组成一个pipeline。一个最简单的.gitlab-ci.yml文件可能是这样的:
before_script:
- apt-get install rubygems ruby-dev -y
run-test:
script:
- ruby --version 6
before_script属性将在运行任何内容之前为你的应用安装依赖,一个名为run-test的job(作业)将打印当前系统的Ruby版本。二者共同构成了在每次推送到仓库的任何分支时都会被触发的pipeline(管道)。
GitLab CI/CD不仅可以执行你设置的job,还可以显示执行期间发生的情况,正如你在终端看到的那样:
为你的应用创建策略,GitLab会根据你的定义来运行pipeline。你的管道状态也会由GitLab显示:
最后,如果出现任何问题,可以轻松地回滚所有更改:
1.2. 基本 CI/CD 工作流程
一旦你将提交推送到远程仓库的分支上,那么你为该项目设置的CI/CD管道将会被触发。GitLab CI/CD 通过这样做:
- 运行自动化脚本(串行或并行) 代码Review并获得批准
- 构建并测试你的应用
- 就像在你本机中看到的那样,使用Review Apps预览每个合并请求的更改
- 代码Review并获得批准
- 合并feature分支到默认分支,同时自动将此次更改部署到生产环境
- 如果出现问题,可以轻松回滚
通过GitLab UI所有的步骤都是可视化的
1.3. 深入了解CI/CD基本工作流程
如果我们深入研究基本工作流程,则可以在DevOps生命周期的每个阶段看到GitLab中可用的功能,如下图所示:
1. Verify
- 通过持续集成自动构建和测试你的应用程序
- 使用GitLab代码质量(GitLab Code Quality)分析你的源代码质量
- 通过浏览器性能测试(Browser Performance Testing)确定代码更改对性能的影响
- 执行一系列测试,比如Container Scanning , Dependency Scanning , JUnit tests
- 用Review Apps部署更改,以预览每个分支上的应用程序更改
2. Package
- 用Container Registry存储Docker镜像
- 用NPM Registry存储NPM包
- 用Maven Repository存储Maven artifacts
- 用Conan Repository存储Conan包
3. Release
- 持续部署,自动将你的应用程序部署到生产环境
- 持续交付,手动点击以将你的应用程序部署到生产环境
- 用GitLab Pages部署静态网站
- 仅将功能部署到一个Pod上,并让一定比例的用户群通过Canary Deployments访问临时部署的功能(PS:即灰度发布)
- 在Feature Flags之后部署功能
- 用GitLab Releases将发布说明添加到任意Git tag
- 使用Deploy Boards查看在Kubernetes上运行的每个CI环境的当前运行状况和状态
- 使用Auto Deploy将应用程序部署到Kubernetes集群中的生产环境
使用GitLab CI/CD,还可以:
- 通过Auto DevOps轻松设置应用的整个生命周期
- 将应用程序部署到不同的环境
- 安装你自己的GitLab Runner
- Schedule pipelines
- 使用安全测试报告(Security Test reports)检查应用程序漏洞
2. GitLab CI/CD 快速开始
.gitlab-ci.yml文件告诉GitLab Runner要做什么。一个简单的管道通常包括三个阶段:build、test、deploy
管道在 CI/CD > Pipelines 页面
2.1. 创建一个 .gitlab-ci.yml 文件
通过配置.gitlab-ci.yml文件来告诉CI要对你的项目做什么。它位于仓库的根目录下。
仓库一旦收到任何推送,GitLab将立即查找.gitlab-ci.yml文件,并根据文件的内容在Runner上启动作业。
下面是一个Ruby项目配置例子:
image: "ruby:2.5"
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- ruby -v
- which ruby
- gem install bundler --no-document
- bundle install --jobs $(nproc) "${FLAGS[@]}"
rspec:
script:
- bundle exec rspec
rubocop:
script:
- bundle exec rubocop
上面的例子中,定义里两个作业,分别是 rspec 和 rubocop,在每个作业开始执行前,要先执行before_script下的命令
2.2. 推送 .gitlab-ci.yml 到 GitLab
git add .gitlab-ci.yml
git commit -m "Add .gitlab-ci.yml"
git push origin master
2.3. 配置一个Runner
在GitLab中,Runner运行你定义在.gitlab-ci.yml中的作业(job)
一个Runner可以是一个虚拟机、物理机、docker容器,或者一个容器集群
GitLab与Runner之间通过API进行通信,因此只需要Runner所在的机器有网络并且可以访问GitLab服务器即可
你可以去 Settings ➔ CI/CD 看是否已经有Runner关联到你的项目,设置Runner简单又直接
2.4. 查看 pipeline 和 jobs的状态
在成功配置Runner以后,你应该可以看到你最近的提交的状态
为了查看所有jobs,你可以去 Pipelines ➔ Jobs 页面
通过点击作业的状态,你可以看到作业运行的日志
回顾一下:
1、首先,定义.gitlab-ci.yml文件。在这个文件中就定义了要执行的job和命令
2、接着,将文件推送至远程仓库
3、最后,配置Runner,用于运行job
3. Auto DevOps
Auto DevOps 提供了预定义的CI/CD配置,使你可以自动检测,构建,测试,部署和监视应用程序。借助CI/CD最佳实践和工具,Auto DevOps旨在简化成熟和现代软件开发生命周期的设置和执行。
借助Auto DevOps,软件开发过程的设置变得更加容易,因为每个项目都可以使用最少的配置来完成从验证到监视的完整工作流程。只需推送你的代码,GitLab就会处理其他所有事情。这使得启动新项目更加容易,并使整个公司的应用程序设置方式保持一致。
下面这个例子展示了如何使用Auto DevOps将GitLab.com上托管的项目部署到Google Kubernetes Engine
示例中会使用GitLab原生的Kubernetes集成,因此不需要再单独手动创建Kubernetes集群
本例将创建并部署一个从GitLab模板创建的应用
3.1. 从GitLab模板创建项目
在创建Kubernetes集群并将其连接到GitLab项目之前,你需要一个Google Cloud Platform帐户
下面使用GitLab的项目模板来创建一个新项目
给项目起一个名字,并确保它是公有的
3.2. 从GitLab模板创建Kubernetes集群
点击 Add Kubernetes cluster 按钮,或者 Operations > Kubernetes
安装Helm, Ingress, 和 Prometheus
3.3. 启用Auto DevOps (可选)
Auto DevOps 默认是启用的。
导航栏 Settings > CI/CD > Auto DevOps
勾选 Default to Auto DevOps pipeline
最后选择部署策略
一旦你已经完成了以上所有的操作,那么一个新的 pipeline 将会被自动创建。为了查看pipeline,可以去 CI/CD > Pipelines
3.4. 部署应用
到目前为止,你应该看到管道正在运行,但是它到底在运行什么呢?
管道内部分为4个阶段,我们可以查看每个阶段有几个作业在运行,如下图:
构建 -> 测试 -> 部署 -> 性能测试
现在,应用已经成功部署,让我们通过浏览器查看。
首先,导航到 Operations > Environments
在Environments中,可以看到部署的应用的详细信息。在最右边有三个按钮,我们依次来看一下:
第一个图标将打开在生产环境中部署的应用程序的URL。这是一个非常简单的页面,但重要的是它可以正常工作!
紧挨着第二个是一个带小图像的图标,Prometheus将在其中收集有关Kubernetes集群以及应用程序如何影响它的数据(在内存/ CPU使用率,延迟等方面)
第三个图标是Web终端,它将在运行应用程序的容器内打开终端会话。
4. Examples
使用GitLab CI/CD部署一个Spring Boot应用
示例 .gitlab-ci.yml
image: java:8
stages:
- build
- deploy
before_script:
- chmod +x mvnw
build:
stage: build
script: ./mvnw package
artifacts:
paths:
- target/demo-0.0.1-SNAPSHOT.jar
production:
stage: deploy
script:
- curl --location "https://cli.run.pivotal.io/stable?release=linux64-binary&source=github" | tar zx
- ./cf login -u $CF_USERNAME -p $CF_PASSWORD -a api.run.pivotal.io
- ./cf push
only:
- master
5. Docs
https://about.gitlab.com/solutions/kubernetes/
https://docs.gitlab.com/ee/ci/README.html
https://docs.gitlab.com/ee/ci/introduction/
https://docs.gitlab.com/ee/topics/autodevops/
https://docs.gitlab.com/ee/ci/examples/README.html
使用gitlab ci 持续集成部署
先来看下总共这一百来个的成果
需要的环境说明:
gitlab 服务
springboot项目
一台虚拟机(java,maven,docker环境)
一、首先构建虚拟机的java和maven环境
(1)下载 apache-maven-3.6.3-bin.tar.gz
和jdk-linux-x64.tar.gz
然后后解压
tar -zxvf /usr/local/jdk8/jdk-linux-x64.tar.gz
tar -zxvf /usr/local/jdk8/apache-maven-3.6.3-bin.tar.gz
(2)配置环境变量 /etc/profile
JAVA_HOME=/usr/local/jdk8/jdk1.8.0_131
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.3
export PATH=$MAVEN_HOME/bin:$PATH
maven: 如果提示命令未找到,执行
sudo apt install maven
mvn help:system
二、安装 GitLab-Runner
(1)在虚拟机安装runner
#在ubuntu server16.04版本下使用命令即可安装
$ sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
#接着授予可执行权限
$ sudo chmod +x /usr/local/bin/gitlab-runner
#创建一个gitlab-ci用户
$ sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
#安装,并作为服务启动
$ sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
(2)注册Runner
sudo gitlab-runner register
会要求输入gitlab的url和Token.
查找过程如下:
进入仓库->settings->CI/CD,找到Runner Settings这一项,点击Expend,即可在Setup a specific Runner manually这项中找到
(3)当这些做完之后启用命令启动Runner
gitlab-runner run 或者 gitlab-runner start
启动成功后就可以看到,gitlab对应的仓库下(操作:进入仓库->settings->CI/CD,找到Runner Settings这一项,点击Expend,即可在Setup a specific Runner manually)看到注册的runner已经在运行了。
三、配置 文件 Dockerfile和.gitlab-ci.yml
(1).gitlab-ci.yml
package是打包
deploy 是部署
stages:
- package
- deploy
package:
stage: package
script:
- mvn clean package install -pl smart-ele-common -am
- mvn clean package -pl smart-ele-api -am
#- mvn clean package -pl smart-ele-dispatch -am
artifacts:
when: on_success
paths:
- target/
tags:
# 执行Job的服务器
- smart
docker-deploy:
stage: deploy
# 执行Job内容
script:
# 通过Dockerfile生成cicd-demo镜像
- docker build -t smart-ele-api .
# 删除已经在运行的容器
#- if [ $(docker ps -aq --filter name= smart-ele-api) ]; then docker rm -f smart-ele-api;fi
# 通过镜像启动容器,并把本机8877端口映射到容器8877端口
- docker run -d -p 8877:8877 --name smart-ele-api smart-ele-api
# 通过Dockerfile生成smart-ele-dispatch镜像
- docker build -t smart-ele-dispatch .
# 删除已经在运行的容器
#- if [ $(docker ps -aq --filter name= smart-ele-dispatch) ]; then docker rm -f smart-ele-dispatch;fi
# 通过镜像启动容器,并把本机8001端口映射到容器8001端口
- docker run -d -p 8866:8866 --name smart-ele-dispatch smart-ele-dispatch
tags:
# 执行Job的服务器
- smart
only:
# 只有在master分支才会执行
- master
(2)Dockerfile
FROM java:8
#工作目标目录
WORKDIR /home
#dockerfile文件一定要在项目的根目录
# smart-ele-api
#前面的是从dockerfile的目录结构开始,那么就直接找到当前目录下的api
COPY smart-ele-api/target/smart-ele-api.jar .
RUN ls /home/
#赋权限
RUN chmod 777 /home/smart-ele-api.jar
#启动
ENTRYPOINT ["nohup","java", "-jar", "/home/smart-ele-api.jar"]
#暴露端口
EXPOSE 8877
#此处不能同时给两个jar,如果给了两个也会覆盖掉或者后者不生效,得采用其他方式
#smart-ele-dispatch
#COPY smart-ele-dispatch/target/smart-ele-dispatch.jar .
#RUN ls /home/
#RUN chmod 777 /home/smart-ele-dispatch.jar
#启动
#ENTRYPOINT ["nohup","java", "-jar", "/home/smart-ele-dispatch.jar"]
#EXPOSE 8866
到这里就会发现上传没问题,然后查看docker也运行起来了
docker ps -a
查看docker执行的日志 sudo docker attach --sig-proxy=false smart-ele-api
遇到的问题整理
1.发现执行了之后就自动关闭了,然后就找为什么会自动关闭的原因
1.没加nohup?
2.打印日志sudo docker logs -f -t --since=“2020-12-10” --tail=100 smart-ele-api
发现找不到启动的jar
然后去查看执行的路径,发现copy 的路径不对,和build上下文的路径有关系
这里是之前配置错误例子,上面是正确例子
FROM openjdk:8-jre
#COPY /home/gitlab-runner/builds/HFkBbk1A/0/weijianxing/smart-ele-module/smart-ele-api/target/smart-ele-api.jar /home/gitlab-runner/smart-ele-api.jar
ENTRYPOINT ["nohup","java", "-jar", "/home/gitlab-runner/builds/HFkBbk1A/0/weijianxing/smart-ele-module/smart-ele-api/target/smart-ele-api.jar"]
EXPOSE 8000
#COPY /home/gitlab-runner/builds/HFkBbk1A/0/weijianxing/smart-ele-module/smart-ele-dispatch/target/smart-ele-dispatch.jar /home/gitlab-runner/smart-ele-dispatch.jar
ENTRYPOINT ["nohup","java", "-jar", "/home/gitlab-runner/builds/HFkBbk1A/0/weijianxing/smart-ele-module/smart-ele-dispatch/target/smart-ele-dispatch.jar"]
EXPOSE 8001
参考:
gitlab ci搭建
https://www.jianshu.com/p/c398509f8861
https://blog.csdn.net/weixin_36380516/article/details/108839861
dockerfile文件的COPY 用法
https://www.cnblogs.com/sparkdev/p/9573248.html
这种方式可以同时运行多个maven子项目
所有的代码都在gitlab.yml 和dockerfile和docker-compose 中完成的
包括jdk和maven环境以及打包部署启动
首先看下项目的目录结构和Dockerfile以及gitlab-ci文件的放置位置
说明:
目前结果是 只有单独打包后的jar生成的镜像.,其他操作不在最后的jar中(分离)
1.根目录下的 Dockerfile文件是搭建 jdk和maven的环境和配置环境变量的镜像
2.根目录下的 Dockerfile2文件是单独的在docker中进行mvn打包命令的
2.api和dispatch目录下的Dockerfile文件是创建对应jar的镜像
3.docker-compose文件是运行启动jar的
4.gitlab ci 是执行运行这些文件的总文件安装gitlab-runner 和注册就不说明了,上篇文章有写到。。。 直接来看重要的几个文件
.gitlab-ci.yml
主要分三个步骤,第一个是创建基础镜像,第二步是创建执行maven的镜像并且拷贝对应的jar包到宿主机,然后创建api和dispatch的镜像,然后api和dispatch中从宿主机去copy打包好的jar。第三步是启动执行docker-compose
stages:
- build
- package
- deploy
build:
stage: build
script:
# 判断是否存在,通过Dockerfile生成java:1.8 镜像(只需要执行一次)
#- if [ $( docker images java:1.8) ]; then echo "1" else docker build -t java:1.8 -f ./Dockerfile . ;fi
- docker build -t java:1.8 -f ./Dockerfile .
tags:
# 执行Job的服务器
- smart
only:
# 只有在master分支才会执行
- master
package:
stage: package
script:
# 执行 mvn命 令
- docker build -t mvn -f ./Dockerfile2 .
#拷贝mvn镜像 临时文件save下的jar包到 宿主机65上的tt目录下
- docker run -v $PWD/tt:/home/save mvn
# 通过Dockerfile生成smart-ele-api镜像
- docker build -t smart-ele-api -f ./smart-ele-api/Dockerfile .
# 通过Dockerfile生成smart-ele-dispatch镜像
- docker build -t smart-ele-dispatch -f ./smart-ele-dispatch/Dockerfile .
artifacts:
when: on_success
paths:
- target/
tags:
# 执行Job的服务器
- smart
only:
# 只有在master分支才会执行
- master
deploy:
stage: deploy
script:
# 通过镜像启动容器,并把本机8001端口映射到容器8001端口
- docker-compose up -d
artifacts:
when: on_success
paths:
- target/
tags:
# 执行Job的服务器
- smart
only:
# 只有在master分支才会执行
- master
根目录的dockerfile
FROM docker.io/library/centos:latest
RUN yum -y install wget
#构建 maven 环境
RUN cd /usr/local
RUN mkdir maven
RUN chmod 777 -R maven
RUN wget -P /usr/local/maven http://apache-mirror.rbc.ru/pub/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
RUN cd /usr/local/maven && tar -zxvf apache-maven-3.6.3-bin.tar.gz
RUN export PATH=apache-maven-3.6.3/bin:$PATH
RUN export PATH=/usr/local/maven/apache-maven-3.6.3/bin:$PATH
RUN echo $PATH
#构建java jdk1.8环境
RUN cd /usr/local
RUN mkdir jdk8
RUN chmod 777 -R jdk8
RUN wget -P /usr/local/jdk8 --no-check-certificate --no-cookies --header "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz
RUN cd /usr/local/jdk8 && tar -zxvf jdk-8u141-linux-x64.tar.gz
ENV JAVA_HOME /usr/local/jdk8/jdk1.8.0_141
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH
#执行环境变量
#ENV JAVA_HOME /usr/local/jdk8/jdk1.8.0_141
#ENV M2_HOME /usr/local/maven/apache-maven-3.6.3
#ENV PATH $PATH:$JAVA_HOME/bin:$M2_HOME/bin```
根目录的dockerfile2
FROM java:1.8
#工作目标目录
WORKDIR /home
#拷贝项目到docker中,然后进行打包jar
COPY / .
RUN ls /home \
&& mkdir /save
#maven 打包
RUN mvn clean install -pl smart-ele-common -am
RUN mvn clean install -pl smart-ele-api -am
RUN mvn clean install -pl smart-ele-dispatch -am
#RUN ls /home/smart-ele-common/target
#RUN ls /home/smart-ele-api/target
#RUN ls /home/smart-ele-dispatch/target
ENTRYPOINT cp /home/smart-ele-api/target/smart-ele-api.jar /home/save/ && cp /home/smart-ele-dispatch/target/smart-ele-dispatch.jar /home/save/
#执行 复制命令
#ENTRYPOINT cp /home/pom.xml /home/save/ && cp /home/README.md /home/save/
api的dockerfile
FROM java:8
#工作目标目录
WORKDIR /home
#RUN ls /home/
COPY tt/smart-ele-api.jar .
#COPY tt/ .
#RUN ls /home
#暴露端口
EXPOSE 8877
dispatch的dockerfile
FROM java:8
#工作目标目录
WORKDIR /home
COPY tt/smart-ele-dispatch.jar .
#RUN ls /home
#暴露端口
EXPOSE 8855
docker-compose.yml
version: "3"
services:
smart-ele-api:
image: smart-ele-api
ports:
- "8877:8877"
entrypoint : ["nohup","java", "-jar", "/home/smart-ele-api.jar"]
smart-ele-dispatch:
image: smart-ele-dispatch
ports:
- "8855:8855"
entrypoint : ["nohup","java", "-jar", "/home/smart-ele-dispatch.jar"]
效果图
命令
查看dockers-compose执行的日志文件
首先要进入到该compose-yml文件的目录(也就是生成的项目路径)----然后执行
sudo docker-compose logs -f smart-ele-api
停止也是在该目录下直接 sudo docker-compose down(直接项目停止容器删除)
删除镜像根据名称和版本号(tag)sudo docker image rm smart-ele-dispatch1:latest
参考上一篇: https://blog.csdn.net/weijx_/article/details/111033457
参考链接:
https://www.cnblogs.com/cjsblog/p/12256843.html
https://cloudaffaire.com/gitlab-ci-yml-part-one-basics-of-script-image-services-stages/ 还是老外和英文写的清晰
https://docs.gitlab.com/ee/ci/services/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!