微服务开发打包以及部署上线(工作必知)

我们在开发做软件的时候,一般是微服务框架,那么怎么实现将微服务各个模块部署到服务器呢,今天就写一个小案例实现,看完之后类别工作中的项目部署就差不多理解了

1.创建数据库,开发本质就是对数据进行操作,数据库创建很重要,怎么保证查询等不需要多张表进行关联查询提高速度呢,可以根据mybatis的一对多和多对多加上业务需求配置字段

2.编写主逻辑,根据对数据库的操作编写逻辑,这些需要java后端自己编写接口操作数据库

3.打包部署,将程序打包为jar包制作成镜像运行在多台服务器上,前端部署在nginx中,处理发送的请求操作数据库

参考文章:SQL的逻辑和优化(面试必知)_sql实现逻辑差-CSDN博客

创建微服务项目和单体配置需要改一下,如下

首先固定springcloud服务版本,在最外层pom.xml文件如下

<!-- 锁定SpringBoot版本 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- 这是一个空元素,表示Maven应该从哪里查找父项目的配置信息。当它为空时,Maven会从仓库中查找父项目。如果你将此元素设置为具体的路径,Maven将从指定的相对路径中查找父项目的pom.xml文件 -->
    </parent>

    <groupId>com.dabalmao</groupId>
    <artifactId>Dabalmao-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Dabalmao-cloud</name>
    <description>Dabalmao-cloud</description>
    <packaging>pom</packaging>

 <!-- 锁定SpringCloud、SpringCloudAlibaba 版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.7.RELEASE</version>
                <type>pom</type>
                <scope>import</scope><!--这两个表示是微服务的pom导入子类模块中-->
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR12</version>
                <type>pom</type>
                <scope>import</scope><!--这两个表示是微服务的pom导入子类模块中-->
            </dependency>
        </dependencies>
    </dependencyManagement>

以上规定版本为2.3.12,接下来在子模块中pom文件继承最外层pom文件,如下

 <parent>
        <!--最外层父类pom文件地址,名称版本等-->
        <groupId>com.dabalmao</groupId>
        <artifactId>Dabalmao-cloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <!--指向最外层父类文件进行打包-->
        <relativePath>../pom.xml</relativePath>
    </parent>
    <packaging>jar</packaging>

最外层pom文件为pom形式,模块为jar包形式

怎么写我就不过多解释了,在每个模块依赖配置写代码即可,博客上都有,不会也可以gpt查询即可(省略......)

3.接下来写接口,我在服务Module1和服务Module2两个微服务模块分别向同一个redis添加数据

e37c56bc56a741b5a4bd40880dc9b1df.png

测试如下

b8859c811a6b439a8189bd8c22c6ad08.png


ef1e04850a9a4718801897373fcb89b1.png

redis中dabalmao1键添加成功 

dfaee8ce08624edca9bf73679982a600.png


924b7ccb10d240c084d37dc1d880f5ca.png

redis中dabalmao2键添加成功 

测试成功后进行打包

f9dff14cf656437c8a967ccdf62ce123.png

打包成功,java-jar测试

现在服务如下,Module1:8081; Module2:8082  接下来将jar包上传部署到服务器

参考Java微服务轻松部署服务器_java 微服务项目 怎么快速在单机部署?-CSDN博客即可

现在工作中一般可视化即可如下1Panel - 现代化、开源的 Linux 服务器运维管理面板官网查看即可,今天从零部署

将两个服务jar包制作成镜像的Dockerfile分别为

项目1:
FROM openjdk:8
# 将jar1.jar复制到镜像中的工作目录
COPY Module1-0.0.1-SNAPSHOT.jar /dabaimao/module1/Module1-0.0.1-SNAPSHOT.jar
# 设置工作目录
WORKDIR /dabaimao/module1
# 暴露端口
EXPOSE 8081
#定义时区参数
ENV TZ=Asia/Shanghai
# 设置时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
# 运行jar文件
CMD java -jar Module1-0.0.1-SNAPSHOT.jar

