如何最好地解决 InProc 会话状态变量\多实例问题?
我最近的任务是修复一个由于滥用会话状态而导致的相当严重的错误。我们有一个使用 inproc 会话状态在单个服务器上运行的 ASP.NET Web 应用程序。基本设计是从数据库加载类型化数据集,并使用通用会话变量名称(如 Session["dataset"] = dataset)将其存储在会话状态中。将数据存储在会话中后,用户编辑数据,从更新的会话中检索数据集并将其发送到数据库进行更新。这种类型的数据编辑/存储用于多个网络表单,这些表单基本上执行相同的操作。一切都很好,直到用户尝试启动应用程序的第二个实例并且会话变量中存储的数据可能会混淆。
以下是我找到的可能的修复方法
Set sessionState cookieless="false" (每个新实例都有一个唯一的会话 ID) PROS - 最简单的解决方案,几乎不需要更改代码 缺点 - url 中的 guid,用户可以编辑 guid,可以复制 guid
为每个实例使用自定义会话密钥(传递会话密钥并将其与“数据集”+会话密钥名称组合起来,以便每个实例都有唯一的会话变量) 优点 - 网址中没有 guid 缺点 - 大部分代码更改,可能很脆弱
删除会话变量(再次从数据库加载数据集进行编辑) PROS-释放服务器资源,不再依赖于会话状态 缺点 - 性能受到影响,代码更改量很大
有人知道任何其他可能的解决方案吗?谢谢
I've recently been tasked with fixing a rather nasty bug resulting from the misuse of session state. We have an asp.net web application that runs on a single sever using inproc session state. The basic design is that a typed dataset is loaded from the database and stored in session state using a common session variable name like Session["dataset"] = dataset. After the data is stored in the session the user edits the data, dataset is retrieved from the session updated and sent to the database for updating. This type of data editing\storing is used across multiple webforms that basically do the same thing. All is good until a user tries to launch a second instance of the application and data stored within the session variable can get mixed up.
Here are the possible fixes that I've been able to find
Set sessionState cookieless="false" (every new instance gets a unique session id)
PROS - easiest solution, almost no code changes needed
CONS - guid in url, user can edit guid, guid can be copiedUse a custom session key for every instance (pass a session key around and combine it the "dataset" + session key name so that each instance has a unique session variable)
PROS - no guid in url
CONS - most amount of code changes, possibly fragileRemove the session variable (Load the dataset from the database a second time for editing)
PROS- frees up server resources, no longer dependent upon session state
CONS - performance hit, high amount of code changes
Anyone know of any other possible solutions? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,保证两个实例不会访问相同会话状态的唯一方法是对 url/POST-data 执行某些操作。这就是你必须玩的东西。
最简单的可能是使用 cookieless=true,并希望所有 url:s 都能正确重写。最好的方法可能是直接访问数据库,很可能它不会影响你想象的那么多,如果它影响了,你真的不应该为每个用户缓存大量数据,而是应该使用全局缓存。
Well, the only way to guarantee that two instances won't access the same sessionstate is to do something with the url/POST-data. That's what you have to play with.
Easiest is probably going to be to use cookieless=true, and hope that all url:s get rewritten correctly. Best will probably be to just access the database directly, most likely it won't affect as much as you think, and if it affects, you really shouldn't cache a lot of data per user, instead you should use a global cache.
您说第三个选项会影响性能(完全删除会话对象),但是您尝试过吗?
我问,因为序列化标准数据集 在服务器端是众所周知的资源密集型 - 在许多情况下,内存占用量可能会增加一个数量级(1MB 数据集可能需要 10-15MB 进行序列化) ,以及执行此操作的处理器时间。
我真的建议尝试 3 并进行测试,看看您的担忧是否有根据,或者您是否确实看到了性能提升;)
如果您打算在会话中存储数据集,那么您应该查看 自定义序列化最大限度地减少存储的数据量。
You state that the third option would be a performance hit (remove the session object altogether), but have you tried it?
I ask, because serialising a standard dataset is notoriously resource intensive on the server side - the memory footprint can increase by an order of magnitude in many cases (a 1MB dataset can take 10-15MB to serialise), as well as processor time to do this.
I'd really recommend looking at trying 3 and testing to see if your concerns are well founded, or if you actually see a performance gain ;)
If you are set on storing datasets in session, then you should look at custom serialisation to minimise the amount of data stored.