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

docker compose启动springcloud微服务案例

gitee案例仓库入口

安装docker与docker compose

1.ubantu安装docker

# 更新 apt 包索引,输入以下命令:
sudo apt-get update
# 安装docker依赖,因为docker想在ubuntu系统运行起来还需要依赖一些别的环境
sudo apt-get install ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
sudo curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 添加Docker软件源
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 安装docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 启动docker
service docker start
# 配置docker服务开机自启
systemctl enable docker
# 配置docker加速器
# 执行下面命令
sudo mkdir -p /etc/docker
# 再接着执行
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://mu03bz48.mirror.aliyuncs.com"]
}
EOF
# 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker

如果无法拉取镜像用这个

sudo tee /etc/docker/daemon.json <<-'EOF'
{
     "registry-mirrors": [
         "https://do.nark.eu.org",
         "https://dc.j8.work",
         "https://docker.m.daocloud.io",
         "https://dockerproxy.com",
         "https://docker.mirrors.ustc.edu.cn",
         "https://docker.nju.edu.cn"
     ]
}
EOF

离线安装docker compose
github下载安装包,我下载的是v2.30.版本

https://github.com/docker/compose/releases

在这里插入图片描述

# 复制 Docker-Compose 到 /usr/local/bin
sudo cp -f ./docker-compose-linux-x86_64 /usr/local/bin/docker-compose
# 赋予 Docker-Compose 执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 查看docker-compose版本
docker-compose -v

开始创建微服务项目

最终的项目结构:
在这里插入图片描述

首先创建一个父工程

