zoukankan      html  css  js  c++  java
  • 一种异步作业处理请求任务的简单实现(以短信发送为例)

    对于以下几类任务,可能需要异步处理,即不是在接口中处理任务,而是在另一个调用作业中处理:

    1. 处理比较耗时、耗时CPU、内存资源
    2. 不很稳定、可能失败但又比较重要,若失败需要多尝试几次
    3. 请求量大、性能要求高。若放在接口中处理不方便拓展机器、负载等

    主要程序流程图如下:

    下面说下程序主要框架:

    1.框架         

    1.Interface 短信发送请求接口,通过json类对象调用。只接受保存任务,状态-未处理。稍后异步在job里处理
    2.Job 异步的后端短信发送程序,一个个处理未发送的消息,含2个互备供应商,可切换
    3.Web 后台,查看任务处理情况、账号等
    4.Interface.Entity 接口模型实体,请求、响应类对象
    5.Test 接口请求测试项目,通过Entity的json序列化、http post参数形式请求Interface
    6.Model DB模型,含底层EF操作类库
    7.Service 主要业务逻辑封装
    8.Repository 主要DB对象封装

    2.接口

     1 public class InterfaceController : Controller
     2     {
     3         public void Index()
     4         {
     5             Response.Write("欢迎访问消息发送接口");
     6         }
     7 
     8         [HttpPost]
     9         public JsonResult Send()
    10         {
    11             MessageResponseEntity response;
    12             try
    13             {
    14                 string jsonRequest = GetPostData();
    15                 if (jsonRequest.IsNullOrWhiteSpace())
    16                 {
    17                     response = new MessageResponseEntity
    18                     {
    19                         TaskId = string.Empty,
    20                         SendStatus = SendStatus.SendFailure,
    21                         ResultDescription = "所有请求参数为空",
    22                     };
    23                 }
    24                 else
    25                 {
    26                     MessageRequestEntity request = JsonConvert.DeserializeObject<MessageRequestEntity>(jsonRequest);
    27                     var service = new SendService();
    28                     response = service.Verify(request);
    29                     if (response.SendStatus != SendStatus.SendFailure)
    30                         response = service.SaveMessage(request);
    31                 }
    32             }
    33             catch (Exception ex)
    34             {
    35                 response = new MessageResponseEntity
    36                 {
    37                     TaskId = string.Empty,
    38                     SendStatus = SendStatus.SendFailure,
    39                     ResultDescription = string.Format("服务器端出错,原因:{0},{1}",ex.Message,ex.StackTrace),
    40                 };
    41             }
    42             return Json(response);
    43         }
    44 
    45         public string GetPostData()
    46         {
    47             string postData = string.Empty;
    48             if (Request.RequestType == "POST")
    49             {
    50                 using (Stream sm = Request.InputStream)
    51                 {
    52                     int len = (int)sm.Length;
    53                     byte[] inputByts = new byte[len];
    54                     sm.Read(inputByts, 0, len);
    55                     postData = Server.UrlDecode(Encoding.GetEncoding(Encoding.UTF8.WebName).GetString(inputByts));
    56                 }
    57             }
    58             return postData;
    59         }
    60     }
    View Code

    3.调用方法:

    1             //调用测试
    2             var request = new MessageRequestEntity
    3             {
    4                 Content = "测试",
    5                 Receivers = "15951984463",
    6                 AccountGuid = "a8bfdd46-e7f6-4ad6-9fc6-ce69a9eb2633",
    7             };
    8             var response = CommTools.WebUtils.Post<MessageResponseEntity>("http://localhost:1952/Interface/send", request);
    9             Response.Write(string.Join(",", response.TaskId, response.SendStatus, response.ResultDescription));      

    4.处理作业

     1 public class HomeController : Controller
     2     {
     3         public static JobStatus JobStatus; 
     4 
     5         public ActionResult Index()
     6         {
     7             ViewBag.Message = "欢迎访问发送信息Job!  当前Job运行状态:" + JobStatus.ToString();
     8             return View();
     9         }
    10 
    11         public void StartJob()
    12         {
    13             Response.Write("发送信息Job已启动");
    14             JobStatus = JobStatus.Running;
    15             var taskOperation = new TaskOperation();
    16             while (true)
    17             {
    18                 taskOperation.SingleSendMessage();
    19                 Thread.Sleep(100);  //暂停100毫秒,即100毫秒处理一个消息发送任务
    20             }
    21         }
    22     }
    View Code
     1 public void SingleSendMessage()
     2         {
     3             var taskRepos = new TaskRepository();
     4             Task waitSendTask = taskRepos.GetTopWaitSendTask();
     5             if (waitSendTask != null)
     6             {
     7                 bool supplierResult;
     8                 int supplierId;
     9                 //指定模式:0-先提交供应商A,再提交B;1-只提交供应商A,对应A Id;2-只提交供应商B,对应B Id。
    10                 int supplierMode = int.Parse(ConfigurationManager.AppSettings["SupplierMode"]);
    11                 switch (supplierMode)
    12                 {
    13                     case 0: 
    14                         {
    15                             supplierId = 1;
    16                             supplierResult = new SupplierA().SendMessage(waitSendTask);
    17                             if (!supplierResult)    //提交供应商A失败则提交供应商B
    18                             {
    19                                 supplierId = 3;
    20                                 supplierResult = new SupplierB().SendMessage(waitSendTask);
    21                             }
    22                             break;
    23                         }
    24                     case 1:
    25                         {
    26                             supplierId = 1;
    27                             supplierResult = new SupplierA().SendMessage(waitSendTask);
    28                             break;
    29                         }
    30                     case 3:
    31                         {
    32                             supplierId = 3;
    33                             supplierResult = new SupplierB().SendMessage(waitSendTask);
    34                             break;
    35                         }
    36                     default:
    37                         {
    38                             supplierId = 1;
    39                             supplierResult = new SupplierA().SendMessage(waitSendTask);
    40                             break;
    41                         }
    42                 }
    43 
    44                 if(supplierResult)
    45                     taskRepos.TaskSendStatus(waitSendTask.TaskId, SendStatus.SendSuccess, "发送成功",supplierId);
    46                 else
    47                     taskRepos.TaskSendStatus(waitSendTask.TaskId, SendStatus.SendFailure, "发送失败:提交供应商失败", supplierId);
    48             }
    49         }
    View Code

    具体代码,我打包提交上来或者git上传,供各位参考

  • 相关阅读:
    汇总sql
    mybatis动态表名
    Windows下PHP(Thread Safe与Non Thread Safe)版本说明
    清除mssql日志
    ISAPI_Rewrite的一些参数
    sublime相关
    php301代码
    【备忘】win7下IIS 用FastCGI模块 配置PHP
    poj 2112 Optimal Milking floyd + 二分 + 最大流
    记录运行时间
  • 原文地址:https://www.cnblogs.com/nlh774/p/4862559.html
Copyright © 2011-2022 走看看