首页 新闻 会员 周边 捐助

IIS WebApi CPU 使用 率占满

0
悬赏园豆:20 [已解决问题] 解决于 2023-03-27 16:19

在IIS上部署了一个WebAPI站点给客户的一个轮询程序调用,发现api被调用一段时间后CPU就满了。(IIS只部署了Webapi,没有其他站点)如下图:

 

这是任务管理器的截图:(这里是提前截图的,后面iisworker的进程CPU使用率到了90%+)

这是服务器配置:

 


这是api程序池配置:

 

业务场景是:我们提供了2个接口,1、新增订单;2、根据订单号返回发货状态;

新增订单:根据之前的需求,他们每天新增的订单就几十单,很零散;一般是当天下单当天晚上就会发货。(偶尔有几单是推迟一两天发货的)

根据订单号返回发货状态:现在设置的是服务轮询,每分钟执行,查询已下单未发货的订单状态。
上周出现这种情况的时候是他们每分钟执行一次,一次大概1000个请求过来,本来就是个很简单的接口,因为他们测试数据都没删所以有这么多,正常就大概几十到三四百的样,我也没做并发相关的设置和优化。
接口里面也是直接每次根据单号来查询数据库,然后返回结果;

代码如下:

View Code

查询数据库的代码,用的Dapper:

View Code

 

后面我担心再次遇到这种情况,就改了下代码用redis缓存了已发货的单号,每两个小时更新一次;今天他们改成了10分钟请求一次,一次大概几十-200个请求;今天晚上只有80几个订单,轮询调用接口,又把CPU占满了。

 1  public IHttpActionResult GetDNS1(int OrderNum)
 2         {
 3             ApiResult result = new ApiResult();
 4             try
 5             {
 6                 result.RS_FLAG = "Y";
 7                 result.Data = "未发货";
 8                 if (OrderNum <= 0)
 9                 {
10                     result.RS_FLAG = "N";
11                     result.RS_MSG = "销售单号不正确!";
12                     return Json(result);
13                 }
14                 Nloger.Info(string.Format("销售单号:{0}", OrderNum));
15              
16                 if (RedisHelper.KeyExists("SHtime"))
17                 {
18                     List<string> listsh = RedisHelper.ListRange("SH");
19                     if (listsh.IndexOf(OrderNum.ToString()) > -1)
20                     {
21                         result.RS_FLAG = "Y";
22                         result.Data = "已发货";
23                     }
24                     //foreach (string item in listsh)
25                     //{
26                     //    if (item == OrderNum.ToString())
27                     //    {
28                     //        result.RS_FLAG = "Y";
29                     //        result.Data = "已发货";
30                     //        break;
31                     //    }
32                     //}
33                 }
34                 else
35                 {   new RedisHelper();
36                     string DBName = WebConfigUnit.HANADB;
37                     string sql = string.Format("SELECT DISTINCT T0.\"DocEntry\" FROM  \"{0}\".\"ORDR\" T0 LEFT JOIN  \"{0}\".\"RDR1\" T1 ON T0.\"DocEntry\"=T1.\"DocEntry\" WHERE T0.\"CANCELED\"='N' AND T1.\"Quantity\">T1.\"OpenQty\"  AND T0.\"DocDueDate\">'{1}'", DBName, DateTime.Now.ToString("yyyy-MM-dd"));
38                     DataTable dt = new CommonLogic().ExcuteDT(WebConfigUnit.SBOConnectionString, sql);
39                     string sh = "未发货";
40                     if (dt != null)
41                     {
42                         RedisHelper.DeleteStringKey("SHtime");
43                         RedisHelper.ListTrim("SH");
44                         RedisHelper.SetStringKey("SHtime", "Y", TimeSpan.FromHours(2));
45                         foreach (DataRow item in dt.Rows)
46                         {
47                             RedisHelper.ListRightPush("SH", item["DocEntry"].ToString());
48                             if (item["DocEntry"].ToString() == OrderNum.ToString())
49                             {
50                                 sh = "已发货";
51                             }
52                         } 
53                     }
54                     result.Data = sh;
55 
56                 }
57                 Nloger.Info(string.Format("销售单发货状态:{0}", result.Data));
58                 return Json(result);
59             }
60             catch (Exception e)
61             {
62                 result.RS_FLAG = "N";
63                 result.RS_MSG = e.Message;
64                 Nloger.Error(e, "获取销售订单发货状态异常");
65             }
66             return Json(result);
67         }
View Code

另外有个校验ip的验证。

 1 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
 2     public class FilterAttribute : AuthorizeAttribute
 3     {
 4         public override void OnAuthorization(HttpActionContext actionContext)
 5         {
 6             //校验IP
 7             string ip = HttpContext.Current.Request.UserHostAddress;
 8             if (ip == "xxxxx" )
 9             {
10                 base.IsAuthorized(actionContext);
11             }
12             else
13             {
14                 actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
15                 {
16                     code = HttpStatusCode.Unauthorized,
17                     data = "",
18                     message = $"IP:{HttpContext.Current.Request.UserHostAddress}没有调用服务的权限",
19                 });
20             }
21         }
22     }
View Code

 

数据库在另外一台服务器上,这台服务器上还有其他应用程序部署;

个人感觉是哪里资源使用后没释放掉,一直占用,导致后面的进程阻塞,但是又找不到在哪里。

求教各位大神,帮忙分析指导一下是我的代码哪里有问题?iis设置是否有问题?

应该如何优化改正?

谢谢!

Vincent8464的主页 Vincent8464 | 初学一级 | 园豆:17
提问于:2022-04-17 22:31
< >
分享
最佳答案
0


这个地方的问题,open了,没释放,
不用open,daper会自动处理,打开释放

收获园豆:20
不知道风往哪儿吹 | 老鸟四级 |园豆:2037 | 2022-04-19 13:31

using会自动释放吧

灬丶 | 园豆:3 (初学一级) | 2022-04-22 16:54

@灬丶: using 释放的是IDbConnection对象,不是连接池里面最大连接数

不知道风往哪儿吹 | 园豆:2037 (老鸟四级) | 2022-04-24 13:40

@不知道风往哪儿吹: 但是using会给close掉的呀

labman004 | 园豆:214 (菜鸟二级) | 2022-05-12 17:01
其他回答(2)
0

就这么点代码很难看出什么来. 建议你dump一个内存快照. 拖到vs里面或者windbg里面 应该能很快找到问题.

czd890 | 园豆:14488 (专家六级) | 2022-04-18 13:19
0

35 { new RedisHelper();

这行代码是干嘛 每调用一次 new 一个redis 实例?

labman004 | 园豆:214 (菜鸟二级) | 2022-05-12 17:04
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册