0%

构建SpringBoot基础项目

SDKMAN 环境安装

修改环境变量

1
2
3
4
#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
export SDKMAN_DIR="/home/user/.sdkman"
[[ -s "/home/user/.sdkman/bin/sdkman-init.sh" ]] && source "/home/user/.sdkman/bin/sdkman-init.sh"

使用命令

1
2
3
4
5
6
7
8
$ sdk version

SDKMAN 5.5.12+269

$ sdk install java
$ sdk install scala 2.12.1
$ sdk uninstall scala 2.11.6
$ sdk list groovy

创建Spring boot工程

通过Spring Starter来创建工程

  • 通过Eclipse MarketPlace安装Sprint Tools插件之后就可以通File-->New-->Project-->Spring Boot-->Spring Starter Project方式来创建工程,接着配置下面两个向导页面来完成工程的创建.

spring-starter-project.png

spring-starter-project-config.png

集成RabbitMQ

安装RabbitMQ

1
2
3
4
5
6
7
~$ echo "deb https://dl.bintray.com/rabbitmq/debian stretch main" | sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list

~$ wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -

~$ sudo apt-get update
~$ sudo apt-get install rabbitmq-server

配置插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
~$ sudo rabbitmq-plugins list
Configured: E = explicitly enabled; e = implicitly enabled
| Status: * = running on rabbit@pgsql
|/
[ ] rabbitmq_amqp1_0 3.7.7
[ ] rabbitmq_auth_backend_cache 3.7.7
[ ] rabbitmq_auth_backend_http 3.7.7
[ ] rabbitmq_auth_backend_ldap 3.7.7
[ ] rabbitmq_auth_mechanism_ssl 3.7.7
[ ] rabbitmq_consistent_hash_exchange 3.7.7
[ ] rabbitmq_event_exchange 3.7.7
[ ] rabbitmq_federation 3.7.7
[ ] rabbitmq_federation_management 3.7.7
[ ] rabbitmq_jms_topic_exchange 3.7.7
[ ] rabbitmq_management 3.7.7
[ ] rabbitmq_management_agent 3.7.7
[ ] rabbitmq_mqtt 3.7.7
[ ] rabbitmq_peer_discovery_aws 3.7.7
[ ] rabbitmq_peer_discovery_common 3.7.7
[ ] rabbitmq_peer_discovery_consul 3.7.7
[ ] rabbitmq_peer_discovery_etcd 3.7.7
[ ] rabbitmq_peer_discovery_k8s 3.7.7
[ ] rabbitmq_random_exchange 3.7.7
[ ] rabbitmq_recent_history_exchange 3.7.7
[ ] rabbitmq_sharding 3.7.7
[ ] rabbitmq_shovel 3.7.7
[ ] rabbitmq_shovel_management 3.7.7
[ ] rabbitmq_stomp 3.7.7
[ ] rabbitmq_top 3.7.7
[ ] rabbitmq_tracing 3.7.7
[ ] rabbitmq_trust_store 3.7.7
[ ] rabbitmq_web_dispatch 3.7.7
[ ] rabbitmq_web_mqtt 3.7.7
[ ] rabbitmq_web_mqtt_examples 3.7.7
[ ] rabbitmq_web_stomp 3.7.7
[ ] rabbitmq_web_stomp_examples 3.7.7
1
2
3
4
5
6
7
8
9
10
~$ sudo rabbitmq-plugins enable rabbitmq_management  rabbitmq_management_agent rabbitmq_event_exchange
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@pgsql...
The following plugins have been enabled:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch

创建管理用户

1
2
3
4
5
6
7
~# rabbitmqctl add_user lcy lcy123
Adding user "lcy" ...
~# rabbitmqctl set_user_tags lcy administrator
Setting tags for user "lcy" to [administrator] ...
~# rabbitmqctl set_permissions -p / lcy ".*" ".*" ".*"
Setting permissions for user "lcy" in vhost "/" ...

