dotnet core高吞吐Http api服务组件FastHttpApi

栏目: 后端 · 前端 · 发布时间: 7年前

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

简介

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

https://github.com/IKende/FastHttpApi

使用便利性

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<Customer> ListCustomer(int count)
        {
            return Customer.List(count);
        }
        // /listemployee?count
        public IList<Employee> 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<Employee> ListEmployee(int count)
        {
            return Employee.List(count);
        }
        // post /AddEmployee 
        public Employee AddEmployee([BodyParameter]Employee item)
        {
            return item;
        }

Kestrel asp.net core GET测试结果

dotnet core高吞吐Http api服务组件FastHttpApi

FastHttpApi GET测试结果

dotnet core高吞吐Http api服务组件FastHttpApi

FastHttpApi GET测试结果开启Keep-Alive

dotnet core高吞吐Http api服务组件FastHttpApi

Kestrel asp.net core POST测试结果

dotnet core高吞吐Http api服务组件FastHttpApi

FastHttpApi POST测试结果

dotnet core高吞吐Http api服务组件FastHttpApi

FastHttpApi POST测试结果开启Keep-Alive

dotnet core高吞吐Http api服务组件FastHttpApi

针对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);
            });
        }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Alone Together

Alone Together

Sherry Turkle / Basic Books / 2011-1-11 / USD 28.95

Consider Facebookit’s human contact, only easier to engage with and easier to avoid. Developing technology promises closeness. Sometimes it delivers, but much of our modern life leaves us less connect......一起来看看 《Alone Together》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器