我不知所措,欢迎任何建议。这段代码看似简单,但Async可能会使事情变得复杂并导致问题。
当数据字节小于3802时,POST方法起作用。当POST数据大于3802时,数据在3800或3801被截断。这需要一段时间来捕获我们,因为大多数时间数据是< 3800.我终于添加了调试日志记录并看到了断开连接。
我一直在对异步进行额外的阅读,目前不相信这段代码存在问题。我知道异步void会引起火灾并忘记,但是我们有一个try / catch,所以我希望错误显示在日志中而不会因为异常而导致整个程序失效。不过,我欢迎提出改进建议。
[HttpPost("{instance}/{objectType}")]
public async void Post( [FromRoute] string instance, [FromRoute] string objectType )
{
Log.Debug("Incoming post(instance/objectype)");
string content = "";
try
{
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
// have a scenario where conlen below is always cut off at 3800 or 3801 bytes
// wild guess is that it is a async/threadpool issue?
content = await reader.ReadToEndAsync();
}
var conlen = (content != null) ? content.Length : 0;
var contentbegin = (content != null) ? content.Substring(0, Math.Min(conlen, 80)) : "";
Log.Debug("POST {objecttype} {contentlen} {contentbegin}", objectType, conlen, contentbegin);
await ProcessPost(objectType, content, instance);
}
catch (Exception ex)
{
Log.Error("Exception in Post {msg} {trace}", ex.Message, ex.StackTrace);
Log.Error("Exception in Post offending message {msg} ", content);
}
}
以下是日志示例。您可以看到数据的大小> 3800,但是,当我们去读它时,我们正在被切断。
[19:27:57 INF] Request starting HTTP/1.0 POST http://backend.example.com/orderinput application/json 5459
[19:27:57 INF] Executing action method Controllers.ValuesController.Post (Test) with arguments (["Production", "orderinput"]) - ModelState is Valid
[19:27:57 DBG] Incoming post(instance/objectype)
[19:27:57 INF] Executed action Controllers.ValuesController.Post (Test) in 0.4701ms
[19:27:57 INF] Request finished in 0.789ms 200
[19:27:57 DBG] POST orderinput 3801 {"SAMPLE":"1234567890.........
[19:27:57 DBG] Enter ProcessPost
[19:27:57 DBG] Persisting post
[19:27:57 ERR] Exception in ProcessPost DB Persist Unexpected end of content while loading JObject. Path 'customer_id', line 1, position 3801.
编辑:
为什么我认为这个代码是一个问题?
在日志第1行的末尾,ASP.NET有助于输入内容长度5459.第6行有我的计算,它显示3801.除非长度超过3802,否则这两个数字总是相同的。
提交的数据如何?我有没有尝试过?
数据来自另一个不受我控制的网络服务,通过NGINX代理。感谢您的建议,无论是否使用代理,在3802上方和下方都会执行此操作,并在此处报告结果。鉴于ASP.NET日志和我的计算之间的脱节,这似乎是一个长镜头,但所有道路都值得下降。
答案 0 :(得分:0)
我放弃了由另一位开发人员编写的代码库,并从头开始解决了此问题。我认为同步/异步被任意混合的事实是问题所在,而这种奇怪的症状就是结果。我在最终解决方案中使用nito asyncex来将Rabbit库与Async调用隔离开来,对于Asp.Net Web API,我将所有传入数据都发布到了队列中,并且该队列在与Rabbit专门交谈的单独线程中运行。自重写以来没有任何问题。