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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

步骤一:创建项目

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

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

步骤二:HelloDistributedDockerA代码

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

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 {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/register")
    public String registerUser(@RequestParam String name) {
        // Check if a user with the same name already exists
        if (userRepository.existsByName(name)) {
            return "User already exists";
        }

        // If user doesn't exist, create a new user and save to the database
        User 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 Setters
    public 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-slim

ENV SERVER_PORT=8081

COPY build/libs/hellodistributeddockerA-0.0.1-SNAPSHOT.jar app.jar

EXPOSE 8081

ENTRYPOINT ["java", "-jar", "/app.jar"]

docker-compose.yml:

version: '3.8'
services:
  register-service:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8081:8081"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/userdata
      SPRING_DATASOURCE_USERNAME: Yichael
      SPRING_DATASOURCE_PASSWORD: Qwerty9527
    depends_on:
      - mysql

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: Qwerty123
      MYSQL_DATABASE: userdata
      MYSQL_USER: Yichael
      MYSQL_PASSWORD: Qwerty9527
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mysql-data:

步骤三:服务二的代码

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

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 {

    @Autowired
    private 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 Setters
    public 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-slim

ENV SERVER_PORT=8082

COPY build/libs/hellodistributeddockerB-0.0.1-SNAPSHOT.jar app.jar

EXPOSE 8082

ENTRYPOINT ["java", "-jar", "/app.jar"]

7,docker-compose.yml

version: '3.8'
services:
  login-service:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8082:8082"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/userdata
      SPRING_DATASOURCE_USERNAME: Yichael
      SPRING_DATASOURCE_PASSWORD: Qwerty9527
    depends_on:
      - mysql

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: Qwerty123
      MYSQL_DATABASE: userdata
      MYSQL_USER: Yichael
      MYSQL_PASSWORD: Qwerty9527
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  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"
07-13 06:39