项目2:
FROM openjdk:8
# 将jar1.jar复制到镜像中的工作目录
COPY Module2-0.0.1-SNAPSHOT.jar /dabaimao/module2/Module2-0.0.1-SNAPSHOT.jar
# 设置工作目录
WORKDIR /dabaimao/module2
# 暴露端口
EXPOSE 8082#定义时区参数
#定义时区参数
ENV TZ=Asia/Shanghai
# 设置时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
# 运行jar文件
CMD java -jar Module2-0.0.1-SNAPSHOT.jar

将两个服务制作成镜像之后如下

启动访问测试一下,测试成功

先启动依赖容器,比如中间件redis,mq,我这边只用到了redis

version: '3'
services:
  redis:
    image: daocloud.io/library/redis:5.0.7
    ports:
      - "6379:6379"
    environment:
      - REDIS_PASSWORD=123456

 启动成功

接下来使用docker-compose同时启动两个服务:

version: '3.3'

services:
  # my-module1 服务配置
  my-module1:
    image: my-module1:1.0
    ports:
      - "18081:8081"
    networks:
      - my-network

  # my-module2 服务配置
  my-module2:
    image: my-module2:1.0
    ports:
      - "18082:8082"
    networks:
      - my-network

  # Nginx 服务配置
  my-nginx:
    image: daocloud.io/library/nginx:latest
    ports:
      - "8080:80"
    networks:
      - my-network

networks:
  my-network:
    driver: bridge

启动成功

测试如下

39eaa3854eff4686a38b1e18ed82d182.png


c8d75dce19bb42909f1e034d3f9516d8.png

redis中dabalmao1键添加成功


7fbe185f8828410595a1006070be0fe9.png

redis中dabalmao2键添加成功

脚本为

cd /dabaimao/redis #redis的docker-compose.yml文件路径
docker-compose up -d #启动redis镜像
cd /dabaimao #module1和module2两个服务的docker-compose.yml文件路径
docker-compose up -d #启动两个服务
#####################没有docker可以使用脚本java-jar启动

这样就可以了,但是再次之前一般需要两个docker-compose.yml文件,先启动比如mysql,redis,mq之类的依赖服务,在启动逻辑服务,可以网络进行连接

3.nginx部署前端代码

我这边用gpt自动生成另一个前端网页,localhost表示同一个网络,127.0.0.1表示本地主机,一般使用内网ip即可,这里连的是同一个网络所以用localhost

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Redis 接口测试</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
        <!--'把bg1.jpg放到/usr/share/nginx/html容器路径下即可访问!'-->
        background: url('/bg1.jpg') center/cover no-repeat;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            color: #333;
        }

        h1 {
            margin-bottom: 20px;
            text-align: center;
        }

        button {
            margin: 10px;
            padding: 10px 20px;
            background-color: #3498db;
            color: #fff;
            border: none;
            cursor: pointer;
            border-radius: 5px;
        }

        button:hover {
            background-color: #2980b9;
        }

        #result1, #result2 {
            margin-top: 20px;
            max-width: 400px;
            padding: 10px;
            background-color: rgba(255,255,255,0.7);
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
<h1>Redis 接口测试</h1>
<button id="button1">获取接口1结果</button>
<button id="button2">获取接口2结果</button>
<div id="result1"></div>
<div id="result2"></div>

