Web API性能优化(一)压缩
简单的应用场景:分页获取日志JSON信息。
很简单的实现,简单的记录一下
未压缩时候
使用PostMan请求http://localhost:34390/api/gpm/syslog/page?pageindex=1&pagesize=10
上图用到了一些技术:AOP、IOC、Request/Response模式(个人觉得十分适合WebAPI),这里不介绍。ApiResullt是我封装的一个类(自动序列化),至于为什么自己造一个,只是本人觉得舒服!这个最重要。
响应结果:可以看到Size:2.04KB,Content-Length:1607
使用压缩
使用DotNetZip压缩,当然使用AOP方式,使用默认压缩级别
1 /// <summary> 2 /// 压缩返回信息 3 /// </summary> 4 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 5 public class CompressionAttribute : ActionFilterAttribute 6 { 7 public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 8 { 9 var content = actionExecutedContext.Response.Content; 10 var acceptEncoding = actionExecutedContext.Request.Headers.AcceptEncoding. 11 Where(x => x.Value == "gzip" || x.Value == "deflate").ToList(); 12 if (acceptEncoding.HasItems() && content != null && actionExecutedContext.Request.Method != HttpMethod.Options) 13 { 14 var first = acceptEncoding.FirstOrDefault(); 15 if (first != null) 16 { 17 var bytes = content.ReadAsByteArrayAsync().Result; 18 switch (first.Value) 19 { 20 case "gzip": 21 actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.GZipBytes(bytes)); 22 actionExecutedContext.Response.Content.Headers.Add("Content-Encoding", "gzip"); 23 break; 24 case "deflate": 25 actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.DeflateBytes(bytes)); 26 actionExecutedContext.Response.Content.Headers.Add("Content-encoding", "deflate"); 27 break; 28 } 29 } 30 } 31 base.OnActionExecuted(actionExecutedContext); 32 } 33 } 34 /// <summary> 35 /// 压缩帮助类 36 /// </summary> 37 internal static class CompressionHelper 38 { 39 public static byte[] DeflateBytes(byte[] bytes) 40 { 41 if (!bytes.HasItems()) 42 { 43 return null; 44 } 45 using (var output = new MemoryStream()) 46 { 47 using (var compressor = new Ionic.Zlib.DeflateStream(output, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.Default)) 48 { 49 compressor.Write(bytes, 0, bytes.Length); 50 } 51 return output.ToArray(); 52 } 53 } 54 55 public static byte[] GZipBytes(byte[] bytes) 56 { 57 if (!bytes.HasItems()) 58 { 59 return null; 60 } 61 using (var output = new MemoryStream()) 62 { 63 using (var compressor = new Ionic.Zlib.GZipStream(output, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.Default)) 64 { 65 compressor.Write(bytes, 0, bytes.Length); 66 } 67 return output.ToArray(); 68 } 69 } 70 }
请求响应结果:Size:833B,Content-Length:329,提升效果十分明显,细心的朋友会发现响应时间变长了,当然这是由于压缩需要时间造成的,但是影响不大