我目前在一个区域(单个数据库用于配置和运营存储)中将IDS4作为单个实例运行。我现在必须将安装分布在两个区域中,以便区域A中的服务/用户访问区域A中的IDS,区域B中的服务/用户访问区域B中的IDS。
两个实例都应该访问相同的数据存储,但是区域B中的IDS不必对区域A中的数据库进行跨区域读取查询。
我们使用Azure SQL Server和地理复制功能,该功能提供单个可写实例(在区域A或B中)和多个可读实例。我们将区域B中的IDS指向同一区域中的一个只读实例,但这是行不通的,因为IDS必须写入诸如持久授权之类的操作数据。
是否有推荐的体系结构来实现这一目标,或者您是否有实施多区域且负载均衡的IDS部署的经验?是否可以将IDS配置为将不同的数据库用于写操作,并将同一区域中的数据库用于读操作?
答案 0 :(得分:0)
由于这种问题在您的业务领域中占了很大比例,因此不太可能为这种情况找到推荐的体系结构。另外,Identity Server 4库或其支持库中没有符合您条件的开箱即用产品。
话虽如此,我也有类似的要求(与Identity Server 4无关,但简而言之,是相同的功能要求),应该有可能在您的情况下采用相同的想法。
首先,您唯一的问题就是您所说的唯一事实是,PersistedGrantStore
使用Identity Server 4 EF软件包开箱即用,它使用IPersistedGrantDbContext
来进行读写操作。数据库。因此,为了解决此问题,您基本上需要创建自己的IPersistedGrantStore
实现,并且在该自定义实现中,您可以在技术上使用两种不同的DbContext
类型,其中一种类型将使用连接字符串来创建数据库的一个可写实例,将仅用于实现进行写操作的接口方法,而另一个将仅用于读取方法,并将连接字符串用于数据库的只读实例。
以上概述的基本思想如下:
public class MyCustomPersistedGrantStore : IPersistedGrantStore
{
private readonly WriteOnlyPersistedGrantDbContext _writeContext;
private readonly ReadOnlyPersistedGrantDbContext _readContext;
public PersistedGrantStore(WriteOnlyPersistedGrantDbContext writeContext, ReadOnlyPersistedGrantDbContext readContext)
{
_writeContext = writeContext;
_readContext = readContext;
}
public Task StoreAsync(PersistedGrant token)
{
//Use _writeContext to implement storage logic
}
public Task<PersistedGrant> GetAsync(string key)
{
//Use _readContext to implement read logic
}
...other interface methods
}
实现自定义版本后,您需要做的就是将IPersistedGrantStore
以及DbContext
的实现添加到DI系统中。
最后,值得注意的是,如果您停止使用.AddOperationalStore(...config)
,那么您也将失去对TokenCleanupHostService
的使用,因此也需要实现。
答案 1 :(得分:0)
您可以使用Azure SQL数据同步而不是地理复制来具有Azure SQL数据库的可写副本,将其中一个定义为中心数据库,将另一个定义为成员数据库。可以双向配置所有数据库之间的同步,因此所有数据库都是可更新的。您可以在this文档上开始配置Azure SQL数据同步。
答案 2 :(得分:0)
我正在用自己的IdentityServer4.Contrib.CosmosDB私分叉来解决问题。如果看一下(非常未完成的atm)源代码,您将对如何实现自己的数据库提供程序(可以妥善处理此类要求)有一个大概的了解。实际上,您可能要假想考虑为IDServer使用NoSQL数据存储,因为与SQL Server相比,我认为它对于多区域读/写是“优化的”。