博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dotnet core高吞吐Http api服务组件FastHttpApi
阅读量:6231 次
发布时间:2019-06-22

本文共 6907 字,大约阅读时间需要 23 分钟。

简介

是dotNet core下基于实现的一个高度精简化和高吞吐的HTTP API服务开源组件,它并没有完全实现HTTP SERVER的所有功能,而是只实现了在APP和WEB中提供数据服务最常用两个指令GET/SET,满足在应用实现JSON,PROTOBUF和MSGPACK等基于HTTP的数据交互功能,虽然是一个精简版本但针对SSL这方面的安全性还是支持。有牺牲就必然有收获,FastHttpApi作出这么大的精简必然在性能上有所收获取,经测试FastHttpApi在GET/POST这些数据交互的场景下性能和吞吐能力是Asp.net core集成的Kestrel的要优胜许多。

使用便利性

FastHttpApi虽然在HTTP方面作了大量的精简,但并没有为此增加了它使用的复杂度。FastHttpApi具备asp.net core webapi的便利性;应用人员只需要制定和webapi一样的方法即可,在使用过程中和写普通逻辑方法没有多大的区别。

定义一个控制器

控制器用来定义具体相应URL处理的方法,只需要在类上定义Controller属性即可把类中的Public方法提供给Http访问;方法参数来源于QueryString,当参数标记为BodyParameter的时候参数来源于Http Body.

