1. Overview
1 What is a multi-tenant architecture?
Multi-tenant architecture refers to supporting simultaneous access by multiple tenants (Tenant) in an application, each tenant has independent resources and data, and is completely isolated from each other. In layman’s terms, multi-tenancy is to “split” an application into multiple independent instances according to customer needs, and each instance does not interfere with each other.
2 Advantages of multi-tenant architecture
-
Better meet the individual needs of different tenants.
-
It can reduce operation and maintenance costs and reduce investment in infrastructure such as hardware and networks.
-
Save development costs, and quickly launch new tenant instances by reusing code.
-
The scalability and scalability of the system are enhanced, horizontal expansion is supported, and the data and resources of each tenant can be managed and controlled.
3 Technology selection for implementing multi-tenant architecture
What is not the most important thing for realizing multi-tenant architecture technology is the correct architecture idea. But choosing the right technology can lead to a faster multi-tenant architecture.
2. Design ideas
1 Architecture selection
It is recommended to use Spring Boot and Spring Cloud to develop multi-tenant applications based on Java. Spring Boot can quickly build applications and provide many mature plug-ins. Spring Cloud provides many tools and components to implement microservice architecture.
1.1 Spring Boot
Using Spring Boot can simplify the project construction process and automatically configure many common third-party libraries and components, reducing the workload of developers.
@RestController public class TenantController { @GetMapping("/hello") public String hello(@RequestHeader("tenant-id") String tenantId) { return "Hello, " + tenantId; } }
1.2 Spring Cloud
Spring Cloud will be more useful when architecting multi-tenant systems. Spring Cloud provides some mature solutions, such as Eureka, Zookeeper, Consul, etc., to realize microservice functions such as service discovery and load balancing.
2 Database Design
In a multi-tenant environment the database must store data separately for each tenant and ensure data isolation. We usually use the following two methods to achieve:
-
Multiple tenants share the same database, and each table contains a tenant_id column to distinguish data from different tenants.
-
Create separate databases for each tenant, each database has the same table structure, but the data is isolated from each other.
3 Application multi-tenant deployment
In order to achieve multi-tenancy in application deployment, we need to consider the following two issues.
3.1 Application isolation
In a multi-tenant environment, different tenants need to access different resources, so application isolation is required. This can be achieved by building separate containers or virtual machines, using namespaces, etc. Docker is a very popular technology for isolating containers.
3.2 Application Configuration
Since each tenant has its own configuration requirements, it is necessary to set application configuration information for each tenant, such as port number, SSL certificate, and so on. These configurations can be stored in a database or in a cloud configuration center.
4 Tenant Management
In a multi-tenant system, it is necessary to be able to manage the data and resources of different tenants, and at the same time, it is necessary to assign corresponding permissions to each tenant. Solutions usually include the following two parts.
4.1 Tenant information maintenance
The maintenance of tenant information includes operations such as adding, modifying, deleting, and querying. It is required to be able to quickly find the corresponding tenant information based on the tenant name or tenant 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
In a multi-tenant application, access to system resources must be set separately for each tenant. For example, A tenant and B tenant cannot access each other’s data.
@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"); } }
3. Technical implementation
1 Multi-tenancy implementation in Spring Boot
In Spring Boot, multi-tenancy mechanism can be realized through multiple data sources and dynamic routing.
1.1 Implementation of multiple data sources
Multiple data sources refer to configuring different data sources for different tenants, so that each tenant can access its own independent data. The specific implementation method is as follows:
@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(); } }
The above code is configured with three data sources corresponding to three tenants. Then when using, you can use annotations to mark the data sources that need to be connected.
@Service public class ProductService { @Autowired @Qualifier("dataSourceA") private DataSource dataSource; //... }
1.2 Dynamic routing implementation
Dynamic routing refers to dynamically switching to the data source of the corresponding tenant according to the requested URL or parameters. The specific implementation is as follows:
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(); } }
The above is the core code of dynamic routing. DynamicDataSource
inherits from AbstractRoutingDataSource
, dynamically obtains the tenant ID through the determineCurrentLookupKey()
method, and then switches to the corresponding data source .
2 Multi-tenancy implementation in Spring Cloud
In Spring Cloud, the multi-tenant mechanism can be realized through service registration and discovery, configuration center, load balancing, etc.
2.1 Service Registration and Discovery
Use Eureka in Spring Cloud to implement service registration and discovery. Each tenant’s service is registered with a different application name in the registry, and the client can access the service of the corresponding tenant through the service name.
2.2 Configuration Center
Use Spring Cloud Config as the configuration center. Configuration files are distinguished by tenant ID, and the client obtains configuration information by reading the configuration file of the corresponding tenant.
2.3 Load balancing
Use Spring Cloud Ribbon as a load balancer. Select the service instance corresponding to the tenant according to the requested URL or parameters to forward the request.
2.4 API
The multi-tenancy mechanism is implemented at the API gateway level to determine the tenant according to the URL or parameters of the request, and forward it to the service instance of the corresponding tenant.
4. Application scenarios
1 Private cloud environment
The private cloud environment refers to the cloud environment built by the enterprise itself, which does not provide external services and is mainly used for data storage, management, sharing and security control within the enterprise. Compared with the public cloud, the advantage of the private cloud is that it can better protect the core data of the enterprise, and it can also meet the requirements of the enterprise for data security and controllability.
2 Public cloud environment
The public cloud environment refers to the cloud environment built by cloud service providers and provides external services. Users can purchase corresponding cloud services according to their needs, such as cloud storage, cloud computing, cloud database, etc. Compared with private clouds, public clouds have the advantages of low cost, elastic scalability, and global deployment, which can better meet the needs of rapid development of enterprises.
3 Enterprise applications
Enterprise-level applications refer to applications for enterprise customers, mainly including a series of application systems such as ERP, CRM, and OA. This type of application is characterized by powerful functions, complex processes, and a large amount of data, and needs to meet the requirements of high efficiency, high reliability, high security, and easy maintenance of the enterprise. In the cloud computing environment, enterprises can deploy these applications on private clouds or public clouds, which reduces the investment and maintenance costs of hardware equipment and improves management efficiency.
5. Implementation steps
1 Build Spring Boot and Spring Cloud environment
First, the following dependencies need to be introduced into the Maven project:
<!-- 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>
Then you need to configure the corresponding parameters in application.yml, as follows:
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: "*"
Among them, datasource.url
is the URL of the database connection, username and password are the account number and password of the database connection; server.port
is the port started by the Spring Boot application; eureka .client.serviceUrl.defaultZone
is the URL of the Eureka service registry.
2 Modify the database design
The database will then need to be modified accordingly to support multi-tenant deployments. Specifically, we need to add a tenant-related field in the database to distinguish different tenants in the application.
3 Realize application multi-tenant deployment
Then you need to implement the multi-tenant deployment function of the application in the code. Specifically, we need to instantiate the corresponding Spring Bean for each tenant, and route the request to the corresponding Bean for processing according to the tenant ID.
Here is an example of a simple implementation:
@Configuration public class MultiTenantConfig { // Provide the data source corresponding to the tenant @Bean public DataSource dataSource(TenantRegistry tenantRegistry) { return new TenantAwareDataSource(tenantRegistry); } // multi-tenant Session factory @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); return sessionFactory. getObject(); } // Dynamically switch tenants @Bean public MultiTenantInterceptor multiTenantInterceptor(TenantResolver tenantResolver) { MultiTenantInterceptor interceptor = new MultiTenantInterceptor(); interceptor.setTenantResolver(tenantResolver); return interceptor; } // register interceptor @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(multiTenantInterceptor()); } // Register tenant information @Bean public TenantRegistry tenantRegistry() { return new TenantRegistryImpl(); } // parse the tenant ID @Bean public TenantResolver tenantResolver() { return new HeaderTenantResolver(); } }
Among them, MultiTenantConfig
is the core configuration class for multi-tenant deployment, which provides functions such as corresponding tenant data source, multi-tenant Session factory, and dynamic switching of tenants.
4 Realize tenant management
Finally, a tenant management function needs to be implemented to manage different tenants in the system. Specifically, we can use Spring Cloud’s service registration and discovery component Eureka to register each tenant’s instance and perform corresponding operations in the management interface. In addition, we also need to provide an independent database for each tenant to ensure data isolation.
6. Summary review
This article details how to use Spring Boot and Spring Cloud to implement an application that supports multi-tenant deployment. It mainly includes building Spring Boot and Spring Cloud environments, modifying database design, implementing multi-tenant deployment of applications, and implementing tenant management.
Application scenarios mainly include SaaS applications, multi-tenant cloud services, etc. The advantages and disadvantages are mainly reflected in improving the scalability and maintainability of the application, but also increasing the complexity of deployment and management. Future improvement directions can consider further improving the automation of multi-tenant management to reduce manual intervention and error rates.
Source: blog.csdn.net/u010349629/article/
details/130737253
Back-end exclusive technology group
Build a high-quality technical exchange community, welcome to join the group who are engaged in programming development and technical recruitment HR, and also welcome everyone to share your company’s referral information, help each other, and make progress together!
Civilized speech, mainly focusing on
communication technology
,job referral
,industry discussion
Advertisers do not enter, do not trust private chats, to prevent being cheated