在这里插入图片描述
删除多余文件,只需要pom.xml下载依赖
在这里插入图片描述
对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>
    <groupId>com.family</groupId>
    <artifactId>springclouddemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!--    子模块引入 product eureka gateway-->
    <modules>
        <module>product</module>
        <module>eureka</module>
        <module>gateway</module>
    </modules>
    <name>springclouddemo</name>
    <packaging>pom</packaging>
    <description>Demo project for Spring Boot</description>
     <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
        <spring-cloud.version>2021.0.5</spring-cloud.version>
        <eureka-server.version>3.1.4</eureka-server.version>
        <eureka-client.version>3.1.4</eureka-client.version>
        <mysql.version>8.0.33</mysql.version>
        <!-- 注意点:这里用变量声明版本,标签必须有.version作为后缀:比如mysql.version不能定义为<mysql></mysql>-->
    </properties>
      <dependencies>
			<!--公共依赖,在这里声明的依赖,子模块默认会继承-->
    </dependencies>

    <dependencyManagement>
    	<!--在 dependencyManagement里面声明的依赖,子类需要再显示声明一遍,才能下载下来,只是不用写版本号了,由这里统一控制-->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
             <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
                 <version>${eureka-server.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
                <version>${eureka-client.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>


        </dependencies>
    </dependencyManagement>
<!-- maven编译插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

创建eureka模块

在这里插入图片描述
在这里插入图片描述重写eureka模块的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
         <!-- 依赖父工程 parent -->
    <parent>
        <artifactId>springclouddemo</artifactId>
        <groupId>com.family</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka</artifactId>
<!--采用jdk8 -->
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
    <!-- 引入依赖eureka-server:不用指定版本,因为父工程限定了-->
        <dependency>
           <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
</dependencies>
<!-- 指定编译后的jar包名称 finalName-->
    <build>
        <finalName>eureka</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

在这里插入图片描述
启动类添加注解@EnableEurekaServer
在这里插入图片描述
编写application.yaml文件

spring:
  application:
    name: eureka-server

server:
  port: 8700 #服务注册中心端口号
eureka:
  instance:
    hostname: eureka-server #服务注册中心IP地址
  client:
    registerWithEureka: false #是否向服务注册中心注册自己
    fetchRegistry: false #是否检索服务
    serviceUrl: #服务注册中心的配置内容,指定服务注册中心的位置
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 这里defaultZone:http://eureka-server:8700/eureka/ 请求eureka注册,原本http后面eureka-server是ip的,
      # 但因为是采用docker compose启动,所以ip可以用服务名代指

编写Dockerfile编写镜像

FROM openjdk:8
# 安装 ping 工具
RUN apt-get update && apt-get install -y iputils-ping
COPY ./eureka.jar /tmp/eureka.jar
ENTRYPOINT ["java","-jar","/tmp/eureka.jar"]
EXPOSE 8700

编写docker-compose.yaml文件启动

version: '3'
services:
  eureka-server:			# 注意此处的名称需要添加到eureka客户端的defaultZone中,相当于docker内的主机名
    build:
      context: ./eureka     #编译的dockerfile位置,路径在下面图片有说
    ports:
      - "8700:8700"        # 对外访问端口
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8700/eureka/" ] # 健康检查接口
      interval: 30s
      timeout: 10s
      retries: 3
  product-server:
    build:
      context: ./product
    ports:
      - "8701:8701"
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8701/actuator/health" ]
    depends_on:
      - eureka-server
  gateway-server:
    build:
      context: ./gateway
    ports:
      - "8082:8082"
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8082/actuator/health" ]
    depends_on:       # depends_on依赖于其他服务,保证eureka-server先启动,再启动gateway-server
      - eureka-server

我这里编写docker compose文件里面的build构建镜像地址都是相对的。
创建了myapp目录,里面有eureka目录,gateway目录,product目录,docker-compose.yaml文件
eureka目录放jar包和dockerfile文件
gateway目录放jar包和dockerfile文件和wait-for-it.sh脚本(被我改名为wait.sh)
product目录放jar包和dockerfile文件wait-for-it.sh脚本(被我改名为wait.sh)
在这里插入图片描述
在这里插入图片描述

创建product服务

注册进eureka服务中心
老样子,创建一个模块,更改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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springclouddemo</artifactId>
        <groupId>com.family</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>product</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

启动类添加注解:
@EnableEurekaClient
@EnableDiscoveryClient
在这里插入图片描述
创建一个接口hello,后面测试用
在这里插入图片描述
product服务的application.yaml配置

spring:
  application:
    name: product-server
server:
  port: 8701

eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8700/eureka/  #此处的eurakaserver为docker-compose.yml中eureka-server工程的容器定义
  instance:
    prefer-ip-address: true	# 使用IP注册,避免容器id:port调用报错

product服务的dockerfile文件

FROM openjdk:8
# 安装 Bash
RUN apt-get update && apt-get install -y bash
# 安装 curl 工具
RUN apt-get update && apt-get install -y curl
# 安装 ping 工具
RUN apt-get update && apt-get install -y iputils-ping
# 复制 JAR 文件
COPY ./product.jar /tmp/product.jar
# 复制 start.sh 脚本
COPY wait.sh /tmp/wait.sh
# 赋予 start.sh 脚本执行权限
RUN chmod +x /tmp/wait.sh
# 设置默认的环境变量
ENV EUREKA_URL=http://eureka-server:8700
# 启动命令
# 默认启动命令
CMD ["bash", "/tmp/wait.sh"]
# 暴露端口
EXPOSE 8701

需要product服务的wait.sh文件,
因为dockercompose的depends_on只能决定那个服务先启动,但是发生请求注册时接口还没准备好,此时刚启动项目就会报错。
比如报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

#!/bin/bash

# 获取环境变量,默认值为 eurekaserver:8701
EUREKA_URL=${EUREKA_URL:-http://eureka-server:8700}

echo "Starting wait script..."

# 检查网络连接:eureka-server:docker-compose.yaml配置的服务名及ip
if ! ping -c 1 eureka-server &> /dev/null; then
  echo "eureka-server is not reachable"
  exit 1
fi

while :
do
    # 访问 eureka 注册中心,获取 HTTP 状态码
    CODE=$(curl -I -m 10 -o /dev/null -s -w %{http_code} $EUREKA_URL)
    # 判断状态码为 200
    if [[ $CODE -eq 200 ]]; then
        # 输出绿色文字,并跳出循环
        echo -e "\033[42;34m $EUREKA_URL is ok \033[0m"
        break
    else
        # 暂停 1 秒
        sleep 1
        echo "EUREKA_URL $EUREKA_URL is not available yet, status code: $CODE"
    fi
done

echo "EUREKA_URL is available, starting product service..."
# 准备好后再启动product的jar包,保证不会刚启动报错
exec java -jar /tmp/product.jar

开始测试:
在这里插入图片描述
将jar包,dockerfile,docker-compose,wait.sh放到相应位置
在这里插入图片描述
eureka目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
cd 切换到docker-compose.yaml服务器的位置
docker compose up
在这里插入图片描述
有可能会启动失败,提供几条调试日志命令查看:
验证网络配置:
使用 docker network ls 命令检查网络列表,确保默认网络 myapp_default 已经创建。
在这里插入图片描述
使用 docker inspect myapp_default 命令检查网络配置,确保 eureka-server 和 product-service 都连接到了这个网络。

查看 eureka-server 的日志,确认是否有任何启动错误或异常信息
docker-compose logs eureka-server
docker-compose logs product-server
首先,确保 eureka-server 服务已经启动并运行正常。可以通过以下命令检查容器状态:
docker-compose ps
确保 product-service 可以通过 eureka-server 的主机名访问到 Eureka 服务。可以在 product-service 容器中运行以下命令:
docker exec -it product-service /bin/sh
再接着在容器内执行请求
curl http://eureka-server:8700/eureka/

下一步整合gateway服务

老样子:新建模块gateway,重写pom.xml

<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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.family</groupId>
        <artifactId>springclouddemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>gateway</artifactId>
    <name>gateway</name>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.1.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>gateway</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

编写application文件–gateway

server:
  port: 8082
eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8700/eureka/  #此处的eurakaserver为docker-compose.yml中eureka-server工程的容器定义
  instance:
    prefer-ip-address: true	# 使用IP注册,避免容器id:port调用报错
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
      routes:
        - id: product-server
          uri: lb://product-server
          predicates:
            - Path=/hello/**

dockerfile文件—gateway的

FROM openjdk:8
# 安装 Bash
RUN apt-get update && apt-get install -y bash
# 安装 curl 工具
RUN apt-get update && apt-get install -y curl
# 安装 ping 工具
RUN apt-get update && apt-get install -y iputils-ping
# 复制 JAR 文件
COPY ./gateway.jar /tmp/gateway.jar
# 复制 start.sh 脚本
COPY wait.sh /tmp/wait.sh
# 赋予 start.sh 脚本执行权限
RUN chmod +x /tmp/wait.sh
# 设置默认的环境变量
ENV EUREKA_URL=http://eureka-server:8700
# 启动命令
# 默认启动命令
CMD ["bash", "/tmp/wait.sh"]
# 暴露端口
EXPOSE 8082

编写wait,sh

#!/bin/bash

# 获取环境变量,默认值为 eurekaserver:8701
EUREKA_URL=${EUREKA_URL:-http://eureka-server:8700}

echo "Starting wait script..."

# 检查网络连接
if ! ping -c 1 eureka-server &> /dev/null; then
  echo "eureka-server is not reachable"
  exit 1
fi

while :
do
    # 访问 eureka 注册中心,获取 HTTP 状态码
    CODE=$(curl -I -m 10 -o /dev/null -s -w %{http_code} $EUREKA_URL)
    # 判断状态码为 200
    if [[ $CODE -eq 200 ]]; then
        # 输出绿色文字,并跳出循环
        echo -e "\033[42;34m $EUREKA_URL is ok \033[0m"
        break
    else
        # 暂停 1 秒
        sleep 1
        echo "EUREKA_URL $EUREKA_URL is not available yet, status code: $CODE"
    fi
done

echo "EUREKA_URL is available, starting product service..."
# 修改启动的jar包,应该要启动gateway.jar,不是product.jar了,上面不用动
exec java -jar /tmp/gateway.jar

最后的docker-compose.yaml文件就长这样了

version: '3'
services:
  eureka-server:			# 注意此处的名称需要添加到eureka客户端的defaultZone中,相当于docker内的主机名
    build:
      context: ./eureka
    ports:
      - "8700:8700"
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8700/eureka/" ]
      interval: 30s
      timeout: 10s
      retries: 3
  product-server:
    build:
      context: ./product
    ports:
      - "8701:8701"
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8701/actuator/health" ]
    depends_on:
      - eureka-server
  gateway-server:
    build:
      context: ./gateway
    ports:
      - "8082:8082"
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8082/actuator/health" ]
    depends_on:
      - eureka-server

编译打包测试:

上面有说打成jar包步骤,放到对应目录,docker compose up (有坑,没有自动重新编译)
但有可能启动的是旧的镜像,所以先执行docker compose build
再接着执行docker compose up
或者提供另一种方案:
docker images
docker rmi 镜像名称(这里有可能不能删除,提示有容器,需要先删除容器docker rm 容器id,再执行删除镜像)
docker rm 容器id
再执行docker compose up 就不会有缓存,且编译完后自动启动容器,等待即可!!!

访问:http://虚拟机IP:8700/
无需加/eureka后缀
在这里插入图片描述
两个实例也注册到eureka中了,访问gateway的网关
在这里插入图片描述

在这里插入图片描述
完美收官!!!


http://www.kler.cn/a/412529.html

相关文章:

  • MQ高级2:MQ的可靠性
  • 【作业九】RNN-SRN-Seq2Seq
  • springboot+redis+lua实现分布式锁
  • python3 自动更新的缓存类
  • [SWPUCTF 2021 新生赛]error
  • Redis 可观测最佳实践
  • 数据结构 (13)串的应用举例
  • Day50 | 动态规划 :线性DP 最大子数组和不同的子序列
  • 如何启用本机GPU硬件加速猿大师播放器网页同时播放多路RTSP H.265 1080P高清摄像头RTSP视频流?
  • 阿里发布 EchoMimicV2 :从数字脸扩展到数字人 可以通过图片+音频生成半身动画视频
  • Android.mk里如何指定编译模块的输出路径
  • Day47 | 动态规划 :线性DP 最长公共子序列最长公共子数组
  • 解决 IDEA 突然出现 unresolved class reference 问题
  • 网络模型(四层)--应用层(http), 传输层(TCP,UDP),网络层(ip),数据的流转
  • 人工智能之数学基础:向量的范数
  • pnpm的menorepo项目配置eslint和prettier
  • setter方法注入(Java EE 学习笔记07)
  • 大工C语言作业答案
  • 【软考速通笔记】系统架构设计师⑥——数据库设计基础知识
  • go-学习
  • ThingsBoard规则链节点:GCP Pub/Sub 节点详解
  • 关闭AWS账号后,服务是否仍会继续运行?
  • vue3 多种方式接受props,定义ref,reactive
  • 如何做好一份技术文档
  • [代码随想录Day24打卡] 93.复原IP地址 78.子集 90.子集II
  • 城电科技|三轴光伏太阳花 建设零碳新园区