WebAPi的可视化输出模式

WebAPi的可视化输出模式,第1张

WebAPi的可视化输出模式(RabbitMQ、消息补偿相关)所有webapi似乎都缺失的一个功能

最近在做一个关于消息发送和接收封装的工作。过程是这样的。消息中间件采用rabbitmq。为了确保消息绝对不会丢失,我们需要在发送和接收消息之前对其进行DB处理。发之前我会插入DB,单表,所以性能上可以接受。插入一个表基本上需要一到两毫秒,再加上消息的发送(带ACK)和两个节点(一个磁盘持久性节点)的高可用性。单个TPS基本在2000-3000左右。这对于我们的业务场景来说已经足够了。一旦消息丢失或者业务不会因为网络问题或者集群问题而中断,消息发不出去也没关系。我们会补偿消息或者补偿同步api调用。这是架构设计中必须考虑的方案A、方案B、方案C。这就是敬畏或者危机意识。

你可能又要说两个节点或者三个节点的集群怎么会有问题,那你就错了,大错特错。只能说明你不知道什么是分布式系统,不知道分布式系统的特点。可能你不知道由于网络抖动和网络闪断导致套接字断开时如何重试心跳。Rabbitmq连接仍然有效。当你的网络极度不稳定,你的linuxkeepalivedVIP来回漂移的时候,你的ARP根本无法有效,甚至可能连广播都无法传输,而客户端却一直在使用一个无用的IP地址。当你的集群节点连不成一个整体的时候,各种奇葩问题又来了。这些都是可能导致你所在集群出现问题的原因,千万不要大意。

(后面我会专门整理一篇文章“/s2/]rabbitmq高可用性和故障转移集群架构”“/s2/],这里就不继续介绍了)

这是一个伏笔。本文的重点是介绍我正在尝试使用的visualwebapi的输出模式,看起来比原来的json输出模式方便很多。如果你的api提供两种输出模式,人性化绝对好。现在很多后端API都没有接口,只提供一个json输出。然而,我们真的需要一个可读的输出模式。

我开发消息补偿程序的时候,借鉴了这个思路,尝试了一下。让我们看一下整体架构蓝图:

本文将介绍这个补偿程序的api的可视化输出。并没有涉及太多的信息,只是为了让这个视觉输出看起来容易理解。这个补偿程序需要查询并比较发送的消息和接收的消息,然后输出它,以确定消息的发送是失败还是成功。简单的逻辑就是在一定时间内对比消息发送表和消息接收表,然后匹配消息id。

我想知道这些数据反馈到api后会是什么样子。根据常规设计,有两个字段:

/// <summary>     /// 接受的消息对象。     /// </summary>     public class ReceiveMessage     {         /// <summary>         /// 发送消息ID。         /// </summary>         public string SendMessageId { get; set; }         /// <summary>         /// 接受消息ID。         /// </summary>         public string ReceiveMessageId { get; set; }     }

表示该消息从发送到接收的过程。如果失败,可能只有SendMessageId,而没有ReceiveMessageId。然后,我会自动补偿没有ReceiveMessageId的消息。开发的时候只有几十条消息,输出到postman看起来还可以,但是不直观。

GetReceiveMessage是获取已接受消息的列表,即检查当前发送到接受的消息的状态。

/// <summary>     /// 处理成功消息对象。     /// </summary>     public class SuccessMessage     {         /// <summary>         /// 发送消息ID         /// </summary>         public string SendMessageId { get; set; }         /// <summary>         /// 接受消息ID         /// </summary>         public string ReceiveMessageId { get; set; }         /// <summary>         /// 处理成功消息ID         /// </summary>         public string SuccessMessageId { get; set; }     }


SuccessMessage表示成功消息的处理。可能有SendMessageId和ReceiveMessageId消息,但可能没有SuccessMessageId。它将为成功处理的消息发送。

突然受到_catendpointofElasticSearch的启发。看来我可以在这里试试。webapi有两种输出模式,一种是供程序使用的json输出模式,一种是供人们阅读的text/plain模式,第二种模式可以简单理解为行到行转换的默认模式。

看起来舒服吗?检查消息的时间段是很有帮助的,但是如果你仍然遵循原来的json输出模式,可能看起来很难。

我们来看看基本的api设计,为了保证你所有的api支持?v可视化模式,需要一些抽象:

需要定义一个ViewModel,所有的数据都会输出这个对象。当然,我只是简单地将其封装在这里。如果可以,其实可以具体提取一个库,包括文本输出的自动化。

让我们来看看BaseApiController:

public class BaseApiController : ApiController     {         public class ViewModel         {             public string Content { get; set; }             public object JsonObject { get; set; }             public bool Success = true;         }         protected bool IsView;         private const string ViewQuerystring = "?v";         public ViewModel ResultModel;         private const string CheckToken = "CheckToken";         private const string Token = "49BBD022-CDBF-4F94-80E4-5BCACB1192EC";         private bool _checkStatus;         public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)         {             //验证token             if (controllerContext.Request.Headers != null && controllerContext.Request.Headers.Contains(CheckToken))             {                 var requestToken = controllerContext.Request.Headers.GetValues(CheckToken).FirstOrDefault();                 if (requestToken != null && requestToken.Equals(Token))                 {                     this._checkStatus = true;                 }             }             if (!_checkStatus)             {                 var checkResult = new Task<HttpResponseMessage>(() => new HttpResponseMessage                 {                     Content = new StringContent("非法访问,缺少token", Encoding.UTF8, "text/plain")                 }, cancellationToken);                 checkResult.Start();                 return checkResult;             }             if (controllerContext.Request.RequestUri.Query.Equals(ViewQuerystring))                 this.IsView = true;             base.ExecuteAsync(controllerContext, cancellationToken);             //text模式             if (this.IsView)             {                 var textResult = new Task<HttpResponseMessage>(() => new HttpResponseMessage                 {                     Content = new StringContent(this.ResultModel.Content, Encoding.UTF8, "text/plain")                 }, cancellationToken);                 textResult.Start();                 return textResult;             }             //json模式             var resultData = new Result<object>             {                 Data = this.ResultModel.JsonObject,                 Type = this.ResultModel.Success ? ResultType.Successfully : ResultType.Failure             };             var jsonResult = new Task<HttpResponseMessage>(() => new HttpResponseMessage             {                 Content = new ObjectContent(typeof(Result), resultData, new JsonMediaTypeFormatter(), "application/json")             }, cancellationToken);             jsonResult.Start();             return jsonResult;         }     }

代码非常简单。这里给我们一个启发,webapi是否真的缺乏可视化模式。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/778111.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-03
下一篇 2022-05-03

发表评论

登录后才能评论

评论列表(0条)

保存