如果您还对于Docker或者Docker Compose不甚了解,可以劳烦移步到我之前的教程:
SpringBoot新手快速入门系列教程九:基于docker容器,部署一个简单的项目
SpringBoot新手快速入门系列教程十:基于Docker Compose,部署一个简单的项目
分布式服务有许多优势,特别是在处理大型和复杂系统时。以下是一些主要的优势:
-
可扩展性:分布式服务可以很容易地通过添加更多的服务器来扩展系统容量,从而处理更多的请求和更大的数据量。
-
可靠性和高可用性:通过将服务分布在多个节点上,即使某个节点出现故障,其他节点仍然可以继续提供服务,确保系统的高可用性和可靠性。
-
性能:分布式服务可以将工作负载分散到多个服务器上,减少单个服务器的负载,提高整体系统的性能和响应速度。
-
灵活性:分布式系统通常采用微服务架构,可以让不同的服务独立开发、部署和维护,提高了系统的灵活性和响应变化的能力。
-
故障隔离:分布式系统可以将故障隔离在单个节点或服务中,防止故障扩散到整个系统,从而提高系统的稳定性。
-
资源优化:分布式服务可以充分利用不同服务器的计算资源和存储资源,提高资源利用率,降低成本。
-
地理分布:分布式系统可以在不同的地理位置部署服务器,提供本地化的服务,降低延迟,改善用户体验。
-
模块化:通过将系统分解为独立的模块,可以更容易地进行测试、调试和维护,提高开发效率。
今天我会带你来一步一步实现你人生的第一个分布式服务部署,你可以在本地的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
- 打开命令行或终端,导航到
HelloDistributedDockerA
项目目录。 - 运行以下命令构建并启动服务
docker-compose up --build
这将构建 register-service
容器并启动 MySQL 数据库。
部署 HelloDistributedDockerB
- 打开另一个命令行或终端,导航到
HelloDistributedDockerB
项目目录。 - 运行以下命令构建并启动服务:
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"