Docker部署普通的Java项目

介绍

说明

  docker部署项目基本都和springboot等后台项目绑定了,这边记录一下部署一个通过main函数启动的普通java项目的过程。

介绍

  项目的结构如下,后台的springboot将大任务划分,通过消息队列将划分的任务分配给子程序去执行,子程序功能相同,监听消息队列并处理数据,随后将处理后的数据发到结果队列中,后台统计结果。可以看到,子程序实际上只需要一直监听消息队列即可,有消息了处理消息就行,并没有接口访问,因此只需要一个普通的java项目即可,要部署的就是这些子程序。
在这里插入图片描述
  项目结构如下所示:
在这里插入图片描述

步骤

环境配置

安装java环境

  • 更新包索引:sudo apt update
  • 安装JDK:sudo apt install default-jdk或者其他版本的java
  • 环境变量:sudo nano /etc/environment,在文件末尾添加JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64",保存退出后重新加载环境变量:source /etc/environment
  • 验证安装:java -version

安装rabbitmq

  • 安装Erlang,RabbitMQ依赖Erlang,需要先安装Erlang。添加Erlang仓库:
sudo apt install -y curl gnupg apt-transport-https
curl -fsSL https://packages.erlang-solutions.com/ubuntu/erlang_solutions.asc | sudo apt-key add -
echo "deb https://packages.erlang-solutions.com/ubuntu $(lsb_release -sc) contrib" | sudo tee /etc/apt/sources.list.d/erlang.list
sudo apt update
sudo apt install -y erlang
  • 添加rabbitmq仓库:
curl -fsSL https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey | sudo apt-key add -
echo "deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/rabbitmq.list
sudo apt update
  • 安装rabbitmq:sudo apt install -y rabbitmq-server
  • 启动并启用RabbitMQ服务并设置为开机启动
sudo systemctl start rabbitmq-server
sudo systemctl enable rabbitmq-server
  • 启用RabbitMQ管理插件sudo rabbitmq-plugins enable rabbitmq_management
  • 验证安装
    打开http://localhost:15672/,如果出现rabbitmq的网站即成功,默认登录账号密码都是guest。
  • 配置防火墙,开启rabbitmq的端口
sudo ufw allow 5672
sudo ufw allow 15672
sudo ufw reload
  • 配置监听接口:rabbitmq默认只监听本地回环接口,为了使消息队列能通过网络访问,需要配置监听的网络接口。创建RabbitMQ配置文件sudo touch /etc/rabbitmq/rabbitmq.conf,添加内容:
listeners.tcp.default = 5672
management.listener.port = 15672
management.listener.ip = 0.0.0.0
  • 保证文件权限
sudo chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.conf
sudo chmod 640 /etc/rabbitmq/rabbitmq.conf
  • 重启服务:sudo systemctl restart rabbitmq-server
  • 验证,在其他电脑上访问http://ip:15672/,如果能出现网站说明成功。
  • 创建用户:默认用户只能通过localhost登录,需要创建用户:sudo rabbitmqctl add_user admin your_password,赋予权限:sudo rabbitmqctl set_user_tags admin administratorsudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

安装docker

  • 安装软件包:sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
  • 添加docker官方的秘钥:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  • 添加 Docker 仓库:```echo “deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable” | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null``
  • 更新软件包列表sudo apt update
  • 安装 Docker:sudo apt install -y docker-ce
  • 启动 Docker:sudo systemctl start docker,设置为开机自启动:sudo systemctl enable docker
  • 验证安装:sudo docker run hello-world,有输出Hello from Docker!说明安装成功,之后记得删除这个测试镜像。
  • docker常用命令
    • 列出镜像:sudo docker images
    • 拉取镜像:sudo docker pull <image_name>
    • 删除镜像:sudo docker rmi <image_name>
    • 列出运行容器:sudo docker ps
    • 列出所有容器:sudo docker ps -a
    • 启动容器:sudo docker start <container_id>
    • 停止容器:sudo docker stop <container_id>
    • 删除容器:sudo docker rm <container_id>

打包部署

将项目转为maven项目

  虽然可能会显得多此一举,我一开始也不想转,但是如果项目比较复杂,手动一个个打包实在是太麻烦了,而且很容易漏掉一些东西,因此还是需要转为maven后去打包会方便很多。另外为了方便我把配置文件写在代码里了,虽然不推荐这么做但我怕弄出问题,因为这种配置文件不像spring那样是自动管理的,这种自己创建的读取方法部署后很容易出问题。
  新建一个maven项目把原项目全部拷贝进去,然后将导入的外部依赖库通过pom的方式导入,如果依旧使用外部依赖库的情况下,可能会打包掉很多依赖。
  springboot项目中有spring-boot-maven-plugin,这个插件会打包所有依赖,但直接创建的maven项目是没有的,因此需要添加插件maven-shade-plugin,这个插件功能和spring-boot-maven-plugin类似,如果不添加,在打包的时候会漏掉依赖。

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

  设置启动类,由于是通过main函数启动的,如果不设置不会有默认的入口。

                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>Work</mainClass>  <!-- 设置启动类 -->
                        </manifest>
                    </archive>
                </configuration>

下面是针对我这个项目的所有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://www.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>Deployment</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.14.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.13.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.4</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>Work</mainClass>  <!-- 设置启动类 -->
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

打包项目为jar包

  依次点击clean、compile和package,生成target文件夹,其中有两个jar包,将上面那个不带origin的复制到ubuntu中,在同目录中创建文件Dockerfile,写入下面的内容。

# 使用OpenJDK作为基础镜像
FROM openjdk:8-jdk-alpine

# 创建并设置工作目录
WORKDIR /app

# 复制JAR文件到容器中
COPY depchild.jar app.jar

# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

项目部署

  • 构建Docker镜像:docker build -t message-service .
  • 运行Docker容器:docker run -d --name message-service --network host -e SOME_ENV_VAR=value message-service
      到此项目部署完成,如果docker ps -a命令有message-service但是docker ps没有,即说明执行出错了,可以通过命令docker logs my-message-service查看日志输出,如果原本的项目没有问题一般就是依赖或者网络的问题,确保所有依赖都被打包,确保网络端口放开能够访问。
      例如开始我有一次日志输出Exception in thread "main" java.lang.NoClassDefFoundError: com/rabbitmq/client/Consumer at Work.main(Work.java:7),说明是依赖问题,重新打包后通过命令jar tf target/Deployment-1.0-SNAPSHOT.jar | grep com/rabbitmq/client/Consumer来查看依赖是否正确打包,正确会输出com/rabbitmq/client/Consumer.class。
  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值