当前位置: 首页 > news >正文

容器化安装Jenkins部署devops

基础环境介绍

系统使用的是centos7.9

内核使用的是5.16.13-1.el7.elrepo.x86_64

容器使用的是26.1.4

docker-compose使用的是 v2.29.0

链路图

devops

配置git环境插件

部署好jenkins后开始配置 jenkins连接git,这里需要jenkins有连接git的插件。在已安装的插件中寻找git。

在可用的插件里找到 git plugin 

在可用的插件里找到  Git Parameter

在页面看到有git插件后 进入容器也需要再验证一下,命令行直接输入git 看看是否有很多命令出来。

 jenkinsdata]# docker exec -it bb4 /bin/bash
jenkins@bb4419a0ac15:/$ git
git                 git-lfs             git-receive-pack    git-shell           git-upload-archive  git-upload-pack
jenkins@bb4419a0ac15:/$ git

这里git插件验证完成,没啥问题了。

配置jenkins里的jdk和maven环境变量

公司大部分都是用的java项目打包的

这里服务器上有jdk和maven  ,直接把文件目录移动过去就好了。

cp -r /usr/local/jdk/ /data/jenkinsdata/
cp -r /root/maven/ /data/jenkinssdata/# 记得授权app权限 这里容器内是用app启动的
chown -R app:app maven  jdk

配置jdk的变量

进入容器查看jdk的路径

maven]# docker exec -it bb4 /bin/bash
jenkins@bb4419a0ac15:/$ ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
jenkins@bb4419a0ac15:/$ cd /var/jenkins_home/jdk/
jenkins@bb4419a0ac15:~/jdk$ ls
COPYRIGHT  README.html                         THIRDPARTYLICENSEREADME.txt  include         jmc.txt  legal  man      src.zip
LICENSE    THIRDPARTYLICENSEREADME-JAVAFX.txt  bin                          javafx-src.zip  jre      lib    release
jenkins@bb4419a0ac15:~/jdk$ pwd
/var/jenkins_home/jdk

在页面配置jdk环境变量

1、这里不要选择自动安装,已经把jdk目录复制到宿主机的卷上了。

2、这里写的路径是上面进入容器后的路径。

配置maven的变量

进入容器查看maven的路径

jenkins@bb4419a0ac15:~/maven$ pwd
/var/jenkins_home/maven

在页面配置maven环境变量

1、这里不要选择自动安装,已经把maven目录复制到宿主机的卷上了。

2、这里写的路径是上面进入容器后的路径。

配置一个test项目

目的:是要 jenkins能够从gitlab拉取代码,并且完成打包编译的操作。

第一步构建项目

新建任务

这里名称自定义起一个,选择自由风格创建。

页面选择刚创建的test0920v1项目工程

第二步配置gitlab地址及凭证

这里点击 源码管理 开始配置私有仓库gitlab地址,这里会报错因为没有配置凭证

添加账号密码

选择刚添加的账号密码。

注意 这里需要jenkins容器所在宿主机可以连接gitlab,这里连接gitlab的账号有权限拉取代码。如果配置没有问题后 页面不会出现报错信息。

第三步拉取代码查看是否成功

点击项目 立即构建

控制台输出

查看日志信息

进入容器查看本次是否把代码拉取下来了,进入目录查看代码文件,看到是有文件的,说明拉取代码成功。

jenkins@bb4419a0ac15:~/maven$ cd /var/jenkins_home/workspace/test0920v01
jenkins@bb4419a0ac15:~/workspace/test0920v01$ pwd
/var/jenkins_home/workspace/test0920v01
jenkins@bb4419a0ac15:~/workspace/test0920v01$ ls
Jenkinsfile  README.md  docker  pom.xml  src

第四配置maven编译代码

选择到build steps --> maven目标

选择刚才添加的maven

编写编译代码的命令,保存退出点击立即构建。

