对于以下几类任务,可能需要异步处理,即不是在接口中处理任务,而是在另一个调用作业中处理:
- 处理比较耗时、耗时CPU、内存资源
- 不很稳定、可能失败但又比较重要,若失败需要多尝试几次
- 请求量大、性能要求高。若放在接口中处理不方便拓展机器、负载等
主要程序流程图如下:
下面说下程序主要框架:
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 }
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 }
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 }
具体代码,我打包提交上来或者git上传,供各位参考