1. 概述
本文将带你了解 Azure Cosmos DB 的核心特性,并演示如何通过 Spring Data 与其进行交互。目标是让你在项目中快速集成 Cosmos DB,少踩坑、高效落地。
2. Azure Cosmos DB 简介
Azure Cosmos DB 是微软提供的全球分布式多模型数据库服务,属于典型的 NoSQL 数据库。
它的亮点不是“能用”,而是“稳得一批”——提供对吞吐量、延迟、可用性和一致性四个维度的 SLA 保障。比如,读写操作的可用性承诺高达 **99.999%**(也就是全年宕机不超过 5 分钟),这在云数据库中属于顶级水准。
一致性模型丰富,不玩二元论
很多数据库只提供“强一致”或“最终一致”两种选择,而 Cosmos DB 提供了 5 种一致性级别,让你按需取舍:
✅ 强一致性(Strong)
✅ 有界过期一致性(Bounded Staleness)
✅ 会话一致性(Session)
✅ 一致前缀(Consistent Prefix)
✅ 最终一致性(Eventual)
你可以根据业务场景在性能与一致性之间灵活平衡。
弹性扩展 + 全球分发
- 存储和吞吐量均可弹性伸缩,按需付费。
- 支持一键式全球部署,数据可跨 Azure 全球任意区域复制,让终端用户就近访问,降低延迟。
- 无需管理索引,数据自动索引化。
- 无固定 Schema,完全 schema-agnostic,适合灵活的数据结构。
- 支持多种标准 API 接入:SQL、MongoDB、Cassandra、Gremlin、Table 等,迁移成本低。
3. Spring Data Azure Cosmos DB
微软官方提供了 Spring Data 模块,让 Java 开发者可以用熟悉的编程模型操作 Cosmos DB。接下来我们将构建一个 Spring Boot 应用,实现 Product 实体的 CRUD。
⚠️ 提示:本文使用的是较早期的
spring-data-cosmosdb
模块(2.x 版本),基于 Azure SDK for Java 的旧版客户端。新项目建议使用更新的spring-data-cosmos
(基于 Azure SDK v4),但本文仍按原文结构讲解,便于理解演进逻辑。
3.1 使用 Azure Cosmos Emulator 本地开发
不想在 Azure 云上开账号?没问题。微软提供了 Azure Cosmos Emulator,可在本地模拟 Cosmos DB 服务,适合开发和测试。
虽然功能不完全等同于线上服务(比如不支持多区域复制),但基本 CRUD 和分区功能都支持,够用。
我们选择在 Docker for Windows 上运行 Emulator,方便环境隔离。
启动 Emulator 容器
先拉取镜像:
docker pull mcr.microsoft.com/cosmosdb/windows/azure-cosmos-emulator
创建本地挂载目录并启动容器:
md $env:LOCALAPPDATA\CosmosDBEmulator\bind-mount 2>null
docker run --name azure-cosmosdb-emulator --memory 2GB --mount
"type=bind,source=$env:LOCALAPPDATA\CosmosDBEmulator\bind-mount,destination=C:\CosmosDB.Emulator\bind-mount"
--interactive --tty -p 8081:8081 -p 8900:8900 -p 8901:8901 -p 8902:8902 -p 10250:10250
-p 10251:10251 -p 10252:10252 -p 10253:10253 -p 10254:10254 -p 10255:10255 -p 10256:10256 -p 10350:10350
mcr.microsoft.com/cosmosdb/windows/azure-cosmos-emulator
启动成功后,可通过 https://localhost:8081/_explorer/
访问 Web 数据管理器。
3.2 配置 Emulator 证书(Java 应用必做)
Emulator 使用自签名证书,Java 应用访问时会因 TLS 验证失败而抛出异常。解决方案是将证书导入 JVM 的信任库(cacerts
)。
获取证书
curl -k https://localhost:8081/_explorer/emulator.pem > ~/emulatorcert.crt
导入证书到 keystore
keytool -importcert -alias azure-cosmos-emulator -keystore cacerts -file ~/emulatorcert.crt -storepass changeit
✅ 默认密码是
changeit
✅ 建议将证书导入到项目本地的 keystore,避免污染全局 JVM 环境
4. 在 Spring 中使用 Azure Cosmos DB
4.1 添加依赖并配置连接
在 pom.xml
中引入 Spring Data Cosmos DB 模块:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>spring-data-cosmosdb</artifactId>
<version>2.3.0</version>
</dependency>
在 application.properties
中配置连接信息:
azure.cosmosdb.uri=https://localhost:8081
azure.cosmosdb.key=C2y6yDjf5/R+ob0N8A7Cgv30VRzGjbvnKtSKV29u4dQd9I4eQqQH9q4aB2v1g== # Emulator 默认密钥
azure.cosmosdb.secondaryKey=RolloverKey== # 可选
azure.cosmosdb.database=product-db
🔐 注意:生产环境务必通过 Azure Key Vault 管理密钥,不要硬编码
配置类:启用 Cosmos DB 支持
创建配置类,继承 AbstractCosmosConfiguration
,并使用 @EnableCosmosRepositories
扫描仓库接口:
@Configuration
@EnableCosmosRepositories(basePackages = "com.example.repository")
public class AzureCosmosDbConfiguration extends AbstractCosmosConfiguration {
@Value("${azure.cosmosdb.uri}")
private String uri;
@Value("${azure.cosmosdb.key}")
private String key;
@Value("${azure.cosmosdb.database}")
private String dbName;
private CosmosKeyCredential cosmosKeyCredential;
@Bean
public CosmosDBConfig getConfig() {
this.cosmosKeyCredential = new CosmosKeyCredential(key);
CosmosDBConfig cosmosdbConfig = CosmosDBConfig.builder(uri, this.cosmosKeyCredential, dbName)
.build();
return cosmosdbConfig;
}
}
✅
CosmosKeyCredential
支持密钥轮换,推荐使用
✅basePackages
指定仓库接口所在包路径
4.2 定义实体类
使用 @Document
注解标记实体,映射到 Cosmos DB 的容器(Container):
@Document(collection = "products")
public class Product {
@Id
private String productid;
private String productName;
private double price;
@PartitionKey
private String productCategory;
// 标准 getter / setter 省略
}
关键点说明:
注解 | 说明 |
---|---|
@Document(collection = "products") |
指定容器名为 products ,若不指定则默认使用类名 |
@Id |
标记文档主键字段,对应 Cosmos DB 的 _id |
@PartitionKey |
指定分区键,用于水平扩展和查询优化 |
⚠️ 分区键一旦设定,不可更改,选型需谨慎
你还可以通过 @DocumentIndexingPolicy
自定义索引策略,或添加 @Version
注解配合 _etag
字段实现乐观锁。
4.3 定义 Repository 接口
创建仓库接口,继承 CosmosRepository
,即可获得开箱即用的 CRUD 方法:
@Repository
public interface ProductRepository extends CosmosRepository<Product, String> {
List<Product> findByProductName(String productName);
}
Product
:实体类型String
:主键类型(即@Id
字段类型)findByProductName
:Spring Data 自动解析方法名生成查询,无需手动写 SQL
4.4 编写测试验证连接
使用 @SpringBootTest
测试实体的保存与查询:
@SpringBootTest
public class AzureCosmosDbApplicationManualTest {
@Autowired
private ProductRepository productRepository;
@Test
public void givenProductIsCreated_whenCallFindById_thenProductIsFound() {
Product product = new Product();
product.setProductid("1001");
product.setProductCategory("Shirt");
product.setPrice(110.0);
product.setProductName("Blue Shirt");
productRepository.save(product);
Product retrievedProduct = productRepository.findById("1001", new PartitionKey("Shirt"))
.orElse(null);
Assert.notNull(retrievedProduct, "Retrieved Product is Null");
}
}
✅ 注意:查询时必须传入
PartitionKey
,否则会触发跨分区查询(性能差且消耗更多 RU) ✅ 测试通过说明:本地 Emulator + Spring Data 集成成功
5. 总结
本文带你完成了 Spring Boot 与 Azure Cosmos DB 的基础集成,涵盖:
- ✅ 使用 Emulator 本地开发
- ✅ 证书配置避坑
- ✅ 实体映射与分区键设计
- ✅ 仓库接口定义与自动查询生成
- ✅ 基础 CRUD 测试验证
虽然示例使用的是旧版 SDK,但核心思想(如注解驱动、Repository 模式、分区键使用)在新版 spring-data-cosmos
中依然适用。建议新项目直接使用官方推荐的最新模块,API 更现代,性能更好。