Maven 配置分析

spring-project-pom

##Maven使用

更改Maven仓库地址

  • 因为国情问题,做Java,Android开发会碰到联网编译很慢,或者直接不能编译的问题,解决此问题要么就是搭一个VPN,或者把仓库地址替换成国内的镜像地址.比如这里把Maven的仓库地址替换成阿里云的镜像.
1
2
3
4
5
6
7
8
9
10
~$ cat ~/.sdkman/candidates/maven/current/conf/settings.xml
[...]
<mirror>
<id>mirrorId</id>
<mirrorOf>*</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
[....]

编译工程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
~$ mvn compile  #在target目录生成目录结构
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building web-printer-servr 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ web-printer-servr ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 24 resources
[...]

~$ mvn package #在target目录下会生成jar包
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[...]
  • 如果出错如下,需要跳过test编译添加**-Dmaven.test.skip=true**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[...]
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR] DemoApplicationTests.contextLoads » IllegalState Failed to load ApplicationCon...
[INFO]
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 04:01 min
[INFO] Finished at: 2018-07-17T12:05:21+08:00
[INFO] Final Memory: 38M/327M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.21.0:test (default-test) on project demo: There are test failures.
~$ mvn package -Dmaven.test.skip=true

处理包的依赖冲突

1
~$ mvn dependency:tree -Dverbose -Dincludes=commons-collections

组合使用

  • 下面命令会执行 clean ,然后执行 dependency 插件的 copy-dependencies 目标(goal),最后执行 package 阶段.
1
~$ mvn clean dependency:copy-dependencies package

运行

  • 进入到工程目录下target/xxxx-SNAPSHOT.jar文件,就是最终运行部署的 jar 包.