注意这里写命令的时候 不要写mvn了 clean install -Dmaven.test.skip=true -U  直接写mvn后面的参数就好了,如果这里 写成 mvn clean install -Dmaven.test.skip=true -U 会报错。

点击构建查看日志,这里我就不再重复截图了。

这里看到日志是编译成功了

进入服务器查看是否打包成功,查看到是有jar包的,再次验证成功。

jenkins@bb4419a0ac15:~/workspace/test0920v01/target$ pwd
/var/jenkins_home/workspace/test0920v01/target
jenkins@bb4419a0ac15:~/workspace/test0920v01/target$ ls
classes  datax-db.jar  datax-db.jar.original  generated-sources  maven-archiver  maven-status

第五步 把打包好的jar包发送到服务器上

推送到目标服务器上 还需要ssh插件,Publish Over SSH  ,  SSH

上面插件安装完成后开始配置ssh插件

这里先配置一个远程服务器。(这里如果点击没有反应,重启一下容器)

这里选择高级选项点击输入密码

点击测试密码,显示success没有问题了。

 开始配置Job

选择构建后操作,这里因为上面安装好了插件,这里才有

找到构建后操作

下面要写容器内打包的相对路径,查看容器内的路径

jenkins@bb4419a0ac15:~/workspace/test0920v01$ ls
Jenkinsfile  README.md  docker  pom.xml  src  target
jenkins@bb4419a0ac15:~/workspace/test0920v01$ cd target/
jenkins@bb4419a0ac15:~/workspace/test0920v01/target$ ls
classes  datax-db.jar  datax-db.jar.original  generated-sources  maven-archiver  maven-status

这里路径是target\*.jar 目录下的jar文件

查看任务日志 已经执行了推送步骤

查看目标服务器是否有文件,这里显示目标服务器上已有jar包。

[root@docker-010050111111-cm5 target]# pwd
/opt/target
[root@docker-010050111111-cm5 target]# ls
datax-db.jar

第六步 在代码中配置docker目录

在代码根目录里增加一个docker目录,创建一个dockerfile文件。

FROM harbor.xxx.xxx.com/base/ubuntu:20.04
WORKDIR /optENV project=$project
ENV env_huanjing=$env_huanjing
ENV pp_agent_id=$pp_agent_id
ENV jacoco="-javaagent:/data/jacoco/org.jacoco.agent-0.8.5-runtime.jar=includes=*,output=tcpserver,address=*,port=18524"
ENV pp_agent="-javaagent:/data/pp-agent/pinpoint-bootstrap.jar -Dpinpoint.applicationName=tihuan_project-tihuan_app_env"
ENV java_opts="-Xms1012m -Xmx2072m -XX:-UseGCOverheadLimit -Dspring.cloud.nacos.config.group=FUSION_GROUP  -Dspring.cloud.nacos.server-addr=10.50.xxx.17:8848,10.50.xxx.18:8848,10.50.xxx.19:8848 -Dspring.cloud.nacos.config.namespace=ad938948-cc3e-4bcc-b458-f0af9548eeef"# app
ADD *.jar .
CMD  /usr/local/jdk/bin/java -jar ${pp_agent} ${jacoco} ${java_opts} -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=utf-8 -Dspring.profiles.active=${app_env} -Dspring.cloud.nacos.discovery.ip=${app_serverip} -Dspring.cloud.nacos.discovery.port=${app_port} datax-db.jar

创建docker-compose.yml 文件

services:datax-db:build:context: ./dockerfile: Dockerfileimage: datax-db:v1.0.0container_name: datax-dbports:- 8080:8080

这里添加了两个docker相关的文件,一个是dockerfile打包镜像,另外一个是 docker-compose文件,后构建后操作 把命令推送到目标服务器。

