内容简介:构建高性能ASP.NET站点(上)
系列文章:
构建高性能ASP.NET站点 开篇
构建高性能ASP.NET站点之一 剖析页面的处理过程(前端)
构建高性能ASP.NET站点之二 优化HTTP请求(前端)
构建高性能ASP.NET站点之三 细节决定成败
构建高性能ASP.NET站点 第五章—性能调优综述(前篇)
大型高性能ASP.NET系统架构设计
构建高性能ASP.NET站点 第五章—性能调优综述(中篇)
构建高性能ASP.NET站点 第五章—性能调优综述(后篇)
构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(上篇)—识别性能瓶颈
构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(下前篇)—简单的优化措施
构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(下后篇)—减少不必要的请求
构建高性能ASP.NET站点 第七章 如何解决内存的问题(前篇)—托管资源优化—垃圾回收机制深度剖析
构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测CLR性能
本文是系列文章,第一篇介绍了开篇及构建高性能的前端及前篇。
构建高性能ASP.NET站点 开篇
网站优化需要考虑的方面
在用ASP.NET开发网站的时候,性能是永远需要考虑和关注的问题,性能不仅仅只是程序代码执行时候的速度,而是涉及到方方面面的东西。
就拿ASP.NET的一个请求来讲,从浏览器向服务器的ASP.NET网站发送请求开始一直到最后整个页面呈现在我们面前,其中请求经过的每一个步骤,都是有不同的调优方式的,而且调用的方法也很多,不仅仅只是常见的:缓存,多线程,异步等。
本系列的文章决定从两个大的方面来讲述调优:
前台调优:主要包含如何尽量的减少http请求,从http请求开始,到如何加载js, css,如何压缩传输的数据等。
后台调优:分析ASP.NET请求的处理过程,并在每一步给出相应的调优方法,而且在代码组织,架构和数据库的操作上面给出调优的方法。
记得在刚刚开发网站的时候,一提到提高性能,最容易也是最快想到的就是缓存,而且在微软官方的Best Practice的一些文档中也是建议:层层缓存(在数据存储层,DAL,BLL,UI等都要缓存)。然后在网站中就”缓存遍地开花”,最后的确实不尽人意。
另外的一个常见的优化针对数据库的:如尽量减少子查询,使用join联接;在常常需要查询的字段上面建立索引。确实,这些是很通用,也不错的一些规则。
而且还有一个体会就是,在优化性能的时候,如果选择优化代码和数据库,往往优化数据库的一些操作带来的效果会更加的好,很可惜的是:在项目中(至少在我开发的一些项目中),数据库仅仅就只是一个数据的存储设备而已,仅此而已,没有发挥出数据库的强大作用。所以还是建议对数据库的内部查询和存储的机制要熟悉,毕竟很多时候开发人员也担任了DBA的工作(很多公司没有正式的DBA)。
而且在项目中我们设计数据库的时候,特别是表字段的时候,是需要有些考虑的,很多人建议表字段的长度不要太长,这也是大家常见的建议,但是为什么?其实,这就需要懂得一些数据库的内部存储机制了:在数据库(SQL SERVER )保存的时候,数据是以”页”为最小的单位的,每一页有8K的大小,如果你的一个表中的数据超过8K,那么这个表的数据就要分几个页面保存,这样在对数据进行查询的时候,就要跨页查询了,跨页是需要性能消耗的,如果数据都在一个页面上,那么速度肯定快些。
所以,要优化网站,就得知道性能消耗在哪里。
当优化的一个网站的时候,不是盲目的一概而论的,一般来说有两种情况:
1. 网站已经存在了,并且运行了,现在要优化。
2. 正在从头开发一个新的网站。
如果是第一种情况,那么首先要找出网站性能的瓶颈,从前台的请求的到后台的请求处理,一直到最后页面的呈现,都要一步步的审查。
如果是第二种情况,可能情况就稍微好一点,并且网站现在完全由我们控制,所有在开发和设计的过程中就可以采用很多的优化原则来优化。
优化不一定就是代码重写或者做些很大的改动,优化时一点点的累积的,就好比代码的重构一样,都是一个积累的效果。比如,是在页面一开始的时候载入js脚本,还是在整个页面的最后载入js脚本,有时候往往就只是简单的调整一下载入的文件,或者异步的载入脚本,或者通过CDN传输脚本等等方法,性能就提升了。性能的提升也不是没有代价的,有的代价很小,例如只是把脚本的载入放在页面最后,大的代价就是,例如买些服务器设备,如Content Delivery Network(CDN)来把静态的文件(js,css,image)传送到客户端。所以说,优化需要权衡策略。
不知道大家是否有过这样的体会:当看着自己开发出来的系统性能很好的时候,自己是很自信的,相反,如果系统很慢,有时真不想说这个系统是自己做的。
构建高性能ASP.NET站点之一 剖析页面的处理过程(前端)
议题如下:
剖析页面的解析过程
分析出可能存在的优化点
剖析页面的解析过程
页面的解析过程,这里说的过程不是我们常说的ASP.NET页面的生命周期的过程,而且浏览器请求一个页面,然后浏览器呈现页面的过程。
在本篇的文章中,我会先阐述页面的解析过程,显示从整体上阐述,然后在每一个点上提出优化的方法。先整体,后局部。
当浏览器在请求一个Web页面是从URL开始的。下面就是过程描述:
1. 输入URL地址或者点击URL的一个链接
2. 浏览器根据URL地址,结合DNS,解析出URL对应的IP地址
3. 发送HTTP请求
4. 开始连接请求的服务器并且请求相关的内容(至于请求时怎么被处理的,我们这里暂时不讨论,只是后面的文章要讨论的问题)
5. 浏览器解析从服务器端返回的内容,并且把页面显现出来,同时也继续进行其他的请求。
上面基本上就是一个页面被请求到现实的过程。下面我们就开始剖析这个过程。
当输入URL之后,浏览器就要知道这个URL对应的IP是什么,只有知道了IP地址,浏览器才能准备的把请求发送到指定的服务器的具体IP和端口号上面。
浏览器的DNS解析器负责把URL解析为正确的IP地址。这个解析的工作是要花时间的,而且这个解析的时间段内,浏览器不是能从服务器那里下载到任何的东西的。但是这个解析的过程是可以优化的。试想,如果每次浏览器每次请求一个URL都需要解析,那么每次的请求都有一点的时间消耗,可能这个时间消耗很短,但是性能的提升就是一点点的“调”出来的。如果把对应URL和IP地址缓存起来,那么当再次请求相同的URL时,浏览器就不用去解析,而是直接读取缓存,这样势必会快一点。
其实浏览器和操纵系统是提供了这样的支持的。
当获得了IP地址之后,那么浏览器就向服务器发送HTTP的请求,下面我们就稍微看下这个发送请求是怎么样被发送的:
1. 浏览器通过发送一个TCP的包,要求服务器打开连接
2. 服务器也通过发送一个包来应答客户端的浏览器,告诉浏览器连接开了。
3. 浏览器发送一个HTTP的GET请求,这个请求包含了很多的东西了,例如我们常见的cookie和其他的head头信息。
这样,一个请求就算是发过去了。
请求发送去之后,之后就是服务器的事情了,服务器端的程序,例如,浏览器清楚的文件是一个ASP.NET的页面,那么服务器端就把请求通过IIS交给ASP.NET 运行时,最后进行一系列的活动之后,把最后的结果,当然,一般是以是以html的形式发送到客户端。
其实首先到达浏览器的就是html的那些文档,所谓的html的文档,就是纯粹的html代码,不包含什么图片,脚本,css等的。也就是页面的html结构。因为此时返回的只是页面的html结构。这个html文档的发送到浏览器的时间是很短的,一般是占整个响应时间的10%左右。
这样之后,那么页面的基本的骨架就在浏览器中了,下一步就是浏览器解析页面的过程,也就是一步步从上到下的解析html的骨架了。
如果此时在html文档中,遇到了img标签,那么浏览器就会发送HTTP请求到这个img响应的URL地址去获取图片,然后呈现出来。如果在html文档中有很多的图片,flash,那么浏览器就会一个个的请求,然后呈现。
到这里,大家也许感觉到这种方式有点慢了。确实这个图片等资源文件的请求的部分也是可以优化的。暂不说别的,如果每个图片都要请求,那么就要进行之前说的那些步骤:解析url,打开tcp连接等等。开连接也是要消耗资源的,就像我们在进行数据库访问一样,我们也是尽可能的少开数据库连接,多用连接池中的连接。道理一样,tcp连接也是可以重用的。但是重用也有问题:如果两个图片它们的url地址如下:
<img src="q2.gif" height="16" width="16" />
<img src="q3.gif" height="16" width="16" />
<img src="q4.gif" height="16" width="16" />
<img src="q5.gif" height="16" width="16" />
<img src="q6.gif" height="16" width="16" />
<img src="q7.gif" height="16" width="16" />
<img src="q8.gif" height="16" width="16" />
<img src="q9.gif" height="16" width="16" />
<img src="q10.gif" height="16" width="16" />
请求这些图片的时间消耗如下图:
大家首先看到最上面的黄线的部分,这个黄线就代表了浏览器打开连接,黄线的后半部分为蓝色,就表示浏览器请求到了html的文档。
最上面的第二条蓝线就表示第一个图片已经请求到了,此时请求这个图片使用还是之前的一个tcp的连接。
大家在看到第三条线,前部分是黄色的,表示请求第二个图片的时候又开了一个tcp的连接,这条线的后半部分为蓝色,表示图片已经请求到了。
剩下的要请求的一些图片都使用上一个tcp连接。
确实,tcp的连接时充分的被使用了,但是图片下载的速度确实慢了,从图中看出,图片是一个个的顺序的下载下来的。整个页面的响应时间可想而知。
如果采用下一种方式,如:
可以看出连接时多了,但是图片的几乎都是并行下载下来的,相比而言就快多了。
其实这就是一个权衡的问题了。
实际上浏览器也是内置了以一些优化方式的,例如缓存图片,脚本等。或者采用并行下载图片的方式,谈到并行下载,就如上图所看到的,势必会消耗更多的连接资源。
今天主要对页面的过程进行了初步的剖析,是的大家有个总体的把握,下一篇我们就开始逐步优化,敬请关注,也希望大家多多提出意见和反馈。先谢过了啊! :)
构建高性能ASP.NET站点之二 优化HTTP请求(前端)
HTTP请求的优化
在一个网页的请求过程中,其实整个页面的html结构(就是页面的那些html骨架)请求的时间是很短的,一般是占整个页面的请求时间的10%-20%.在页面加载的其余的时间实际上就是在加载页面中的那些flash,图片,脚本的资源. 一直到所有的资源载入之后,整个页面才能完整的展现在我们面前.
下面,我们就从一个页面开始讲述:
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <title>小洋,燕洋天</title>
5
6 <script type="text/javascript" src="../demo.js">
7 </script>
8
9 </head>
10 <body>
11 <div>
12 <img src="../images/1.gif" />
13 <img src="../images/2.gif" />
14 <img src="http://yanyangtian.cnblogs.com/image/3.gif" />
15 <img src="http://yanyangtian.cnblogs.com/image/4.gif" />
16 <img src="http://yanyangtian.cnblogs.com/image/5.gif" />
17 <img src="http://yanyangtian.cnblogs.com/image/6.gif" />
18 <img src="http://yanyangtian.cnblogs.com/image/7.gif" />
19 <img src="http://yanyangtian.cnblogs.com/image/8.gif" />
20 <img src="http://yanyangtian.cnblogs.com/image/7.gif" />
21 <img src="http://yanyangtian.cnblogs.com/image/8.gif" />
22 </div>
23 </body>
24 </html>
如果我们向服务器请求这个页面,客户端的浏览器首先请求到的数据就是html骨架,即:
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <title>小洋,燕洋天</title>
5
6 <script type="text/javascript" src="../demo.js">
7 </script>
8
9 </head>
10 <body>
11 <div>
12 <img src="../images/1.gif" />
13 <img src="../images/2.gif" />
14 <img src="http://yanyangtian.cnblogs.com/image/3.gif" />
15 <img src="http://yanyangtian.cnblogs.com/image/4.gif" />
16 <img src="http://yanyangtian.cnblogs.com/image/5.gif" />
17 <img src="http://yanyangtian.cnblogs.com/image/6.gif" />
18 <img src="http://yanyangtian.cnblogs.com/image/7.gif" />
19 <img src="http://yanyangtian.cnblogs.com/image/8.gif" />
20 <img src="http://yanyangtian.cnblogs.com/image/7.gif" />
21 <img src="http://yanyangtian.cnblogs.com/image/8.gif" />
22 </div>
23 </body>
24 </html>
在此之前,首先来普及一下页面加载的小知识:
当页面的html骨架载入了之后,浏览器就开始解析页面中标签,从上到下开始解析.
首先是head标签的解析,如果发现在head中有要引用的js脚本,那么浏览器此时就开始请求脚本,此时整个页面的解析过程就停了下来,一直到js请求完毕.
之后页面接着向下解析,如解析body标签,如果在body中有img标签,那么浏览器就会请求img的src对应的资源,如果有多个img标签,那么浏览器就一个个的解析,解析不会像js那样等待的,如果发现img的url地址是同一个地址,那么浏览器就会充分的利用这个已经打开的tcp连接顺序的去一个个的请求图片,如果发现有的img的url地址不同,那么浏览器就另开tcp连接,发送http请求.
注意之前请求js的区别:请求需要js,浏览器会一直等待,不在解析下面的html标签
但是解析到img的时候,尽管此时需要加载图片,但是页面的解析过程还是会继续下去的,然后决定是否发送新的tcp连接加载资源.
大家可能觉得这个之前的代码片段一样,确实代码是一样的,但是,在最开始的时候,发送到浏览器中的只是那些html的代码,任何的js脚本和图片还没有发送过来.
当html代码到了浏览器中,那么浏览器就开始一步步的解析这些代码了,只要遇到了需要加载的资源,浏览器就向服务器发出http请求,请求所需的资源.
整个页面的加载时间图如下:
大家从图中可以看出:
第一条线中分为一半黄色和一半蓝色,其实黄色的部分就代表了打开一个tcp连接花的时间,而后面的蓝色的部分就是请求整个html骨架文档的时间.可以看出,请求html骨架的时间是很短的.其余蓝色的线就表示了图片,脚本资源加载所花的时间.
很显然,这样页面的整个加载时间就很长了.因为页面的加载几乎是顺序的载入,时间就是所有资源加载时间的总和.
下面我们把上面的页面代码代为如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>小洋,燕洋天</title>
<script type="text/javascript" src="../demo.js">
</script>
</head>
<body>
<div>
<img src="http://demo1.com/images/1.gif" />
<img src="http://demo1.com/images/2.gif" />
<img src="http://demo2.com/image/3.gif" />
<img src="http://demo2.com/image/4.gif" />
<img src="http://demo3.com/image/5.gif" />
<img src="http://demo3/image/6.gif" />
<img src="http://demo4.com/image/7.gif" />
<img src="http://demo4.com/image/8.gif" />
<img src="http://yanyangtian.cnblogs.com/image/7.gif" />
<img src="http://yanyangtian.cnblogs.com/image/8.gif" />
</div>
</body>
</html>
我们再来看看页面的加载时间图
这就是所谓的”并行”载入了.
比较一下两段代码的不同:其实就在img的src属性上面:
第一段页面的代码:img的src属性都是指向一个域名的.
第二段页面的代码:img的src属性指向了不同的域名
这样做的结果是什么?
请大家注意比较img的src的不同.
解释之前,首先来看一个小的常识(在上篇文章中也提过):
当页面请求向服务器请求资源的时候,如果浏览器已经在客户端和服务器之前打开了一个tcp连接,而且请求的资源也在开了连接的服务器上,那么以后资源的请求就会充分的利用这个连接去获取资源. 这样也就是第一个时间图的由来.
如果请求的图片分别位于不同的服务器网站,或者那个请求的服务器网站有多个域名,那么因为浏览器就会为每一个域名去开一个tcp连接,发送http请求,这样,结果就是同时开了多tcp连接,这也是第二个时间图的由来.
虽然说并行加载,确实使得页面的载入快了不少,但是也不是每一个图片或者其他的资源都去搞一个不同的域名,像之前的第二个并行载入图片的例子,也是让两个图片利用一个tcp连接.如果每个图片都去开一个连接,这样浏览器就开了很多个连接,也是很费资源的,而且浏览器还可能会”僵死”.而且有时还会严重的影响性能.
所以,这是需要权衡的.
除了上面的优化方式,还有其他的图片优化的加载方式.主要是通过减少http的请求达到优化
大家都知道网站的一个menu菜单,有些菜单就是用图片作出来的.如
如果上面的图片一个个载入,势必影响速度,如果开多和请求,有点得不偿失.而且图片也不是很大,那么就一次把整个menu需要的图片作为整个图片,一次加载,然后通过map的方式,控制点击图片的位置来达到导航的效果.
这样一个问题就是:算出图片的坐标,不能点击了”主页”图片,然后却跳到了”帮助”页面了.
构建高性能ASP.NET站点之三 细节决定成败
本篇的议题如下:
问题的描述
细节的重要性
问题的描述
首先,描述一下故事的背景:(希望大家耐心的故事读完)
在网站中,网页中的分页控件每次显示10条数据,每次点击下一页,就再次去取下一个10条数据。至于分页的方法怎样做,方法有很多,相信这点大家都知道。
过程是这样的:在用户请求数据的时候(考虑到了用户的操作和网站的访问量)我会第一次取出500条数据,然后把数据放在缓存中,也就是说,我取出了50页的数据,放在缓存中,这样如果,以后用户请求第一页到第49页的时候,就直接从缓存中拿数据。
如下图:
第一个数据块:
采用键值对的形式:字典保存
如果用户请求到了49页以后,那么就再次从数据库中取出下一个数据块(包含501到1000数据),然后,现在内存中就有了1000条数据。
至于缓存多久,数据什么失效,失效后怎么做,这里暂不谈论。(网站在这种缓存策略下运行的很好)。
代码如下:
代码的意思很清楚,从缓存中拿数据,如果缓存中没有对应的数据,那么就先从数据库中拿500条数据,然后放在缓存中,最后返回10条数据。
后来,因为某些功能的需要,需要返回当前页的前6页数据和后6页的数据,例如:如果当前页是第12页,那么就要返回12页之前6页Product(也就是第6,7,8,9,10,11页的数据),和第12页后的页的Product(第13,14,15,16,17,18页的数据)。
如下:
当然,如果当前页是第5页,那么就把之前所有5页的数据都返回,另外再加上第5页之后的6页数据。
这里就可能涉及到跨块获取数据,如:
如果当前页是第48页的时候,那么返回前6页数据是没有什么问题的,那么后6页的数据就不足了,因为49,40也得数据可以从缓存的数据块中取到,至于51,52,53,54页的数据,就需要再次从数据库中读取,然后再次缓存(如果事先没有被缓存)。
最后在缓存中的数据如下:
然后调用方法:(伪码)
上面传入的是从第42页开始的数据,也就是第48页的前6页和后6页的数据。
这个方法的内部实现是这样的:
1. 首先从第一个数据块中取出42页到50页的数据
取出数据后保存在一个List<Product> firstProductList;
2. 从第二个数据块中取出从51页到54页(如果第二个数据块在缓存不存在,就去数据库中取501-1000条,然后再放在缓存的第二个数据块中)。
保存在第二个List<Product> secondProductList
3. 然后把两个list合并,返回结果。例如
secondProductList.Foreach(u=>firstProductList.Add(u));
基本的实现就是这样,看起来还行,也比较的合理,但是就是因为这个操作,从而导致服务器内存溢出。
大家想想看是什么原因。
细节的重要性
其实缓存的数据不是很多,是不足以让服务器内存溢出的,但是服务器还是出现了out of memory的异常。之前一直跑的很好,就是改了代码之后才出现问题的。
其实这就是由于一个最基本的错误产生的:引用类型。
下面就来分析下:
首先是从第一个数据块中取出数据,然后用
List<Product> firstProductList 引用指向取出的数据
然后从第二个数据块中取出数据,用
List<Product> secondProductList指向数据的引用
如下图
在第三步中采用
secondProductList.Foreach(u=>firstProductList.Add(u));
把secondProductList中的数据加入到firstProductList中,就因为是引用类型,其实实际操作的结果是:不断的在改变第一个数据块中的数据,使得第一个数据块中的数据逐渐的变多。
现在当前页是48页,采用上面的操作,致使第一个数据块中的数据增加了60条,
如果用户再次翻页,到了49页,那么第一个数据块中的数据又增多了60条
依此类推,最后导致了服务器内存的不足,致使服务器崩溃了。原本的“功臣”----缓存却成为了罪魁祸首。
其实这个问题的解决,只要改变一点点的代码就行了:
List<Product> firstProductList;
List<Product> secondProductList;
然后
List<Product> resultProductList=new List<Product>();然后分别把firstProductList,secondProductList遍历,加入到resultProductList就行了。
就这么简单。
一个小的细节,导致了大的问题。
不要忽视每一个细节。不要做没有比较的循环等操作,一定要审视代码,重构代码。
构建高性能ASP.NET站点 第五章—性能调优综述(前篇)
本章的议题如下:
性能调优的一般过程
利用分析 工具 分析页面加载信息
利用分析工具分析性能瓶颈
性能调优的一般过程
在解决性能问题之前首先要确认问题的所在,首先就来看看确保高性能的一般过程:
1. 持续监控
2. 设定性能目标
3. 持续改进
1. 持续监控
网站的性能总体来说受两个方面的影响:
一,我们可以控制的,例如代码;
二,我们不能控制的,例如访问用户的数量,或者服务器本身
特别是随着站点的访问量增大的时候,原来没有出现的问题,现在可能出来了,不同的阶段要解决的问题也是不一样的。所以很有必要对网站进行持续的监控, 趁早发现网站变慢的原因。本篇的后面部门会介绍一些我们可以使用的监控服务,来帮助我们做这些事情。
2. 设定性能目标
网站的性能如何,一个最直观的感受就是:打开这个站点之后,页面加载的时间,这也是说是访问者最直接的体验。很多的优化工作(不管是前台的优化还是后台的优化)都是为了让用户更快的看到所想看的页面和信息。我们后面的讨论很多时候都是以这个为目标的。
首先必须要明白“快”的含义:一个网站的响应速度多快才算是“快”?因为优化网站需要花费很大的时间和精力,如果网站本身已经很快了,例如网页呈现到用户眼前的时间是毫秒级别的,我们确实可以再花时间让它更快,但是这样做起来成本会更高!
3.持续改进
在进行性能优化的时候,要涉及到很多的东西,所以在进行优化的时候必须确认:进行的优化措施确实的提高了站点的性能。为了达到这个目的,有几个规则可以遵循:
1. 每次优化只改动一处。如果改动了很多处,那么这些改动之间可能相互的影响,最后产生一些奇奇怪怪的现象,有时候这些"优化措施"反而使得网站性能降低。而且如果一次改动多次,也不利于衡量那些"优化措施"真真正正提升了网站的性能。
2. 不断的测试。每次进行了所谓的"优化"之后,一定要测试一下,这个"优化"是否真的提升了性能,如果没有提升,那么就回滚这个操作。
一般进行优化的步骤如下:
1. 记录现在网站的性能指数和一些相关的数据(后面会告诉大家如何获取这些性能指数数据)
2. 诊断站点的性能故障点.可能有几个地方都影响了站点的性能,但是,此时我们只是选择影响最大的那个因数进行优化。
3. 解决找出的性能故障点。
4. 测试。收集数据,和优化前进行比较,看看是否提升了性能。
5. 重复1到4步骤。
上面虽然提出了一些规则,但是我们可以灵活处理某些情况:在我们查找影响性能的问题的时候,我们发现多个问题,而且这些问题根据我们的经验判断会影响性能,那么我们可以同时修改此处。
我们用一个流程图来总结上面的优化步骤。如下:
未完待续......
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 《高性能linux服务器构建实战》
- 构建高性能ASP.NET站点(下)
- 构建高性能ASP.NET站点(中)
- 如何构建基于 Ceph 的高性能云存储解决方案?
- 高阶:腾讯新闻构建高性能的 react 同构直出方案
- 直播预约 | 在生产环境中,阿里云如何构建高性能云原生容器网络?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。