在.NET Core中使用Digital Ocean Managed Databases服务



尽管其他云平台长期以来都有自己的数据库解决方案,但直到今天,Digital Ocean仍未在此细分市场中提供任何服务。 但是在2月14日这一天,所有公司都决定向客户赠送礼物,并以“有限可用性”模式启动了托管数据库服务。

由于Digital Ocean现在是在.NET Core上托管小型项目的相当流行的平台,因此我不能忽略此事件。

我将在此出版物中描述使用.NET Core时服务的工作方式以及在连接数据库时的细微差别。



今天,可以使用PostrgeSQL版本10和11的数据库,然后是MySQL和Redis。

根据Digital Ocean的说法,托管数据库服务解决了许多公司和开发人员从头开始创建集群时面临的常见问题:

  • 确定最佳基础架构
  • 随着业务和数据需求的增长来扩展基础架构
  • 设计和管理高可用性基础架构和故障转移流程
  • 实施备份和恢复策略
  • 预测和维护基础架构维护成本

今天,创建最紧凑的基座将花费您15美元。 最昂贵的配置每月可能花费两千多美元

连接池


当客户端直接连接到PostgreSQL数据库时,服务器将创建一个处理该连接的过程。 每个单独的连接大约需要10 MB的RAM,并使用该内存直到关闭。 此外,连接总数是固定的,并且当使用所有连接时,新客户端将不再能够连接。

Digital Ocean允许您创建基于PgBouncer运行的连接池。 连接池通过将客户端连接定向到池应用程序来减少性能问题,从而减少数据库需要处理的进程数。 池应用程序将部分连接转移到数据库,并将其余部分放在队列中,直到数据库可用于新连接为止。

使用连接池时,应用程序不需要管理实际的连接。 他们仅需要连接到池并在完成任务后断开连接。

池创建


创建连接池非常简单-您需要打开集群并转到“连接池”选项卡。 DigitalOcean支持三种类型的池化:



交易额

此模式允许每个客户端同时将池用于一个事务。 如果发送的事务数超过池中的可用事务数,则在连接可用之后,将对其他事务进行排队和处理。 当您有大量使用空闲连接的客户端时,事务模式是合适的。 这些客户端将保持与池的连接,而无需建立与PostgreSQL的连接。

届会

此模式允许客户端处理请求,直到它与数据库断开连接为止,并始终保持与此客户端的连接。 如果连接的客户端多于无法在池中处理的客户端,则在断开现有客户端的连接后,这些客户端将排队并连接。

声明书

此模式是最严格的模式,一次只能允许一个操作员,然后再移至队列中的下一个客户端。 这意味着不允许使用多个运算符的请求,也不会执行这些请求。 此模式主要在每笔交易仅限于一个操作员的情况下有用。 与多个代理商的交易将被池拒绝。

创建池之后,需要使用池参数连接到数据库。 您可以通过单击“连接详细信息”链接来查看它们:



泳池连接




在我的项目中,我使用Npgsql ,因此更多示例将暗示使用该驱动程序。

连接字符串如下所示:

User ID=xxx;Password=xxxx;Host=xxx.db.ondigitalocean.com;Port=xxx;Database=pool_name;Pooling=false;SslMode=Require;Server Compatibility Mode=Redshift; 


您要注意的是:

  • Database参数将不包含数据库的名称,而是包含用于连接数据库的池的名称。
  • 池化将设置为false。 连接池将由PgBouncer而不是驱动程序管理。
  • SslMode参数必须设置为Require,因为打开连接将需要证书。
  • 服务器兼容模式参数必须初始化为Redshift值。 通过PgBouncer使用npgsql驱动程序时,这将避免许多问题。

连接准备方法如下所示:

 protected async Task<IDbConnection> CreateConnection() { var connection = new NpgsqlConnection(_connectionString) { ProvideClientCertificatesCallback = certificates => { certificates.Add(new X509Certificate2(_cert)); }, UserCertificateValidationCallback = CertificateValidation() }; await connection.OpenAsync(); return connection; } private RemoteCertificateValidationCallback CertificateValidation() => (sender, certificate, chain, errors) => { if (errors == SslPolicyErrors.None) return true; if ((errors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) { var allErrorsIsUntrustedRoot = chain? .ChainStatus .All(o => o.Status == X509ChainStatusFlags.UntrustedRoot); return allErrorsIsUntrustedRoot ?? true; } return true; }; 

这里值得注意两点。

  • 第一个 。 创建连接时,必须使用证书。 可以将其下载到对话框中,以查看池的连接参数。 证书连接是通过ProvideClientCertificatesCallback配置的。
  • 第二个 。 池证书验证过程,可通过RemoteCertificateValidationCallback配置。 在我的示例中,使用了一个小技巧,您可以忽略由于根证书验证不起作用而导致的错误。

不要忘记,该服务当前是在“有限可用性”模式下提供的,这意味着部分功能仍可以扩展,并且在使用服务期间可能会出现问题,DO团队还没有时间消除这些问题。

参考文献


Source: https://habr.com/ru/post/zh-CN440464/


All Articles