SpringBoot新手快速入门系列教程十一:基于Docker Compose部署一个最简单分布式服务项目

news/2024/9/11 3:28:24/ 标签: docker, 容器, 运维

我的教程都是亲自测试可行才发布的,如果有任何问题欢迎留言或者来群里我每天都会解答。

如果您还对于Docker或者Docker Compose不甚了解,可以劳烦移步到我之前的教程:

SpringBoot新手快速入门系列教程九:基于docker容器,部署一个简单的项目

SpringBoot新手快速入门系列教程十:基于Docker Compose,部署一个简单的项目

分布式服务有许多优势,特别是在处理大型和复杂系统时。以下是一些主要的优势:

  1. 可扩展性:分布式服务可以很容易地通过添加更多的服务器来扩展系统容量,从而处理更多的请求和更大的数据量。

  2. 可靠性和高可用性:通过将服务分布在多个节点上,即使某个节点出现故障,其他节点仍然可以继续提供服务,确保系统的高可用性和可靠性。

  3. 性能:分布式服务可以将工作负载分散到多个服务器上,减少单个服务器的负载,提高整体系统的性能和响应速度。

  4. 灵活性:分布式系统通常采用微服务架构,可以让不同的服务独立开发、部署和维护,提高了系统的灵活性和响应变化的能力。

  5. 故障隔离:分布式系统可以将故障隔离在单个节点或服务中,防止故障扩散到整个系统,从而提高系统的稳定性。

  6. 资源优化:分布式服务可以充分利用不同服务器的计算资源和存储资源,提高资源利用率,降低成本。

  7. 地理分布:分布式系统可以在不同的地理位置部署服务器,提供本地化的服务,降低延迟,改善用户体验。

  8. 模块化:通过将系统分解为独立的模块,可以更容易地进行测试、调试和维护,提高开发效率。

今天我会带你来一步一步实现你人生的第一个分布式服务部署,你可以在本地的window系统上做简单的测试部署。当然如果条件允许你也可以尝试的部署在两台不同的服务器上。

我们今天要做的业务逻辑拆分是基于上一教程,用户“输入用户名注册” HelloDistributedDockerA和 “用户通过用户名确认自己是否可以登录”HelloDistributedDockerB 为例子来拆分之前的两个业务逻辑运行在不同的Docker容器内。

步骤一:创建项目

我们来分别创建:HelloDistributedDockerA和HelloDistributedDockerB 项目,依赖如下

步骤二:HelloDistributedDockerA代码

RegisterController.java

