如果您还对于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 {
@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:
步骤三:服务二的代码
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
- 打开命令行或终端,导航到
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"