[Controller]    public class ControllerTest    {        //  /hello?name=        public string Hello(string name)        {            return DateTime.Now + " hello " + name;        }        // /add?a=&b=        public string Add(int a, int b)        {            return string.Format("{0}+{1}={2}", a, b, a + b);        }        // /post?name=        public object Post(string name, [BodyParameter] UserInfo data)        {            return data;        }        // /listcustomer?count        public IList
ListCustomer(int count) { return Customer.List(count); } // /listemployee?count public IList
ListEmployee(int count) { return Employee.List(count); } // post /AddEmployee public Employee AddEmployee([BodyParameter]Employee item) { return item; } }
Filter定义

Filter是Controller处理方法的拦载器,通Filter可以对所有方法进行统一拦载处理,如权限日志等。

[Controller]    [NotFoundFilter]    public class ControllerTest    {        //  /hello?name=        [SkipFilter(typeof(NotFoundFilter))]        [CustomFilter]        public string Hello(string name)        {            return DateTime.Now + " hello " + name;        }        // /add?a=&b=        public string Add(int a, int b)        {            return string.Format("{0}+{1}={2}", a, b, a + b);        }    }    public class GlobalFilter : FilterAttribute    {        public override void Execute(ActionContext context)        {            Console.WriteLine(DateTime.Now + " globalFilter execting...");            context.Execute();            Console.WriteLine(DateTime.Now + " globalFilter executed");        }    }    public class NotFoundFilter : FilterAttribute    {        public override void Execute(ActionContext context)        {            Console.WriteLine(DateTime.Now + " NotFoundFilter execting...");            context.Response.NotFound();            Console.WriteLine(DateTime.Now + " NotFoundFilter executed");        }    }    public class CustomFilter : FilterAttribute    {        public override void Execute(ActionContext context)        {            Console.WriteLine(DateTime.Now + " CustomFilter execting...");            context.Execute();            Console.WriteLine(DateTime.Now + " CustomFilter executed");        }    }
启动服务
static void Main(string[] args)        {            mApiServer = new BeetleX.FastHttpApi.HttpApiServer();            mApiServer.Register(typeof(Program).Assembly);            mApiServer.ServerConfig.BodySerializer = new BeetleX.FastHttpApi.JsonBodySerializer();            mApiServer.Open();            Console.Read();        }

制定HTTP Body转换器

转换器是组件最常用的自定义功能,通过它可以实现不同种类的数据格式,如json,protobuf和msgpack等。以下是一个json转换器的实现

public class JsonBodySerializer : IBodySerializer    {        public JsonBodySerializer()        {            ContentType = "application/json";        }        public string ContentType { get; set; }        public object GetInnerError(Exception e, HttpResponse response, bool outputStackTrace)        {            return new ErrorResult { url = response.Request.Url, code = 500, error = e.Message, stackTrace = outputStackTrace? e.StackTrace:null };        }        public object GetNotSupport(HttpResponse response)        {            return new ErrorResult { url = response.Request.Url, code = 403, error = response.Request.Method + " method type not support" };        }        public object GetNotFoundData(HttpResponse response)        {            return new ErrorResult { url = response.Request.Url, code = 404 };        }        public class ErrorResult        {            public string url { get; set; }            public int code { get; set; }            public string error { get; set; }            public string stackTrace { get; set; }        }        public virtual int Serialize(PipeStream stream, object data)        {            int length = stream.CacheLength;            string value = Newtonsoft.Json.JsonConvert.SerializeObject(data);            stream.Write(value);            return stream.CacheLength - length;        }        public virtual bool TryDeserialize(PipeStream stream, int length, Type type, out object data)        {            data = null;            if (stream.Length >= length)            {                string value = stream.ReadString(length);                if (type != null)                {                    data = Newtonsoft.Json.JsonConvert.DeserializeObject(value,type);                }                else                {                    data = Newtonsoft.Json.JsonConvert.DeserializeObject(value);                }                return true;            }            return false;        }    }

性能对比测试

由于dotnet core下面没有其他简化的http api组件,只能拿Kestrel asp.net core来作对比,虽然对asp.net core不公平,但这样的对比测也只是为了体现简化后的性能回报;测试服务器是阿里云的4核虚拟机,8G内存,测试工具是AB,测试功能主要是针对GET/POST的json数据处理。由于Kestrel asp.net core默认不支持AB的Keep-Alive选项,所以测试结果就并没有针对asp.net core的Keep-Alive测试

Kestrel asp.net core代码
// GET api/values/5        [HttpGet("{id}")]        public ActionResult Get(int id)        {            return new JsonResult(Employee.List(id));        }        // POST api/values        [HttpPost]        public ActionResult Post([FromBody] Employee value)        {            return new JsonResult(value);        }
FastHttpApi 代码
// /listemployee?count        public IList
ListEmployee(int count) { return Employee.List(count); } // post /AddEmployee public Employee AddEmployee([BodyParameter]Employee item) { return item; }
Kestrel asp.net core GET测试结果

FastHttpApi GET测试结果

FastHttpApi GET测试结果开启Keep-Alive

Kestrel asp.net core POST测试结果

FastHttpApi POST测试结果

FastHttpApi POST测试结果开启Keep-Alive

针对Kestrel的对比测试

对比一下两者在accept connection上的性能差异,开启了两个AB实例同时进行压测,结果是FastHttpApi在处理并发数快高于Kestrel快一倍的情况,CPU使用率只有Kestrel的一半。

Kestrel代码
public void Configure(IApplicationBuilder app, IHostingEnvironment env)        {            app.Run(context =>            {                byte[] data = System.Text.Encoding.UTF8.GetBytes(DateTime.Now.ToString());                return context.Response.Body.WriteAsync(data, 0, data.Length);            });        }
FastHttpApi代码
//  /hello?name=        public string Hello(string name)        {            return DateTime.Now + " hello " + name;        }
Kestrel测试结果

FastHttpApi测试结果

转载地址:http://rvqna.baihongyu.com/

你可能感兴趣的文章
Django搭建个人博客:文章标签功能
查看>>
63. Unique Paths II
查看>>
989-数组形式的整数加法
查看>>
Redis 源码分析之故障转移
查看>>
React as a UI Runtime(四、条件)
查看>>
阿里云MWC 2019发布7款重磅产品,助力全球企业迈向智能化
查看>>
使用Logtail采集Kubernetes上挂载的NAS日志
查看>>
电脑录音软件哪个好,怎么用电脑录音
查看>>
《前端十年-我将一切告诉你》人物关系图
查看>>
angular js中的依赖注入是什么?
查看>>
聊聊 Array 中的坑
查看>>
修改golang源代码获取goroutine id实现ThreadLocal
查看>>
Flutter尝鲜2——动画处理<基础>
查看>>
【Redis源码分析】Redis的压缩列表ZipList
查看>>
【学习笔记】CSS深入理解之line-height
查看>>
41. 缺失的第一个正数
查看>>
【C++】 47_父子间的冲突
查看>>
[LeetCode] 694. Number of Distinct Islands
查看>>
文章收藏夹
查看>>
PHP设计模式(五)建造者模式(Builder)
查看>>