package com.yuye.www.hellodistributeddockera.controller;import com.yuye.www.hellodistributeddockera.entity.User;
import com.yuye.www.hellodistributeddockera.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class RegisterController {@Autowiredprivate UserRepository userRepository;@GetMapping("/register")public String registerUser(@RequestParam String name) {// Check if a user with the same name already existsif (userRepository.existsByName(name)) {return "User already exists";}// If user doesn't exist, create a new user and save to the databaseUser user = new User();user.setName(name);userRepository.save(user);return "User registered successfully";}
}

User.java

package com.yuye.www.hellodistributeddockera.entity;import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;// Getters and Setterspublic Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

UserRepository.java

package com.yuye.www.hellodistributeddockera.repository;import com.yuye.www.hellodistributeddockera.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;import java.util.Optional;public interface UserRepository extends JpaRepository<User, Long> {Optional<User> findByName(String name);boolean existsByName(String name);
}

RegisterServiceApplication.java

package com.yuye.www.hellodistributeddockera;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class HelloDistributedDockerAApplication {public static void main(String[] args) {SpringApplication.run(HelloDistributedDockerAApplication.class, args);}
}

application.properties

spring.application.name=HelloDistributedDockerA
spring.datasource.url=jdbc:mysql://mysql:3306/userdata?useSSL=false&serverTimezone=UTC
spring.datasource.username=Yichael
spring.datasource.password=Qwerty9527
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
server.port=8081

Dockerfile

FROM openjdk:17-jdk-slimENV SERVER_PORT=8081COPY build/libs/hellodistributeddockerA-0.0.1-SNAPSHOT.jar app.jarEXPOSE 8081ENTRYPOINT ["java", "-jar", "/app.jar"]

docker-compose.yml:

version: '3.8'
services:register-service:build:context: .dockerfile: Dockerfileports:- "8081:8081"environment:SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/userdataSPRING_DATASOURCE_USERNAME: YichaelSPRING_DATASOURCE_PASSWORD: Qwerty9527depends_on:- mysqlmysql:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: Qwerty123MYSQL_DATABASE: userdataMYSQL_USER: YichaelMYSQL_PASSWORD: Qwerty9527ports:- "3306:3306"volumes:- mysql-data:/var/lib/mysqlvolumes:mysql-data:

步骤三:服务二的代码

1,LoginController.java

package com.yuye.www.hellodistributeddockerb.controller;import com.yuye.www.hellodistributeddockerb.entity.User;
import com.yuye.www.hellodistributeddockerb.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.Optional;@RestController
public class LoginController {@Autowiredprivate UserRepository userRepository;@GetMapping("/login")public String loginUser(@RequestParam String name) {Optional<User> user = userRepository.findByName(name);if (user.isPresent()) {return "User found: " + name;} else {return "User not found";}}
}

2,User.java:

package com.yuye.www.hellodistributeddockerb.entity;import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;// Getters and Setterspublic Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

3,UserRepository.java

package com.yuye.www.hellodistributeddockerb.repository;import com.yuye.www.hellodistributeddockerb.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;import java.util.Optional;public interface UserRepository extends JpaRepository<User, Long> {Optional<User> findByName(String name);boolean existsByName(String name);
}

4,HelloDistributedDockerBApplication.java

package com.yuye.www.hellodistributeddockerb;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class HelloDistributedDockerBApplication {public static void main(String[] args) {SpringApplication.run(HelloDistributedDockerBApplication.class, args);}
}

5,application.properties

spring.application.name=HelloDistributedDockerB
spring.datasource.url=jdbc:mysql://mysql:3306/userdata?useSSL=false&serverTimezone=UTC
spring.datasource.username=Yichael
spring.datasource.password=Qwerty9527
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
server.port=8082

6,Dockerfile

FROM openjdk:17-jdk-slimENV SERVER_PORT=8082COPY build/libs/hellodistributeddockerB-0.0.1-SNAPSHOT.jar app.jarEXPOSE 8082ENTRYPOINT ["java", "-jar", "/app.jar"]

7,docker-compose.yml

version: '3.8'
services:login-service:build:context: .dockerfile: Dockerfileports:- "8082:8082"environment:SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/userdataSPRING_DATASOURCE_USERNAME: YichaelSPRING_DATASOURCE_PASSWORD: Qwerty9527depends_on:- mysqlmysql:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: Qwerty123MYSQL_DATABASE: userdataMYSQL_USER: YichaelMYSQL_PASSWORD: Qwerty9527ports:- "3306:3306"volumes:- mysql-data:/var/lib/mysqlvolumes:mysql-data:

步骤三:部署和测试步骤

部署 HelloDistributedDockerA
  1. 打开命令行或终端,导航到 HelloDistributedDockerA 项目目录。
  2. 运行以下命令构建并启动服务

docker-compose up --build

这将构建 register-service 容器并启动 MySQL 数据库。

部署 HelloDistributedDockerB
  1. 打开另一个命令行或终端,导航到 HelloDistributedDockerB 项目目录。
  2. 运行以下命令构建并启动服务:
docker-compose up --build

这将构建 login-service 容器并启动 MySQL 数据库。

步骤四:部署和测试步骤

使用 Postman 或 curl 进行测试:

注册用户

curl -X GET "http://localhost:8081/register?name=testuser"

登录用户

curl -X GET "http://localhost:8082/login?name=testuser"


http://www.ppmy.cn/news/1475265.html

相关文章

ZGC的流程图

GC标记过程 1、初始标记 扫描所有线程栈的根节点&#xff0c;然后再扫描根节点直接引用的对象并进行标记。这个阶段需要停顿所有的应用线程&#xff08;STW&#xff09;&#xff0c;但由于只扫描根对象直接引用的对象&#xff0c;所以停顿时间很短。停顿时间高度依赖根节点的数…

14-47 剑和诗人21 - 2024年如何打造AI创业公司

​​​​​ 2024 年&#xff0c;随着人工智能继续快速发展并融入几乎所有行业&#xff0c;创建一家人工智能初创公司将带来巨大的机遇。然而&#xff0c;在吸引资金、招聘人才、开发专有技术以及将产品推向市场方面&#xff0c;人工智能初创公司也面临着相当大的挑战。 让我来…

LDAPWordlistHarvester:基于LDAP数据的字典生成工具

关于LDAPWordlistHarvester LDAPWordlistHarvester是一款功能强大的字典列表生成工具&#xff0c;该工具可以根据LDAP中的详细信息生成字典列表文件&#xff0c;广大研究人员随后可以利用生成的字典文件测试目标域账号的非随机密码安全性。 工具特征 1、支持根据LDAP中的详细信…

利用宝塔安装一套linux开发环境

更新yum&#xff0c;并且更换阿里镜像源 删除yum文件 cd /etc/yum.repos.d/ 进入yum核心目录 ls sun.repo rm -rf * 删除之前配置的本地源 ls 配置阿里镜像源 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 配置扩展包 wge…

DP(3) | 0-1背包 | Java | 卡码 46 LeetCode 416 做题总结

代码随想录笔记 AcWing-背包九讲专题 一道例题 dd大牛背包9讲 背包笔记 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。 01背包&#xff1a;n种物品&#xff0c;每种物品只有 1 个&#xff0c;每…

FFmpeg——视频拼接总结

最近需要做一个关于视频拼接的内容&#xff0c;需要将两个视频合成一个视频&#xff0c;使用opencv的话需要将视频读上来然后再写到文件了&#xff0c;这个会很消耗时间也没有必要。两个视频的编码格式是一样的&#xff0c;并不需要转码操作所以想法是直接将视频流补到后面&…

vue3使用Echarts图表生成项目进度甘特图

先看效果 代码展示 <template><h1>项目进度甘特图</h1><div id"app"><!-- Echarts 图表 --><div ref"progressChart" class"progressChart"></div></div> </template><script setup&…

Xcode Playgrounds:探索Swift编程的交互式乐园

Xcode Playgrounds&#xff1a;探索Swift编程的交互式乐园 Xcode是苹果公司为macOS开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它提供了一套完整的工具集&#xff0c;用于开发macOS、iOS、watchOS和tvOS应用。在Xcode中&#xff0c;Playgrounds是一个革命性的…

C++中的RTTI(运行时类型识别)的定义

C中的RTTI&#xff08;Runtime Type Identification&#xff0c;运行时类型识别&#xff09;是一种机制&#xff0c;它允许程序在运行时确定对象的实际类型。这是C语言为了支持面向对象编程中的多态性而提供的一个重要特性。RTTI主要通过两个运算符实现&#xff1a;typeid和dyn…

Mac M1安装配置Hadoop+Flink SQL环境

Flink 1.18.1 Hadoop 3.4.0 一、准备工作 系统&#xff1a;Mac M1 (MacOS Sonoma 14.3.1) JDK&#xff1a;jdk1.8.0_381 &#xff08;注意&#xff1a;尽量一定要用JDK8&#xff0c;少用高版本&#xff09; Scala&#xff1a;2.12 JDK安装在本机的/opt/jdk1.8.0_381.jdk/C…

ubuntu安装k8s+docker运行英伟达gpu cuda

安装k8sdocker sealos resetsealos run registry.cn-shanghai.aliyuncs.com/labring/kubernetes-docker:v1.27.7 registry.cn-shanghai.aliyuncs.com/labring/helm:v3.9.4 registry.cn-shanghai.aliyuncs.com/labring/cilium:v1.13.4 --single 英伟达Ubuntu驱动下载地址&…

鸿蒙系统创建签名文件及使用创建签名文件打包并安装

* 第一步 第二步&#xff1a;创建.p12文件&#xff0c;点击New如果有的话就Choose Existing 填好下面信息 点击Next进入到下面界面 开始生成csr文件如下图 点击OK–>Finish 文件保存在了下面目录 第三步 1.访问华为开发者平台&#xff0c;登录开发者账号&#xff0c;进…

重点区域分布式无人机探测防御系统详解

重点区域分布式无人机探测防御系统采用模块化设计&#xff0c;结合先进的传感技术、通信技术和数据处理技术&#xff0c;实现对无人机的高效探测与防御。系统架构由无人机探测模块、数据分析中心、防御与反制模块以及用户交互界面四大部分组成。系统特点包括分布式部署、高灵敏…

目前分布式光纤测温系统的主流架构有哪些?

分布式光纤测温技术的主流架构&#xff0c;历经多个阶段的发展和演变&#xff0c;每种架构都有其独特的特点和优势。回顾过去的发展历程&#xff0c;我们可以看到三种主要架构的演进&#xff0c;每一次创新都在不同程度上推动了技术的进步和市场的发展。 首先&#xff0c;2005…

[Elasticsearch]ES近似实时搜索的原因|ES非实时搜索的原因|ES Near real-time search

Elasticsearch-专栏&#x1f448;️ 往期回顾&#xff1a; ES单一查询定义&#x1f448;️ ES深分页问题&#x1f448;️ ES商城搜索实战&#x1f448;️ ES环境搭建:单节点模式/集群模式&#x1f448;️ ES开启认证&#x1f448;️ 近似实时搜索&#xff08;Near real-t…

光学传感器图像处理流程(一)

光学传感器图像处理流程&#xff08;一&#xff09; 1. 处理流程总览2. 详细处理流程2.1. 图像预处理2.1.1. 降噪处理2.1.2. 薄云处理2.1.3. 阴影处理 2.2. 辐射校正2.2.1. 辐射定标2.2.2. 大气校正2.2.3. 地形校正 2.3. 几何校正2.3.1. 图像配准2.3.2. 几何粗校正2.3.3. 几何精…

切割01串(牛客小白月赛98)

题意&#xff1a; 给三个整数n&#xff0c;l&#xff0c;r&#xff0c;和一个字符串s&#xff0c;满足l<|c0-c1|<r就可以切成字符串a和字符串b&#xff0c;c0为字符串a左侧出现0的次数&#xff0c;c1为字符串b右侧出现1的次数&#xff0c;求最多切割次数 知识点&#x…

HTML5新增的input元素属性:placeholder、required、autofocus、min、max等

HTML5 大幅度地增加与改良了 input 元素的属性&#xff0c;可以简单地使用这些属性来实现 HTML5 之前需要使用 JavaScript 才能实现的许多功能。 下面将详细介绍这些新增的 input 元素的属性。 属性说明属性说明placeholder在输入框显示描述性或提示性文本autocomplete是否保…

Java常用的API_02(正则表达式、爬虫)

Java正则表达式 七、正则表达式7.1 格式7.1.1 字符类注意字符类示例代码1例2 7.1.2 预定义字符预定义字符示例代码例2 7.1.3 区别总结 7.2 使用Pattern和Matcher类与直接使用String类的matches方法的区别。&#xff08;1&#xff09; 使用Pattern和Matcher类示例代码 &#xff…

使用Spring Boot创建自定义Starter

Spring Boot的起步依赖&#xff08;Starter&#xff09;简化了Spring应用的开发&#xff0c;提供了一组默认的库和配置。自定义Starter可以帮助你封装通用功能&#xff0c;便于在多个项目中重用。本文将详细介绍如何创建和使用自定义Spring Boot Starter。 一、什么是Spring B…