1
2
3
4
5
6
7
8
9
10
11
~$ java -jar target/demo-0.0.1-SNAPSHOT.jar

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _`| \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)

2018-07-17 12:12:05.518 INFO 21595 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on debian with PID 21595 (/home/michael/workspace/demo/target/demo-0.0.1-SNAPSHOT.jar started by michael in /home/michael/workspace/demo)

配置文件

  • 工程目录下src/main/resources存放着工程的配置文件与一些资源文件.

数据库配置(MyBatis)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
~$ cat mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<typeAliases>
<typeAlias alias="UUID" type="java.util.UUID" />
<typeAlias alias="UUIDTypeHandler" type="lcy.printer.typehandlers.UUIDTypeHandler"/>
</typeAliases>

<typeHandlers>
<package name="lcy.printer.typehandlers" />
</typeHandlers>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://192.168.50.170:5432/web_printer_db"/>
<property name="username" value="postgres"/>
<property name="password" value="pass"/>
</dataSource>
</environment>
</environments>

<mappers>
<package name="lcy.printer.mapper"/>
</mappers>
</configuration>

###MyBatis代码生成器

  • generatorConfig.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<classPathEntry
location="postgresql-42.1.4.jar" />
<context id="PostgresqlContext" targetRuntime="MyBatis3Simple"
defaultModelType="flat">
<property name="autoDelimitKeywords" value="true" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="addRemarkComments" value="true" />
</commentGenerator>

<jdbcConnection connectionURL="jdbc:postgresql://192.168.1.120:5432/web_printer_db"
driverClass="org.postgresql.Driver" password="lcy123" userId="postgres" />
<javaModelGenerator targetPackage="lcy.printer.model"
targetProject="src/main/java">
<property name="trimStrings" value="true" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources" />
<javaClientGenerator targetPackage="lcy.printer.mapper"
targetProject="src/main/java" type="XMLMAPPER" />

<table tableName="users" delimitIdentifiers="true"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<generatedKey column="id" sqlStatement="JDBC" />
<columnOverride column="uuid" typeHandler="UUIDTypeHandler" />
</table>

<table tableName="printer_model" delimitIdentifiers="true">
<generatedKey column="id" sqlStatement="JDBC" />
</table>
[...]
</context>
</generatorConfiguration>

通过MyBatis自动生成代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
~$ mvn mybatis-generator:generate

#没有报错,就会根据数库表项与generatorConfig.xml配置生产下面三个目录的内容.
~$ tree src/main/java/lcy/printer/mapper
src/main/java/lcy/printer/mapper
├── AddressMapper.java
├── BindPrinterMapper.java
├── FactoryRecordMapper.java
├── PrinterClassMapper.java
├── PrinterHistoryMapper.java
├── PrinterLoginHistMapper.java
├── PrinterMapper.java
├── PrinterModelMapper.java
├── RolesMapper.java
├── UserLoginHistMapper.java
└── UsersMapper.java

~$ tree src/main/java/lcy/printer/model/
src/main/java/lcy/printer/model/
├── Address.java
├── BindPrinter.java
├── FactoryRecord.java
├── PrinterClass.java
├── PrinterHistory.java
├── Printer.java
├── PrinterLoginHist.java
├── PrinterModel.java
├── Roles.java
├── UserLoginHist.java
└── Users.java

~$ tree src/main/resources/mapper/
src/main/resources/mapper/
├── AddressMapper.xml
├── BindPrinterMapper.xml
├── FactoryRecordMapper.xml
├── PrinterClassMapper.xml
├── PrinterHistoryMapper.xml
├── PrinterLoginHistMapper.xml
├── PrinterMapper.xml
├── PrinterModelMapper.xml
├── RolesMapper.xml
├── UserLoginHistMapper.xml
└── UsersMapper.xml

工程参数配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
~$ cat application.properties
server.port=8090
server.address=0.0.0.0
server.session.cookie.max-age=2592000
server.session.timeout=86400

### rabbitmq ####
spring.rabbitmq.host=192.168.1.120
spring.rabbitmq.port=5672
spring.rabbitmq.password=xxxxx
spring.rabbitmq.username=yjdwbj
printer.control.exchange=printer.control
printer.control.routekey=xxxx123
printer.control.queue=printer.control.queue

spring.http.multipart.max-file-size=50MB
spring.http.multipart.max-request-size=50MB
spring.http.multipart.file-size-threshold=0
spring.http.multipart.location=/opt/data/

### redis ####
spring.session.store-type=redis
spring.redis.password=lcy123
spring.redis.host=192.168.1.120
spring.redis.port=6379

###自定义属性###
upload.image.dir=/opt/data/image
aeskey =liucy1591620xxxx
aesiv = 3c64d1381xxxxxx
[...]

  • 资源文件application.properties可以配置现有的模块参数之外,还可以自定义属性,在工程中可以使用注解@Value=(value=”${upload.image.dir}”)的方式,绑定到字符串使用.编译时直接编进到目标文件中,如果在运行目标文件时,想覆盖现有的属性(不重新编译的前提下),在目标文件目录下创建config目录及config/application.properties文件,在该文件中重新定义需要替换的属性字段,重新运行服务就能加载到最新属性值.
1
2
3
4
5
~$ tree
.
├── config
│   └── application.properties
└── target-xxxx-0.0.1-SNAPSHOT.jar

Spring Boot 与 Docker 整合

创建 Docker 基础镜像

Spring Boot 工程添加 Dockerfile

dockerfile-maven 插件

  • Dockerfile Maven

  • 按照上面网站上的说明,Dockerfile在创建在项目的顶级目录下,不是src/main/resources,示例如下:

1
2
3
4
5
6
a/
Dockerfile
pom.xml
b/
Dockerfile
pom.xml

###Docker Compose服务编排

  • Docker Compose
  • https://github.com/docker/compose
  • Compose 是一个用于定义并运行多容器Docker应用的工具.先通过一个compose文件来配置你的应用服务,然后用一个简单的命令就可以创建并启动所有的应用服务了.
    -Compose的特性:
    • 单主机多个隔离环境Compose使用项目名称来隔离各个环境.在不同的应用场景中使用这个特性:
      • 在开发机上,可以创建同一个环境的不同副本
      • 在CI服务器上,可以设置项目名为一个唯一的build ID,从而避免build时互相干扰
      • 在一个共享主机或开发机上,可能会存在相同服务名称的应用,通过这个特性可以避免互相干扰默认的项目名称是项目目录的目录名,可以通过-p 命令行选项或者COMPOSE_PROJECT_NAME指定.
    • 保存容器创建时使用的卷(volume)数据
    • 只重新创建已更改的容器
      -Compose会缓存用于创建容器的配置,当重启一个未曾更改过的服务时,Compose会重用已存在的容器.这意味着你可以很快地改变你的环境.
    • 支持变量,在不同的环境间定义不同的组合
  • 如果一个Spring Boot项目要用到RabbitMQ,Redis,PostgreSQL三个服务,如果用docker run的方式会比较烦杂,如果使用Docker Compose的方式,只需要写一个docker-compose.yml就能有组织创建,停止,删除这些要依赖到的容器服务了.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
~$ cat docker-compose.yml
version: "2"
services:
rabbitmq:
image: rabbitmq
container_name: amqp
ports:
- 5672:5672
- 15672:15672
- 25672:25672
environment:
RABBITMQ_DEFAULT_PASS: "rabbitmq"
RABBITMQ_DEFAULT_USER: "rabbitmq"
RABBITMQ_DEFAULT_VHOST: "/"
labels:
NAME: "rabbitmq1"
restart: always
volumes:
- ./docker-vol/rabbitmq/enabled_plugins:/etc/rabbitmq/enabled_pluings
command:
- /bin/sh
- -c
- |
rabbitmq-plugins enable rabbitmq_management rabbitmq_management_agent rabbitmq_event_exchange
rabbitmq-server -detached
sleep 10
echo "add new user............................"
rabbitmqctl add_user lcy lcy123
rabbitmqctl set_user_tags lcy administrator
rabbitmqctl set_permissions -p / lcy ".*" ".*" ".*"
rabbitmqctl stop
rabbitmqctl stop_app
rabbitmq-server

redis:
image: redis
container_name: redis
ports:
- 6379:6379
restart: always
command: redis-server --requirepass redis123

database:
image: postgres:9.6
container_name: pg96
ports:
- 5432:5432
volumes:
- ./docker-vol/postgresql/data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=pg123
- POSTGRES_USER=postgres
restart: unless-stopped
  • 启动Docker-Compose

    1
    2
    3
    4
    5
    ~$ docker-compose up -d
    Creating network "dockerbuild_default" with the default driver
    Creating amqp
    Creating redis
    Creating pg96
  • 停止并删除 Docker-Compose

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ~$ docker-compose down
    Stopping amqp ... done
    Stopping redis ... done
    Stopping pg96 ... done
    Removing amqp ... done
    Removing redis ... done
    Removing pg96 ... done
    Removing network dockerbuild_default

  • 如果需要进入Docker容器内查看与操作

    1
    ~$ docker exec -it pg96 /bin/bash

Docker集成

搭建本地Docker Registry

启动Docker Registry

1
~$ docker run -d -p 50000:5000 -v ~/docker-register:/tmp/registry registry
  • -d:表示将在后台启动该容器.
  • -p: 表示对容器中应用程序暴露的端口进行端口进行映射,50000为当前宿主机端口,5000为容器中要暴露的端口.
  • 启动后,通过浏览器访问http://127.0.0.1:50000/可以查看Docker Registry的内容.

推送镜像

1
~$ docker push 127.0.0.1:50000/lcy/java
  • 推送成功后,可以在本的磁盘上~/docker-registry找到Docker Registry的仓库与镜像文件.

创建PostgreSQL容器服务

1
2
3
4
5
6
7
8
9
10
11
12
docker pull postgres:9.6
Using default tag: latest
latest: Pulling from library/postgres
be8881be8156: Pull complete
[...]
3e8eac382462: Pull complete
Digest: sha256:d8011033f12f1cbb18807b423892605a506ba340e468b16a6446179a130f140d
Status: Downloaded newer image for postgres:9.6

docker run --name pgsql -dit -p 15432:5432 -e POSTGRES_USERNAME=postgres -e POSTGRES_PASSWORD=pg123 -e POSTGREE_DB=db_test -v ~/3TB-DISK/docker_backup/pgdata:/var/lig/postgresql/data postgres:9.6
f703a096c4eeda186cf24a540b412c304c9b687542c4fd3d1183266543719413

#Jenkins+GitLab集成配置

安装Jenkins

##Jenkins常用插件

  • Gitlab Hook Plugin
  • Build Authorization Token Root Plugin
1
~$ docker pull jenkinsci/jenkins

运行Jenkins

1
2
3
4
5
6
7
8
9
10
11
12
13
14
~$  docker run -d -p 9090:8080 -v ~/jenkins:/var/jenkins_home --name jenkins jenkinsci/jenkins

~$ docker logs -f jenkins
Running from: /usr/share/jenkins/jenkins.war
webroot: EnvVars.masterEnvVars.get("JENKINS_HOME")
[...]

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

743cb67494f5428e801093ed2416e359

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
[...]
  • 运行起来之后,通过宿主机浏览器访问http://127.0.0.1:9090/就会看到Jenkins提示输入密码访问,复制743cb67494f5428e801093ed2416e359输入就能进管理界面.

安装GitLab容器服务

-GitLab是由GitLab Inc.开发,使用MIT许可证的基于网络的Git仓库管理工具,且具有wikiissue跟踪功能.GitLab 由乌克兰程序员Dmitriy ZaporozhetsValery Sizov开发,它由Ruby写成.后来,一些部分用Go语言重写.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
~$ docker pull gitlab/gitlab-ce
Using default tag: latest
latest: Pulling from gitlab/gitlab-ce
[...]
6ee63ee02d04: Pull complete
Digest: sha256:5632b85c9f4201c7777e301b24c65957b41dceb29854993206d45101a0a542aa
Status: Downloaded newer image for gitlab/gitlab-ce:latest

~$ docker run -d -h gitlab.lcy.com -p 10022:22 -p 10080:80 -p 10443:443 -v ~/gitlab/etc:/etc/gitlab -v ~/gitlab/log:/var/log/gitlab -v ~/gitlab/opt:/var/opt/gitlab --name gitlab gitlab/gitlab-ce
7b7d4d8d7997190cd39c0adbe197c967d39ab82de26b512f864a70bb6f2a934e
~$ docker logs -f gitlab #查看容器gitlab的日志
[...]
Configure GitLab for your system by editing /etc/gitlab/gitlab.rb file
And restart this container to reload settings.
To do it use docker exec:
#按照这日志里的提示,可以修改gitlab的参数,并重启使其生效.
docker exec -it gitlab vim /etc/gitlab/gitlab.rb
docker restart gitlab

For a comprehensive list of configuration options please see the Omnibus GitLab readme
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md

If this container fails to start due to permission problems try to fix it by executing:

docker exec -it gitlab update-permissions
docker restart gitlab
[...]

Ran "bash" "/tmp/chef-script20180723-42-eebbkz" returned 1

Running handlers complete
Chef Client failed. 86 resources updated in 55 seconds
  • /etc/gitlab: 表示容器GitLab的配置目录,映射到宿主机的~/gitlab/etc
  • /var/log/gitlab: 表示容器GitLab的日志目录,映射到宿主机的~/gitlab/log
  • /var/opt/gitlab: 表示容器GitLab的数据目录,映射到宿主机的~/gitlab/opt

错误处理

  • 如果出现下面错误,尝试把/var/opt/gitlab映射去掉.
1
2
3
4
PG::ConnectionBad (could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/opt/gitlab/postgresql/.s.PGSQL.5432"?
):

使用GitLab容器服务

  • 安装GitLab容器之后,通过宿主机浏览器访问http://127.0.0.1:10080/管理页面,初次登录,修改完管理密码后,进入登录界面.到次,可以创建项目(Project),或者创建一个群组(Group).
  • 下面是创建新工程的界面,具体Git使用方法比如,克隆创库,推送代码等都会显示在上面.
    gitlab-mvn-project

Jenkins集成系统

  • 创建一个Jenkins构建任务,让它从GitLab容器服务上拉取源码,并能过Maven进行编译打包,最后将构建成功的程序包进行归档,这里的Jenkins服务与 GitLab 服务都是分别运在不同的Docker容器中,使用过程中,难免会遇到容器之间的通信问题.
    jenkins-git-error
  • 如上图所示,访问GitLab容器中的Git仓库地址出错.这里出错如果是容器间的域名出错,可以通过修改Jenkins容器的/etc/hosts指向正确的地址及端口.推荐的方法是添加--link选项启动Jenkins.
1
2
3
4
5
~$  docker run -d -p 9090:8080 \
-v ~/jenkins:/var/jenkins_home \
--link gitlab-ce:gitlab.lcy.com \
--name jenkins \
jenkinsci/jenkins

配置 Maven 构建

  • 源码管理,这里选择Git,Repository URL可以任意的Git仓库,不限于github.com,gitlab.com,私有仓库.Credentials列表,要通过右边的Add图标去添加不能认证方式,这里选择用户名与密码的验证方式.
  • Build区域中的Goal and options输入框中输入clean package -q,如要对Maven进行其它配置,可点开Advanced...配置.比如把跳过测试部分,点开Advanced...,在MAVEN_OPTS中写入-Dmaven.test.failure.ignore=false.
    jenkins-mvn-build
  • Post-build Actions选项中添加Archive the artifacts项,并填入**/target/*.jar,保存,回到项目的主面按Build Now手动执行构建.
    jenkins-mvn-project

自动构建

  • 我的需求是,当代码推送到GitLab后,将自动构建,这里选择Source Code Management -->Build Triggers-->Poll SCM-->选项,在Schedule的文本框里写入”H/5 * * * *“,这样Jenkins就会每隔5分种去检测源版本是否有改变,如果有改变就执行构建.
    jenkins-mvn-project
  • 另一种方式是使用WebHook的方式触发,这个不是轮询而是基于消息推送的,设置比较复杂.要使用到Personal Access Tokens以及GitLab项目中的Projects_xxx-->Settingss-->Integrations设置.
  • 创建 Personal Access Tokens
    jenkins-gitlab-ptokens

构建Docker镜像

jenkins-docker-shell

  • 在 Jenkins 项目中,可以添加pre-build,post-build的脚本,上图中的脚是在项目构建完成后,执行脚中功能.根据Dockerfile构建Docker镜像,并推送到Docker镜像的仓库中.但是如果使用的Jenkins镜像容器服务,就不能执行这些脚本了,因为Jenkins本身是在容器中运行,它是没有安装Docker工具.

  • Jenkins容器中运行Docker命令,按<<轻量微服务架构(上)>>有四个方案可选,以下方法各有利弊,可以根据实际情况自行选择:

    1. 不使用任何Jenkins镜像容器,而是在一个物理机安装JenkinsDocker服务.
    2. 不使用官方提供的Jenkins镜像,自己构建一个带有Docker服务的Jenkins的镜像.
    3. 使用Docker-in-Docker(DinD)方案,表示在Docker容器中可运行其它Docker容器,这两个容器之间是”父子关系统”,Docker Hub中提供了JenkinsDinD镜像.
    4. 使用Docker-outside-Docker(DooD)方案,表示在Docker容器中创建宿主机上的Docker容器,这两个容器之间是”兄弟关系统”,Docker Hub中提供了JenkinsDooD镜像.
  • Jenkins with DooD

  • Jenkins DinD

##GitLab CI/CD配置

相关概念

cicd_pipeline_infograph

  • Pipeline

    • 一次Pipeline其实相当于一次构建任务,里面可以包含多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程.任何提交或者Merge Request的合并都可以触发Pipeline.
  • Stages

    -Stages表示构建阶段,说白了就是上面提到的流程.我们可以在一次Pipeline中定义多个Stages,这些Stages会有以下特点:

    • 所有Stages会按照顺序运行,即当一个Stage完成后,下一个Stage才会开始只有当所有Stages完成后,该构建任务 (Pipeline) 才会成功如果任何一个Stage失败,那么后面的Stages不会执行,该构建任务 (Pipeline) 失败.
  • Jobs

    -Jobs表示构建工作,表示某个Stage里面执行的工作.我们可以在Stages里面定义个Jobs,这些Jobs会有以下特点:

    • 相同Stage中的Jobs会并行执行
    • 相同Stage中的Jobs都执行成功时,该Stage才会成功
    • 如果任何一个Job失败,那么该Stage失败,即该构建任务 (Pipeline) 失败

GitLab Runner

-GitLab Runner就是最终干活的角色,因为编译构建任务是要占用很多的系统资源的脏累活.GitLab CI是项目构建状态的管理者,如果把它安装在一起,肯定会影响GitLab的性能.
-GitLab Runner可以是虚拟机,VPS,物理主机,Docker容器,甚至一堆容器.GitLabGitLab Runner通过 API 通信,所以唯一的要求就是它们之间是要联网的.

1
2
3
4
5
6
7
8
9
~$ docker pull gitlab/gitlab-runner:latest
~$ docker run -dit \
--name gitlab-runner \
--restart always \
-v ~/gitlab-runner/config:/etc/gitlab-runner \
-v ~/gitlab-runner/run/docker.sock:/var/run/docker.sock \
--link gitlab-ce:gitlab \
gitlab/gitlab-runner:latest

注册 Runner

  • 打开 GitLab 的项目,打开Settings-->CI/CD-->Runners如下图所示:

gitlab-cicd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker exec -it gitlab-runner gitlab-ci-multi-runner register
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://192.168.1.100:10080/ #gitlab.com的仓库地址
Please enter the gitlab-ci token for this runner:
2g54sKrFyoQCFCzx-ytx     #如上图所示.
Please enter the gitlab-ci description for this runner:
[a7ed7fea90f2]: docker-runner01    #Runner服务器名称
Please enter the gitlab-ci tags for this runner (comma separated):
gitlab-runner,docker,springboot,java #Runner的标签,显示Runner的属性.
Registering runner... succeeded runner=2g54sKrF
Please enter the executor: virtualbox, docker+machine, docker-ssh+machine, docker, docker-ssh, parallels, shell, ssh, kubernetes:
docker  #这里是Docker
Please enter the default Docker image (e.g. ruby:2.1):
java:8 #默认容器镜像的文件.
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
  • 直接命令行注册
1
2
3
4
5
6
7
8
9
10
11
12
docker exec -it  gitlab-runner \
gitlab-ci-multi-runner register \
--non-interactive \
--url "http://192.168.1.100:10080/" \
--registration-token "2g54sKrFyoQCFCzx-ytx" \
--executor "docker" \
--docker-image alpine:3 \
--description "docker-runner" \
--tag-list "docker,springboog" \
--run-untagged \
--locked="false"

  • 经测试如果GitLab Runner是一个 Docker 容器服务的话,--executor "docker"就是一个DinD方式,CI 中的Pipelines无法进行下去,一直报错如下:
1
2
3
4
5
6
7
8
9
10
11
12
Running with gitlab-runner 11.1.0 (081978aa)
on docker-runner 2328c533
Using Docker executor with image java:8 ...
ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:1148:0s)
Will be retried in 3s ...
Using Docker executor with image java:8 ...
ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:1148:0s)
Will be retried in 3s ...
Using Docker executor with image java:8 ...
ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:1148:0s)
Will be retried in 3s ...
ERROR: Job failed (system failure): Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:1148:0s)

使用GitLab.com服务

登录Gitlab.com

1
2
# 如果直接docker login 就是登录到hub.docker.com
~$ docker login registry.gitlab.com

编译Docker镜像

  • 简单 Dockerfile
1
2
3
4
5
6
7
8
9
$ cat Dockerfile
FROM debian:stable
MAINTAINER "lcy"<yjdwbj@gmail.com>
ADD liblcyCaptcha.so /usr/local/lib
EXPOSE 8090
RUN apt-get update
RUN apt-cache search libjpeg
RUN apt-get install git openjdk-8-jre libpng16-16 libfreetype6 libfontconfig1 -y
CMD java -jar app.jar

推送镜像到 registry.gitlab.com

1
2
3
4
5
6
7
8
9
~$ docker build -t registry.gitlab.com/yjdwbj/web-srv .
~$ $ docker push registry.gitlab.com/yjdwbj/web-srv
The push refers to a repository [registry.gitlab.com/yjdwbj/web-srv]
d19e173b6135: Pushed
e91b9ff142c2: Pushed
27b4d9dc346a: Pushed
1421ffaa76d9: Pushed
latest: digest: sha256:b6104be5dd99c8d7de6174e785cd03ac1652c613f3b4cb22b06585f89aa4ce9f size: 1165

推送镜像到 hub.docker.com

-hub.docker.com网站类似github.com的功能一样,先要注册一个帐号,登录后创建一个容器仓库(private/public),之后就可以对仓库进行push或者pull等操作.

1
2
3
4
5
6
7
8
9
10
  # 新建一个tag指定需要推送的镜像.
~$ docker tag registry.gitlab.com/yjdwbj/web-srv yjdwbj/web-srv:v1.0
~$ docker push yjdwbj/web-srv
The push refers to a repository [docker.io/yjdwbj/web-srv]
d19e173b6135: Pushed
e91b9ff142c2: Pushed
27b4d9dc346a: Pushed
1421ffaa76d9: Mounted from library/debian
v1.0: digest: sha256:09a07d28fbbcc53eba9afced03235f3a791285a76b414cb964c00c1a35aa58e0 size: 1165

UML 插件扩展

UML 仓库

Papyrus

  • Papyrus 是一款可定制的 UML 工具,其往往以 Eclipse 插件的形式发布.目前,Papyrus 支持 UML 2.5,可以集成 SysML 1.1 和 SysML 1.4.

Papyrus 升级站点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Papyrus Photon (4.X.0)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/photon

Papyrus Oxygen (3.X.0)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/oxygen

Papyrus Neon (2.0.X)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/neon

Papyrus Mars (1.1.X)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/mars

Papyrus Luna (1.0.X)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/luna

Papyrus Kepler (0.10.X)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/kepler

Papyrus Juno (0.9.2)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/juno

Papyrus Indigo (0.8.2)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/indigo

Papyrus Helios (0.7.3)
http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/helios

Papyrus User Guide

  • 注意:Papyrus 包逆向生成 Papyrus 类图需要安装GMF的支持.

PlantUML

  • PlantUml是一个支持快速绘制的开源项目.其定义了一套完整的语言用于实现 UML 关系图的描述.并基于强大的 graphviz 图形渲染库进行 UML 图的生成.绘制的 UML 图还可以导出为图片,以及通用的矢量 SVG 格式文件.

yED

  • yEd 是一款基于 Java 的流程图绘制软件,把它归类于这里是因为 yEd 是基于 Java 开发的,且功能非常丰富,UML 作图只是它的一种功能.与它功能高度重合的开源绘图件还有Dia可供选择.不过看了 Dia 网站好像它的版本很久没有更新了.

谢谢支持