cd docker
mv ../target/*.jar ./
docker-compose down
docker-compose up -d --build

以上内容根据每个人的不同的镜像及环境修改,编辑完后开始点击立即构建,会把代码及文件推送至目标服务器,并在目标服务器上打包镜像及运行容器。

在目标服务器上查看已运行的容器。这里编译打包和运行命令是需要根据业务改变的。

查看任务的状态,查看任务的日志

这里看到传了4个文件 并且后续的shell命令已执行成功。

查看目标服务器容器运行情况,(这里报错原因是因为业务连接依赖问题,就不再改了,这里算是已成功)

 docker]# docker ps -a | grep datax-db
c7d95614554f        datax-db:v1.0.0                                                                          "/bin/sh -c '/usr/lo…"   41 seconds ago      Exited (1) 31 seconds ago                                                                   datax-db

到这里 拉取代码,编译 ,再部署到目标机器上使用容器的方式已完成了。

配置sonarqube

这里分为三部分  第一部分部署sonarqube服务,第二部分部署sonarqube的jenkins插件,第三部分部署sonarqube在jenkins的环境变量。

第一部分部署sonarqube服务

软件分为社区版和商用版,这里下载稳定的社区版本(lts-community)

 docker pull sonarqube:lts-communitydocker pull postgres

新版本使用Pg做为数据库。

创建一个存储的sonarqube的目录,创建docker-compose文件

services:db:image: postgrescontainer_name: dbports:- 5432:5432networks:- sonarnetenvironment:POSTGRES_USER: sonarPOSTGRES_PASSWORD: sonarTZ: Asia/Shanghaisonarqube:image: sonarqube:lts-communitycontainer_name: sonarqubedepends_on:- dbports:- 9000:9000networks:- sonarnetenvironment:SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarSONAR_JDBC_USERNAME: sonarSONAR_JDBC_PASSWORD: sonarTZ: Asia/Shanghai
networks:sonarnet:driver: bridge

启动服务

docker-compose up -d

启动sonarnet服务,这里查看容器服务报错,根据提示修改配置。

anglingIndicesState] gateway.auto_import_dangling_indices is disabled, dangling indices will not be automatically detected or imported and must be managed manually
2024.09.23 09:36:33 INFO  es[][o.e.n.Node] initialized
2024.09.23 09:36:33 INFO  es[][o.e.n.Node] starting ...
2024.09.23 09:36:33 INFO  es[][o.e.t.TransportService] publish_address {127.0.0.1:44639}, bound_addresses {127.0.0.1:44639}
2024.09.23 09:36:33 INFO  es[][o.e.b.BootstrapChecks] explicitly enforcing bootstrap checksERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
ERROR: Elasticsearch did not exit normally - check the logs at /opt/sonarqube/logs/sonarqube.log
2024.09.23 09:36:33 INFO  es[][o.e.n.Node] stopping ...
2024.09.23 09:36:33 INFO  es[][o.e.n.Node] stopped
2024.09.23 09:36:33 INFO  es[][o.e.n.Node] closing ...
2024.09.23 09:36:33 INFO  es[][o.e.n.Node] closed
2024.09.23 09:36:33 WARN  app[][o.s.a.p.AbstractManagedProcess] Process exited with exit value [ElasticSearch]: 78
2024.09.23 09:36:33 INFO  app[][o.s.a.SchedulerImpl] Process[ElasticSearch] is stopped
2024.09.23 09:36:33 INFO  app[][o.s.a.SchedulerImpl] SonarQube is stopped

修改系统配置

echo vm.max_map_count=262144 >> /etc/sysctl.conf
sysctl -p   #立即生效

修改完成后再次启动服务

docker-compose up -d

访问web页面  IP地址+端口9000,账号密码默认admin/admin

首次登录后修改admin账号密码

修改后 登录访问页面

下载安装中文插件

点击重启服务,这里是容器启动的,还需要在宿主机重启容器。

到创建docker-compose目录下 restart

sonarqube_docker]# docker-compose restart
[+] Restarting 2/2✔ Container sonarqube  Started                                                                                                          1.1s✔ Container db         Started          

访问web页面,查看已换成中文。

第二部分部署sonarqube的jenkins插件

 在插件中搜索 sonarqube插件,安装插件。

安装插件这里有可能会安装失败

等待重启后打开jenkins的web页面,系统管理-->system

配置sonarqube参数,在下面添加账号的token。

这里选择凭证类型 Secret text 类型

在sonarqube的web页面找到右上角的 账号-->安全 ,根据提示 输入名称 ,类型 和选择过期时间,点击生成。

复制记住这个token,黏贴到jenkins凭证这里,输入描述保存。

选择刚添加的这个凭证,保存

第三部分部署sonarqube在jenkins的环境变量

sonar-scaner下载地址

https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.1.2450-linux.zip

可以在以下地址寻找更多版本的安装包。

把下载的包上传到服务器上,可以直接传到jenkins映射的路径里

# 这里上传和解压都省略了,还需要给目录授予一定的权限,这里jenkins映射出来的是什么文件权限,就给sonar也授予什么文件权限就好了
jenkins_docker]# cd /data/jenkinsdata/sonar-scanner/
sonar-scanner]# pwd
/data/jenkinsdata/sonar-scanner
sonar-scanner]# ls
bin  conf  jre  lib

配置sonarqube的环境变量,这里不要选择自动安装,把自动安装对钩取消就好。名字随意输入一个,环境变量要容器内的路径,这里/var/jenkins_home是容器路径。这里路径如果输入错误会有黄色的提示。

配置之前的test项目,在增加构建步骤这里点击下 下拉列表,选择execule sonarqube scanner

这里配置完成,(这里注意Key的首字母要大写)

sonar.projectname=${JOB_NAME}
sonar.projectKey=${JOB_NAME}
sonar.source=./
sonar.java.binaries=target

配置示例

这里点击立即构建查看详情,sonarqube命令正常执行了。

日志输出是正常的。

查看sonarqube的web终端。这里选择项目,查看到刚推送的详情,可以查看项目的具体情况。

点进去可以看到更详细的信息

以上的问题由研发解决,这里运维无需处理。

配置harbor

把自定义镜像推送到harbor服务器,目标服务器端通过harbor仓库来拉取文件。

安装harbor仓库

github下载地址

https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz

下载文件到服务器,解压包 配置文件harbor.yml.tmpl复制出来一份harbor.yml。

harbor]# pwd
/data/harbor
harbor]# ls
common.sh  harbor.v2.11.1.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare

编辑 harbor.yml 文件

1、这里修改 hostname 后面改成IP地址

2、把https都注释掉

3、把服务映射到宿主机上的存储路径变一下 data_volume: /data/harbordata 

其它的配置不变

 harbor]# egrep -v '#|^$' harbor.yml
hostname: 10.50.xxx.xxx
http:port: 80
harbor_admin_password: Harbor12345
database:password: root123max_idle_conns: 100max_open_conns: 900conn_max_lifetime: 5mconn_max_idle_time: 0
data_volume: /data/harbordata
trivy:ignore_unfixed: falseskip_update: falseskip_java_db_update: falseoffline_scan: falsesecurity_check: vulninsecure: falsetimeout: 5m0s
jobservice:max_job_workers: 10job_loggers:- STD_OUTPUT- FILE
notification:webhook_job_max_retry: 3
log:level: infolocal:rotate_count: 50rotate_size: 200Mlocation: /var/log/harbor
_version: 2.11.0
proxy:http_proxy:https_proxy:no_proxy:components:- core- jobservice- trivy
upload_purging:enabled: trueage: 168hinterval: 24hdryrun: false
cache:enabled: falseexpire_hours: 24

开始安装harbor

harbor]# sh install.sh

查看运行日志,这边查看到运行成功。

✔ ----Harbor has been installed and started successfully.----harbor]# docker-compose ps
WARN[0000] /data/harbor/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
NAME                IMAGE                                 COMMAND                   SERVICE       CREATED         STATUS                            PORTS
harbor-core         goharbor/harbor-core:v2.11.1          "/harbor/entrypoint.…"   core          8 seconds ago   Up 6 seconds (health: starting)
harbor-db           goharbor/harbor-db:v2.11.1            "/docker-entrypoint.…"   postgresql    8 seconds ago   Up 6 seconds (health: starting)
harbor-jobservice   goharbor/harbor-jobservice:v2.11.1    "/harbor/entrypoint.…"   jobservice    7 seconds ago   Up 2 seconds (health: starting)
harbor-log          goharbor/harbor-log:v2.11.1           "/bin/sh -c /usr/loc…"   log           8 seconds ago   Up 7 seconds (health: starting)   127.0.0.1:1514->10514/tcp
harbor-portal       goharbor/harbor-portal:v2.11.1        "nginx -g 'daemon of…"   portal        8 seconds ago   Up 6 seconds (health: starting)
nginx               goharbor/nginx-photon:v2.11.1         "nginx -g 'daemon of…"   proxy         7 seconds ago   Up 6 seconds (health: starting)   0.0.0.0:80->8080/tcp, :::80->8080/tcp
redis               goharbor/redis-photon:v2.11.1         "redis-server /etc/r…"   redis         8 seconds ago   Up 6 seconds (health: starting)
registry            goharbor/registry-photon:v2.11.1      "/home/harbor/entryp…"   registry      8 seconds ago   Up 6 seconds (health: starting)
registryctl         goharbor/harbor-registryctl:v2.11.1   "/home/harbor/start.…"   registryctl   8 seconds ago   Up 6 seconds (health: starting)

查看服务挂载出来的持久化目录

harbor]# ls /data/harbordata/
ca_download  database  harbor  job_logs  redis  registry  secret

访问harbor,IP地址+80端口 账号默认是admin/Harbor@123

新建私有仓库

创建repo镜像仓库

这里如果让宿主机成功推送容器到镜像地址,这里还需要修改docker服务的配置文件/etc/docker/daemon.json,修改完配置文件后重启服务。

{"insecure-registries": ["10.50.xxx.xxx:80"],"registry-mirrors": ["https://hub.iyuu.cn","https://docker.1panel.live"],"data-root": "/data/dockerdb/docker"
}

重启完后开始登录docker服务,这里看到Succeeded 是登录成功了。

 harbor]# docker login -u admin -p Harbor12345 10.50.xxx.xxx:80
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded

给镜像打上标签

 docker tag jenkins/jenkins:2.319.1-lts 10.50.xxx.xxx:80/repo/jenkins:2.319.1-lts

查看镜像

10.50.110.152:80/repo/jenkins   2.319.1-lts     2a4bbe50c40b   2 years ago    441MB
jenkins/jenkins                 2.319.1-lts     2a4bbe50c40b   2 years ago    441MB

推送镜像到私有仓库

 docker push 10.50.xxx.xxx:80/repo/jenkins:2.319.1-lts

web页面查看镜像,推送成功。

以上harbor容器已经安装好了,如需让jenkins使用容器并推送,需要修改两个地方,一个是宿主机的/var/run/docker.sock,另一个是daemon.json 两个文件,修改完成后,jenkins就可以直接使用宿主机的容器环境了。

第一步 先对需要修改的配置文件进行备份

run]# cp -ar docker.sock docker.sock.bak
run]# ll docker.sock*
srw-rw---- 1 root docker 0 9月  11 16:07 docker.sock
srw-rw---- 1 root docker 0 9月  11 16:07 docker.sock.bak

第二步 开始修改配置文件

授权文件

run]# chown root:root docker.sock
run]# chmod 777 docker.sock

查看现在的权限

srwxrwxrwx  1 root   root      0 9月  11 16:07 docker.sock
srw-rw----  1 root   docker    0 9月  11 16:07 docker.sock.bak

再次编辑jenkins的docker-compose文件

jenkins_docker]# cat docker-compose.yaml
services:jenkins:image: jenkins/jenkins:latestcontainer_name: jenkinsenvironment:- TZ=Asia/Shanghaiports:- 8080:8080- 50000:50000volumes:- /data/jenkinsdata:/var/jenkins_home- /var/run/docker.sock:/var/run/docker.sock- /usr/bin/docker:/usr/bin/docker- /etc/docker/daemon.json:/etc/docker/daemon.json

重新加载一下

jenkins_docker]# docker-compose up -d
[+] Running 1/1✔ Container jenkins  Started                              

进入容器运行一下docker命令

jenkins_docker]# docker exec -it jenkins /bin/bash
jenkins@4146a6753382:/$ docker version
Client: Docker Engine - CommunityVersion:           26.1.4API version:       1.45Go version:        go1.21.11Git commit:        5650f9bBuilt:             Wed Jun  5 11:32:04 2024OS/Arch:           linux/amd64Context:           default

编辑shell,根据环境编写镜像生成的命令。

mv target/*.jar docker/
docker build -t datax-db:v1 docker/

构建这里选择一个执行 shell 编写如下命令

点击构建看到这边日志显示已经在打包了

服务器命令行查看镜像

docker]# docker images | grep datax
datax-db                        v1              792dba69b798   3 minutes ago   200MB

这边已经生成了镜像,再次把镜像推送到私有仓库

编辑刚才的shell窗口

mv target/*.jar docker/
docker build -t datax-db:v1 docker/
docker login -u admin -p Harbor12345 10.50.xxx.xxx:80
docker tag datax-db:v1 10.50.xxx.xxx:80/repo/datax-db:v1
docker push 10.50.xxx.xxx:80/repo/datax-db:v1

编辑填入shell窗口中

点击构建可以看到有日志输出了。

这边已经把镜像推送至仓库了。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于SpringBoot的在线点餐系统【附源码】
  • 【Unity设计模式】Unity MVC/MVP架构介绍,及MVC/MVP框架的简单应用
  • json格式互相转换
  • [论文笔记] 多语言配比的自动化超参搜索
  • 第三讲 part 2:LINK3D原理 - 代码 - 自定义内容
  • 【VUE】vue-router
  • 在虚幻引擎中实时显示帧率
  • 【计算机网络 - 基础问题】每日 3 题(二十)
  • nginx+keepalived健康检查案例详解(解决nginx出现故障却不能快速切换到备份服务器的问题)
  • 也遇到过 PIL Image “image file is truncated“的问题
  • 锤炼核心技能以应对编程革命
  • AndroidLogger插件使用技巧
  • JW01二氧化碳传感器(串行通信 STM32)
  • Linux:八种重定向详解(万字长文警告)
  • 低代码中实现数据映射的必要性与方案
  • Android 架构优化~MVP 架构改造
  • Angular 响应式表单 基础例子
  • ES2017异步函数现已正式可用
  • java 多线程基础, 我觉得还是有必要看看的
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • js对象的深浅拷贝
  • mysql外键的使用
  • opencv python Meanshift 和 Camshift
  • Puppeteer:浏览器控制器
  • uni-app项目数字滚动
  • Vue全家桶实现一个Web App
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 讲清楚之javascript作用域
  • 让你的分享飞起来——极光推出社会化分享组件
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 探索 JS 中的模块化
  • 学习HTTP相关知识笔记
  • 一些关于Rust在2019年的思考
  • No resource identifier found for attribute,RxJava之zip操作符
  • # Kafka_深入探秘者(2):kafka 生产者
  • # windows 安装 mysql 显示 no packages found 解决方法
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • (2)STM32单片机上位机
  • (c语言)strcpy函数用法
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (HAL库版)freeRTOS移植STMF103
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (SERIES10)DM逻辑备份还原
  • (接口封装)
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (五)关系数据库标准语言SQL
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)nsfocus-绿盟科技笔试题目
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • **CI中自动类加载的用法总结
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