Mastering Multi‑Tenant Architecture with Spring Boot & Spring Cloud: A Complete Guide

Learn how to design, implement, and deploy a multi‑tenant architecture using Spring Boot and Spring Cloud, covering concepts, advantages, database strategies, dynamic routing, service registration, configuration management, and practical code examples for scalable SaaS applications.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Mastering Multi‑Tenant Architecture with Spring Boot & Spring Cloud: A Complete Guide

Overview

1 What is multi‑tenant architecture?

Multi‑tenant architecture allows multiple tenants to access a single application simultaneously, each with isolated resources and data, effectively partitioning the application into independent instances per customer.

2 Advantages of multi‑tenant architecture

Better meet different tenant customization needs.

Reduce operation costs and lower hardware, network, and infrastructure investment.

Save development cost by reusing code and quickly launching new tenant instances.

Improve scalability and extensibility, supporting horizontal scaling with manageable and controllable tenant data and resources.

3 Technical choices for implementing multi‑tenant architecture

While the correct architectural thinking is most important, choosing appropriate technology speeds up implementation.

Design ideas

1 Architecture selection

For Java multi‑tenant applications, it is recommended to use Spring Boot and Spring Cloud.

1.1 Spring Boot

Spring Boot simplifies project setup and automatically configures many common third‑party libraries and components, reducing developer workload.

@RestController
public class TenantController {
    @GetMapping("/hello")
    public String hello(@RequestHeader("tenant-id") String tenantId) {
        return "Hello, " + tenantId;
    }
}

1.2 Spring Cloud

Spring Cloud provides mature solutions such as Eureka, Zookeeper, and Consul for service discovery, load balancing, and other microservice functions.

2 Database design

In a multi‑tenant environment, the database must store data for each tenant separately and ensure isolation. Two common approaches are:

All tenants share the same database, with a tenant_id column in each table to distinguish data.

Create a separate database for each tenant; the schema is identical but data is isolated.

3 Application multi‑tenant deployment

Two key considerations when deploying multi‑tenant applications are application isolation and application configuration.

3.1 Application isolation

Different tenants need isolated resources; isolation can be achieved with independent containers, virtual machines, or namespaces. Docker is a popular container isolation technology.

3.2 Application configuration

Each tenant has its own configuration requirements (e.g., port, SSL certificate). Configurations can be stored in a database or a cloud configuration center.

4 Tenant management

Managing tenant data and resources, and assigning appropriate permissions, typically involves tenant information maintenance and permission control.

4.1 Tenant information maintenance

Operations include adding, modifying, deleting, and querying tenant information, allowing quick lookup by tenant name or ID.

CREATE TABLE tenant (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE,
    description VARCHAR(255),
    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

4.2 Tenant permission control

Each tenant must have separate access permissions to system resources. Example using Spring Security:

@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/api/tenant/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
            .passwordEncoder(new BCryptPasswordEncoder())
            .and()
            .inMemoryAuthentication()
            .withUser("admin")
            .password(new BCryptPasswordEncoder().encode("123456"))
            .roles("ADMIN");
    }
}

Technical implementation

1 Multi‑tenant with Spring Boot

1.1 Multiple data sources

Configure separate DataSource beans for each tenant.

@Configuration
public class DataSourceConfig {
    @Bean(name = "dataSourceA")
    @ConfigurationProperties(prefix = "spring.datasource.a")
    public DataSource dataSourceA() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dataSourceB")
    @ConfigurationProperties(prefix = "spring.datasource.b")
    public DataSource dataSourceB() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dataSourceC")
    @ConfigurationProperties(prefix = "spring.datasource.c")
    public DataSource dataSourceC() {
        return DataSourceBuilder.create().build();
    }
}

Inject the required datasource with @Qualifier:

@Service
public class ProductService {
    @Autowired
    @Qualifier("dataSourceA")
    private DataSource dataSource;
    // ...
}

1.2 Dynamic routing

Implement AbstractRoutingDataSource to switch datasource based on tenant ID.

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return TenantContextHolder.getTenantId();
    }
}

@Configuration
public class DataSourceConfig {
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(DynamicDataSource.class).build();
    }
}

2 Multi‑tenant with Spring Cloud

2.1 Service registration and discovery

Use Eureka; each tenant registers services with a unique application name, allowing clients to discover the correct tenant service.

2.2 Configuration center

Use Spring Cloud Config as a configuration center. Configuration files are separated by tenant ID, and clients load the appropriate file.

2.3 Load balancing

Use Spring Cloud Ribbon to select the tenant‑specific service instance based on request parameters.

2.4 API gateway

At the API‑gateway layer, determine the tenant from the URL or parameters and forward the request to the corresponding tenant service instance.

Application scenarios

1 Private cloud

Private cloud is built by the enterprise for internal use, offering better data security and control compared to public cloud.

2 Public cloud

Public cloud is provided by service providers, offering low cost, elasticity, and global deployment, suitable for rapid business growth.

3 Enterprise applications

SaaS, ERP, CRM, OA and other enterprise applications benefit from multi‑tenant architecture, improving scalability, reliability, and maintainability.

Implementation steps

1 Set up Spring Boot and Spring Cloud environment

Add Maven dependencies:

<!-- Spring Boot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>2020.0.3</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Configure application.yml:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/appdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
mybatis:
  type-aliases-package: com.example.demo.model
  mapper-locations: classpath:mapper/*.xml
server:
  port: 8080
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
management:
  endpoints:
    web:
      exposure:
        include: "*"

2 Modify database design

Add a tenant identifier column or create separate databases to support isolation.

3 Implement multi‑tenant deployment

Instantiate Spring beans per tenant and route requests based on tenant ID.

@Configuration
public class MultiTenantConfig {
    @Bean
    public DataSource dataSource(TenantRegistry tenantRegistry) {
        return new TenantAwareDataSource(tenantRegistry);
    }
    // Additional beans for SqlSessionFactory, interceptors, etc.
}

4 Implement tenant management

Register each tenant instance with Eureka, provide independent databases, and manage permissions using Spring Security.

Conclusion

This article details how to build a multi‑tenant SaaS application with Spring Boot and Spring Cloud, covering environment setup, database design, deployment, and tenant management, while highlighting the benefits and challenges of multi‑tenant architectures.

图片
图片
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

architecturedatabaseMulti‑Tenantspring-bootspring-cloud
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.