扩展一个Entity Framework应用程序 / 多个应用程序访问同一个数据库?

4
我有一个使用MVC/EF Code First编程的应用程序,它进行了大量的服务器端处理,资源占用较高。
我知道如何设置负载均衡,但是我想知道,扩展EF应用程序是否像配置新服务器、部署应用程序并指向数据库集群那样简单,或者说,多个EF应用程序访问同一数据库服务器时是否会出现任何问题?
我似乎找不到任何关于此的建议/指南,我很担心选择EF而不是更简单/更直截了当的东西是错误的选择!

1
对于性能:它取决于瓶颈在哪里。如果您有一个查询需要运行多次,而且特别昂贵,则将这些执行分散到多个数据库实例可能是正确的选择。但是,如果您有很多轻量级查询,并且大部分时间都花在应用程序内部,则数据库集群无法提高性能。如果您还没有这样做,请尝试对应用程序进行分析,并查看在您的代码中与外部代码和外部资源(数据库、Web 服务调用)之间花费了多少时间的百分比。 - ta.speot.is
但更基本的层面上,处理多个MVC应用程序实例的复杂性之一是状态管理。例如,如果您在内存中保留有关下一页请求的某些信息,但用户被负载平衡到另一台服务器...那么该服务器如何知道第一台服务器在内存中保存了什么? - ta.speot.is
@te.speot.is - 这个问题基本上与输入/输出有关... 应用程序不过是一个API... 我有客户端发送大量包含数据的请求,我的应用程序必须在存储到后端数据库之前进行处理/排序/过滤... 我需要支持更多的客户端,只想了解EF扩展 / 当两个前端需要写入同一张表时我很担心会发生什么。 - Wil
除此之外,我理想中希望构建一些“额外”的支持应用程序,这些应用程序钩入同一个数据库...而且,我不确定EF如何处理多个应用程序连接到同一个数据库....在想是否应该转向Linq,至少我知道事情将如何运作 :/ - Wil
1个回答

3
“...关于多个EF应用程序访问同一数据库服务器的问题?”
回顾一下,您的应用程序是基于ASP .NET MVC的。拥有多个实例可能会引发状态管理问题。
MSDN对为什么这是一个问题进行了很好的介绍:
“HTTP是一种无状态协议。这意味着Web服务器将每个页面的HTTP请求视为独立请求。服务器不保留在以前请求期间使用的变量值的任何知识。 ASP.NET会话状态将在有限时间窗口内来自同一浏览器的请求标识为会话,并提供一种持久化该会话期间变量值的方法。默认情况下,所有ASP.NET应用程序都启用了ASP.NET会话状态。”
“会话状态的替代方法包括以下内容:”
“应用程序状态,它存储可以由ASP.NET应用程序的所有用户访问的变量。”
这一点是存储状态的极其常见的方法,但涉及多个应用程序实例时会出现问题(状态只对其中一个实例“可见”)。
通常可以通过使用StateServerSQLServer值的SessionStateMode来解决这个问题。同一篇文章提供了每个选项的摘要(强调是我的)。
  • StateServer模式,将会话状态存储在称为ASP.NET状态服务的单独进程中。这确保了如果Web应用程序重新启动,会话状态得以保存并且会话状态可用于Web农场中的多个Web服务器。
  • SQLServer模式将会话状态存储在SQL Server数据库中。这确保了如果Web应用程序重新启动,会话状态得以保存并且会话状态可用于Web农场中的多个Web服务器。
如果您的应用程序是无状态的,则此问题无关紧要。
至于访问数据库的多个应用程序实例的问题,任何数据访问技术都会有问题。
以下是基本情况:假设您的应用程序按计划向用户发送欢迎电子邮件。

给定表格 Users:

UserId | Email           | WelcomeLetterSent
-------+-----------------+------------------
     1 | user@domain.com | 0

还有一些伪代码:

foreach (var user in _context.Users.Where(u => !u.WelcomeLetterSent))
{
    SendEmailForUser(user);
    user.WelcomeLetterSent = true;
}

_context.SaveChanges();

在您的应用程序中,有一个竞态条件,即实例一和实例二可能会同时评估_context.Users.Where(...),在它们中任何一个有机会设置WelcomeLetterSent = true并调用SaveChanges之前。在这种情况下,每个用户可能会收到两封欢迎电子邮件而不是一封。

并发可能是一件隐蔽的事情。有一个关于使用Entity Framework管理并发的入门指南此处,但这只是冰山一角。

您的问题的答案?这取决于您的应用程序要做什么 :)

除此之外,我理想情况下还想构建一些“额外”的支持应用程序,这些应用程序连接到同一个数据库......,但我不确定EF将如何处理多个应用程序连接到同一个DB....

如果您的应用程序可以容忍多个实例访问一个数据库,那么使这些“支持应用程序”和谐运行通常不是问题。无论并发性是来自一个应用程序的多个实例还是每个实例的多个应用程序,情况都不会有太大区别。

你没有提到EF迁移。在不关闭所有服务器的情况下,你如何执行迁移? - Kugel
@Kugel 把它们全部摧毁。OP没有要求100%的可用性。 - ta.speot.is

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接