<script>
    document.getElementById('button1').addEventListener('click', function() {
        // 创建一个新的 XMLHttpRequest 对象
        var xhr = new XMLHttpRequest();
        // 配置请求
        xhr.open('GET', 'localhost:18081/dabalmao/toRedis', true);
        // 设置请求完成后的回调函数
        xhr.onload = function() {
            if (xhr.status >= 200 && xhr.status < 300) {
                // 请求成功时,将返回的数据插入到页面上
                document.getElementById('result1').innerHTML = xhr.responseText;
            } else {
                // 请求失败时,显示错误信息
                document.getElementById('result1').innerHTML = 'Error: ' + xhr.statusText;
            }
        };
        // 设置请求失败时的回调函数
        xhr.onerror = function() {
            // 请求失败时,显示错误信息
            document.getElementById('result1').innerHTML = 'Network error';
        };
        // 发送请求
        xhr.send();
    });

    document.getElementById('button2').addEventListener('click', function() {
        // 创建一个新的 XMLHttpRequest 对象
        var xhr = new XMLHttpRequest();
        // 配置请求
        xhr.open('GET', 'localhost:18082/dabalmao/toRedis', true);
        // 设置请求完成后的回调函数
        xhr.onload = function() {
            if (xhr.status >= 200 && xhr.status < 300) {
                // 请求成功时,将返回的数据插入到页面上
                document.getElementById('result2').innerHTML = xhr.responseText;
            } else {
                // 请求失败时,显示错误信息
                document.getElementById('result2').innerHTML = 'Error: ' + xhr.statusText;
            }
        };
        // 设置请求失败时的回调函数
        xhr.onerror = function() {
            // 请求失败时,显示错误信息
            document.getElementById('result2').innerHTML = 'Network error';
        };
        // 发送请求
        xhr.send();
    });
</script>


</body>
</html>

启动nginx指令

docker run -d -p 8080:80 --name my-nginx daocloud.io/library/nginx:latest

进入nginx指令

docker exec -it ae6fe44888f9 /bin/bash

找到nginx配置文件`/etc/nginx/conf.d/default.conf`,修改配置

 静态文件把bg1.jpg放到/usr/share/nginx/html容器路径下即可访问

server {
    # 前端程序运行端口
    # 注释:前端程序运行端口
    listen       80;
    # 前端程序运行ip
    # 注释:前端程序运行ip
    server_name  localhost;
    # 前端代码,vue使用dist,需要index.html会开头
    # 注释:前端代码,vue使用dist,需要index.html会开头
    root         /usr/share/nginx/html;
 
    # 加载配置文件以使用默认服务器块。
    # Load configuration files for the default server block.
    # 注释:加载配置文件以使用默认服务器块。
    include /etc/nginx/default.d/*.conf;
 
    location / {
        proxy_pass http://jar;
        #通过代理转到jar进行负载均衡
    }
    
    location / {
    #动静分离
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }    

    location ~* \.(gif|jpg|png|js|css|html)$ {
        # 匹配以gif|jpg|png|js|css|html为结尾的路径 静态资源
        root /usr/share/nginx/statics;
    }
 
    error_page 404 /404.html;
        location = /40x.html {
        # 如果请求的错误页面是404,则返回404.html文件。
        # 如果请求的错误页面是40x.html,则不做任何处理。
        # 注释:如果请求的错误页面是404,则返回40x.html文件。
        # 如果请求的错误页面是50x.html,则不做任何处理。
    }
 
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        # 如果发生5xx错误,例如500内部服务器错误,则返回50x.html文件。
        # 如果请求的错误页面是50x.html,则不做任何处理。
        # 注释:如果发生错误,例如内部服务器错误,则返回5xx.html文件。
    }
}
Upstream jar{
#负载均衡
  #  server 192.168.30.137:18080
  #  server 192.168.30.137:18081
}

修改完成后重新加载配置

nginx -s reload

访问Nginx本地8080端口http://192.168.30.137:8080,展示前端页面如下(一般这种情况放置网关)

查看redis数据库

redis中dabalmao1键添加成功 

 redis中dabalmao2键添加成功,最后访问成功

在工作中部署项目到服务器一般分为以下几步

1. 将前端代码部署在公网IP的服务器上,并通过域名或公网IP来访问前端应用
2. 将后端代码部署在内网IP的服务器上,服务器之间通过内网IP进行通信,以减少网络延迟和提高数据传输速度
3. 为了使前端能够使用后端的内网IP地址进行通信,通常需要在两者之间设置一个代理服务器(也称为反向代理),这个代理服务器位于公网和内网之间,具有公网IP地址,并且能够访问内网中的后端服务器,前端服务器通过这个代理服务器来与后端服务器进行通信
3. 在前端代码中,可以使用代理服务器,将请求发送给后端, 以实现前后端的通信

这样就完成了 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大白猫~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值