1.部署流程说明
记录了本地测试、上传代码到仓库,主要是为了完整的手动操作一遍,同时熟悉一下如何使用vscode来构建spring boot工程,具体过程是
1、vscode构建了两个spring boot工程
2、初始化工程获取本地maven库
3、上传本地库到maven私有库,同时配置快照库和发布库相关配置
4、手动单节点部署容器应用
5、手动部署容器应用到swarm集群
2.本地配置spring boot项目
因为要引入nacos实现服务注册与发现,需要写两个项目,一个注册服务,一个发现服务
2.1.注册服务
创建项目
vscode->ctrl+shift+p
删除demo文件,修改provider目录为controller,并创建相关代码
生成的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.teng</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建HelloWorldController.java
package com.teng.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController {
@GetMapping("/hello/{name}")
public String hello(@PathVariable String name) {
return "Hello " + name + " , Welcome to Nacos Discovery!!!";
}
}
创建ProviderController.java
package com.teng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
application.properties中配置nacos
server.port=8081
spring.application.name=nacos-discovery-provider
spring.cloud.nacos.discovery.server-addr=192.168.0.151:8848
spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
最终的目录结构
2.2.发现服务
创建项目
vscode->ctrl+shift+p
将上图中的consumer修改为controller,并删除demo文件
生成的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.teng</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建文件TestController.java
package com.teng.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping("/test")
public String test() {
// 通过spring cloud common中的负载均衡接口选取服务提供节点实现接口调用
ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-discovery-provider");
String url = serviceInstance.getUri() + "/hello/" + "xiaoliang";
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject(url, String.class);
}
}
创建ConsumerApplication.java
package com.teng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
application.properties中配置nacos
server.port=8082
spring.application.name=nacos-discovery-consumer
spring.cloud.nacos.discovery.server-addr=192.168.0.151:8848
spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos
management.endpoints.web.exposure.include=*
最终的目录结构
启动工程
访问工程
http://localhost:8082/test
查看nacos
访问http://192.168.0.151:8848/nacos
ps:启动工程有两种方式,直接F5开始调试或者根目录执行mvn clean install package生成jar包后执行java -jar 包名
3.上传maven本地库到私有库
3.1.获取本地库
开发人员本地首次mvn的时候肯定是从远端去下载依赖包,一般需要修改为国内的源这样构建会快一点
更换maven源为阿里云源,在maven的settings.xml里添加如下设置
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
pom.xml里添加配置
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
maven在打包时下载的包默认缓存在如下位置
也可以自定义缓存空间,maven配置文件settings.xml里设置
<localRepository>D:/maven_repository</localRepository>
3.2.创建私有库
访问http://192.168.0.152:8081
将其加入maven-public
3.3.上传本地库到私有库
构建完后,把本地缓存的所有库文件上传至可以连通nexus私服的主机上,创建一个目录比如repo,同时在该机器上安装maven、jdk,这些过程具体不细述,安装后根据前面部署的maven私服来给项目和maven添加一些配置
在maven全局配置settings中在如下地方添加
<mirror>
<id>maven-public</id>
<mirrorOf>*</mirrorOf>
<name>maven-public</name>
<url>http://192.168.0.152:8081/repository/maven-public/</url>
</mirror>
添加认证
<server>
<id>maven-public</id>
<username>waka2020</username>
<password>!QAZ1qaz</password>
</server>
<server>
<id>maven-releases</id>
<username>waka2020</username>
<password>!QAZ1qaz</password>
</server>
<server>
<id>maven-snapshots</id>
<username>waka2020</username>
<password>!QAZ1qaz</password>
</server>
pom.xml添加配置
<!-- 设置deploy的地址 -->
<distributionManagement>
<repository>
<id>maven-releases</id> <!--库的ID-->
<name>maven-releases</name> <!--库的名字-->
<url>http://192.168.0.152:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>maven-snapshot</name>
<url>http://192.168.0.152:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
在maven全局配置settings.xml里设置三个仓库(public releases sanpshots)的授权账号,同时设置私服地址为maven-public的地址,pom.xml里添加releases、snapshots仓库的地址,用于将本地的依赖包deploy到对应的仓库(maven-release、maven-sanpshots),注意deploy的包是通过mvn install命令下载缓存的jar包,不是package生成的jar包
进入repo,执行下面的导入脚本
cat import.sh
#!/bin/bash
# copy and run this script to the root of the repository directory containing files
# this script attempts to exclude uploading itself explicitly so the script name is important
# Get command line params
while getopts ":r:u:p:" opt; do
case $opt in
r) REPO_URL="$OPTARG"
;;
u) USERNAME="$OPTARG"
;;
p) PASSWORD="$OPTARG"
;;
esac
done
find . -type f -not -path './mavenimport\.sh*' -not -path '*/\.*' -not -path '*/\^archetype\-catalog\.xml*' -not -path '*/\^maven\-metadata\-local*\.xml' -not -path '*/\^maven\-metadata\-deployment*\.xml' | sed "s|^\./||" | xargs -I '{}' curl -u "$USERNAME:$PASSWORD" -X PUT -v -T {} ${REPO_URL}/{} ;
执行脚本
bash import.sh -u waka2020 -r http://192.168.0.152:8081/repository/maven-local/ -p !QAZ1qaz
查看maven-local
查看maven-public
3.4.发布自建工程到私有库
工程根目录执行
mvn deploy
其部署过程在下载包的时候按照的顺序是先从本地仓库下载,本地仓库没有就去私有库下载,私有库没有就去中央仓库下载,中央仓库下载后会缓存到私有库,最后可以在对应的snapshots库或releases库
找到上传的工程
4.发布应用
4.1.构建专用打包镜像
drwxr-xr-x. 6 root root 99 Jul 6 14:31 apache-maven-3.5.4
-rw-r--r--. 1 root root 8842660 Jul 6 14:29 apache-maven-3.5.4-bin.tar.gz
drwxr-xr-x. 7 root root 226 Jul 8 12:53 consumer
-rw-r--r--. 1 root root 970 Jul 8 11:15 Dockerfile
drwxr-xr-x. 7 10143 10143 245 Mar 12 14:37 jdk1.8.0_251
-rw-r--r--. 1 root root 195132576 Jul 6 14:29 jdk-8u251-linux-x64.tar.gz
drwxr-xr-x. 20 root root 4096 Jul 7 12:24 maven-local
drwxr-xr-x. 20 root root 4096 Jul 7 16:47 maven_repository
-rw-r--r--. 1 root root 117326527 Jul 7 02:25 maven_repository.zip
drwxr-xr-x. 6 root root 191 Jul 8 12:42 provider
-rw-r--r--. 1 root root 35140274 Jul 6 16:32 provider.zip
-rw-r--r--. 1 root root 10854 Jul 8 11:09 settings.xml
cat Dockerfile
FROM centos:7
MAINTAINER linuxwt <tengwanginit@gmail.com>
######更换163源######
RUN yum -y install wget \
gcc \
&& wget http://mirrors.163.com/.help/CentOS7-Base-163.repo \
&& mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak \
&& mv -f CentOS7-Base-163.repo /etc/yum.repos.d/CentOS-Base.repo \
&& yum makecache
######配置jdk#####
WORKDIR /usr
RUN mkdir /usr/local/java
ADD jdk-8u251-linux-x64.tar.gz /usr/local/java
RUN ln -s /usr/local/java/jdk1.8.0_251 /usr/local/java/jdk
ENV JAVA_HOME /usr/local/java/jdk
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH
###配置maven######
WORKDIR /usr
RUN mkdir /usr/local/maven
ADD apache-maven-3.5.4-bin.tar.gz /usr/local/maven
RUN ln -s /usr/local/maven/apache-maven-3.5.4 /usr/local/maven/maven
ADD settings.xml /usr/local/maven/maven/conf/settings.xml
ENV MAVEN_HOME /usr/local/maven/maven
ENV PATH ${MAVEN_HOME}/bin:$PATH
该镜像配置了maven私有仓库、jdk、maven
docker build -t soa-maven-jdk:v1 .
上传到docker私有仓库
docker tag soa-maven-jdk:v1 192.168.0.152:8082/soa-maven-jdk:v1
4.2.手动部署应用
同样是以服务注册和服务提供这两个工程为例
注册服务
total 12
-rw-r--r--. 1 root root 574 Jul 8 12:42 docker-compose.yml
-rw-r--r--. 1 root root 262 Jul 8 12:11 Dockerfile
-rw-r--r--. 1 root root 3065 Jul 7 16:28 pom.xml
drwxr-xr-x. 4 root root 30 Jul 5 13:47 src
drwxr-xr-x. 9 root root 241 Jul 7 16:47 target
构建应用镜像
cat Dockerfile
FROM 192.168.0.152:8082/soa-maven-jdk:v1 as build-stage
WORKDIR /usr/local/project
COPY . .
RUN mvn clean package
#####
FROM 192.168.0.152:8082/soa-maven-jdk:v1
WORKDIR /tmp
ENV TZ=Asia/Shanghai
COPY --from=build-stage /usr/local/project/target .
CMD ["java","-jar","provider-0.0.1-SNAPSHOT.jar"]
docker build -t provider:v1 .
cat docker-compose.yml
version: "3.4"
services:
provider:
image: provider:v1
networks:
- service_overlay
- monitor_overlay
- database_overlay
- elk_overlay
ports:
- 8083:8083
volumes:
- "/etc/localtime:/etc/localtime:ro"
deploy:
placement:
constraints: [node.hostname==node150]
restart_policy:
condition: any
delay: 5s
max_attempts: 3
networks:
service_overlay:
external: true
monitor_overlay:
external: true
database_overlay:
external: true
elk_overlay:
external: true
启动服务
docker stack deploy -c docker-compose.yml 150
发现服务
[root@node150 consumer]# ll
total 12
-rw-r--r--. 1 root root 593 Jul 8 15:24 docker-compose.yml
-rw-r--r--. 1 root root 299 Jul 8 15:20 Dockerfile
-rw-r--r--. 1 root root 2530 Jul 5 23:50 pom.xml
drwxr-xr-x. 4 root root 30 Jul 5 23:50 src
drwxr-xr-x. 9 root root 241 Jul 7 02:33 target
构建应用镜像
cat Dockerfile
FROM 192.168.0.152:8082/soa-maven-jdk:v1 as build-stage
WORKDIR /usr/local/project
COPY . .
RUN mvn clean package
#####
FROM 192.168.0.152:8082/soa-maven-jdk:v1
WORKDIR /tmp
ENV TZ=Asia/Shanghai
COPY --from=build-stage /usr/local/project/target .
CMD ["java","-jar","consumer-0.0.1-SNAPSHOT.jar"]
docker build -t consumer:v1 .
cat docker-compose.yml
version: "3.4"
services:
consumer:
image: consumer:v1
networks:
- service_overlay
- monitor_overlay
- database_overlay
- elk_overlay
ports:
- 8084:8084
volumes:
- "/etc/localtime:/etc/localtime:ro"
deploy:
placement:
constraints: [node.hostname==node151]
restart_policy:
condition: any
delay: 5s
max_attempts: 3
networks:
service_overlay:
external: true
monitor_overlay:
external: true
database_overlay:
external: true
elk_overlay:
external: true
启动服务前目标节点上需要部署用到的镜像
docker save consumer:v1 -o consumer.tar
scp consumer.tar 192.168.0.151:/root
远程至151节点
docker load -i consumer.tar
docker tag 上载的镜像的ID consumer:v1
启动服务
docker stack deploy -c docker-compose.yml 151
访问服务
http://192.168.0.151:8084/test