F5长连接测试.docx_第1页
F5长连接测试.docx_第2页
F5长连接测试.docx_第3页
F5长连接测试.docx_第4页
F5长连接测试.docx_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

F5 BIGIP MBLB 测试记录F5北京 杨明非2009年8月目录1. 测试环境31.1 测试环境准备31.2 测试网络拓扑31.3 BIGIP MBLB工作原理:42. V10 MBLB 测试过程52.1 TCP连接测试52.2 交易分发测试62.3 启动第二个客户端的连接建立过程及Timeout82.4 加入新的客户端观察负载均衡算法102.5 手工Disable服务器测试122.6 关闭服务器测试132.7 V10 MBLB 测试总结142.8 附:TCPdump数据包分析143. One Connect工作模式测试163.1 One Connect模式的工作原理173.2 TCP连接测试173.3 交易分发测试193.4 启动第二个客户端的连接203.5 启动多个客户端观察负载均衡算法223.6 手工Disable 服务器测试253.7 重新Enable服务器263.8 关闭服务器测试293.9 One Connect模式测试总结:304. 附录304.1 如何使用iRules来判断交易边界304.2 关于交易定向发送324.3 关于会话保持324.4 两种模式的对比324.5 还需要研究的部分321. 测试环境1.1 测试环境准备PC server一台,安装Windows 2003 Server.BIGIP 1台,安装10.0.1版本TCP Client/Server软件1.2 测试网络拓扑所有的IP地址均在同一个网段内,TCP client 和Server也运行在同一台设备上。通过启动多个不同的实例来模拟多台Server和Client。测试用BIGIP 配置virtual test_vs snat automap pool test_pool destination 3:9000 ip protocol tcp rules mblb-basic profiles mblb tcp pool test_pool monitor all tcp_half_open members 4:9000 4:9001 注意mblb的Profile是手工加入的,在图形界面里没有配置。另外对于这种类型的Server,最好使用tcp_half_open健康检查模式。rule mblb-basic when CLIENT_ACCEPTED TCP:collectwhen CLIENT_DATA TCP:release TCP:notify request #log client_data trigered TCP:collectwhen SERVER_CONNECTED TCP:collectwhen SERVER_DATA TCP:release TCP:notify response #log Server_data trigered TCP:collect1.3 BIGIP MBLB工作原理:客户端首先与BIGIP建立TCP连接,在客户端发送数据的时候,BIGIP根据交易将客户端请求发送到不同的服务器,在发送前,BIGIP将与后台服务器建立连接。在这种工作模式下,可以支持同步阻塞模式交易或者同连接里的异步交易。同步工作模式:Client1 RequestServer1 ResponseClient2 RequestServer2 ResponseClient1 RequestServer2 Response异步工作模式:Client1 RequestClient2 RequestClient1 RequestServer1 ResponseServer2 Response-Server3 Response在异步工作模式下,不能用下面测试的简单irules,需要使用iRules来判断每个交易的边界,以便将每笔交易请求分发到不同的服务器上。下面的测试基于小包状态,也就是每笔交易的长度不超过1个MTU,通常情况下是1460字节的情况,在这种情况下,在一次CLIENT_DATA事件触发的时候就可以接收到整个的交易请求或者交易回应。2. V10 MBLB 测试过程2.1 TCP连接测试首先启动两台Server,分别侦听9000和9001端口确认在BIGIP里显示两台服务器都是工作的。B conn显示没有任何的链接产生rootltm3600:Active config # b conn62:14774 4:ssh 4:ssh tcp 1/0上面的那个连接是我的SSH登录产生的。启动客户端,配置好发送的内容,点击Connect观察BIGIP上的连接状态:rootltm3600:Active config # b conn62:14774 4:ssh 4:ssh tcp 1/04:4933 3:9000 any6 tcp 1/1在客户端没有发送数据之前,在BIGIP上只有一个Client-Any6的连接,此时客户端还没有发送数据,因此BIGIP与后台并不建立连接。2.2 交易分发测试点击客户端上的发送按钮观察客户端的收发状态观察Server端收发状态观察BIGIP上的连接状态rootltm3600:Active config # b connany6 3:9000 4:9000 tcp 1/1any6 3:9000 4:9001 tcp 1/62:14774 4:ssh 4:ssh tcp 1/04:4933 3:9000 any6 tcp 1/1可以看到,在客户端开始发送数据后,BIGIP分别和两台Server建立了连接,并将客户端的请求以轮询的方式发送到两台服务器上。由于我在这里启用了SNAT,因此可以看到第一个Server连接是使用的客户端源端口和服务器建立连接,第二个客户端连接使用的另外一个源端口和服务器建立连接。2.3 启动第二个客户端的连接建立过程及Timeout启动第二个客户端建立连接观察BIGIP状态rootltm3600:Active config # b conn62:14774 4:ssh 4:ssh tcp 1/04:1088 3:9000 any6 tcp 1/0怎么没有Server端连接了呢?看看Server端日志,原来由于俺写文章的时间太长,被BIGIP timeout了。好,现在就让C2开始发送数据看到Server端又开始建立连接了BIGIP上的连接状态:rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/062:14774 4:ssh 4:ssh tcp 1/04:1088 3:9000 any6 tcp 1/0现在开始启动C1发送数据C1的连接也被断掉了:重新启动C1并连接BIGIP上状况:rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/062:14774 4:ssh 4:ssh tcp 1/04:1088 3:9000 any6 tcp 1/04:1144 3:9000 any6 tcp 1/0当C1开始发送数据的时候:rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/062:14774 4:ssh 4:ssh tcp 1/04:1088 3:9000 any6 tcp 1/04:1144 3:9000 any6 tcp 1/0Server上的状态:可以看到BIGIP针对每一个客户端连接,分别在每台Server上建立了同样数量的连接,并将请求在这些连接里进行分发。2.4 加入新的客户端观察负载均衡算法我们再启动C3, 看看有什么状况?BIIGProotltm3600:Active config # b connany6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/062:14774 4:ssh 4:ssh tcp 1/04:1088 3:9000 any6 tcp 1/04:1144 3:9000 any6 tcp 1/04:1231 3:9000 any6 tcp 1/1当C3开始发送数据的时候:Server状态:两台Server都收到了C3的请求BIGIP上显示3个client connection, 6个Server connection:rootltm3600:Active config # b connany6 3:9000 4:9000 tcp 1/1any6 3:9000 4:9001 tcp 1/1any6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/062:14774 4:ssh 4:ssh tcp 1/04:1088 3:9000 any6 tcp 1/04:1144 3:9000 any6 tcp 1/04:1231 3:9000 any6 tcp 1/1在S2上收到的是C1和C2的请求在S1上收到的是C1和C3的请求停止所有的客户端,然后全部重新发送的时候,Server端接收发生了变化:S1上收到的是C1和C2的请求S2上收到的是C1和C3的请求应该是Round Robin的算法导致了这种现象的出现BIGIP上的连接没有发生变化:rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/1any6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/1any6 3:9000 4:9000 tcp 1/1any6 3:9000 4:9001 tcp 1/0any6 3:9000 4:9000 tcp 1/62:14774 4:ssh 4:ssh tcp 1/04:1144 3:9000 any6 tcp 1/04:1231 3:9000 any6 tcp 1/4:1271 3:9000 any6 tcp 1/12.5 手工Disable服务器测试现在手工Disable一台服务器在S1上收到了3个客户端的请求恢复disable的服务器:S1收到了C1和C2的请求:S2重新开始接受请求,收到C1和C3的请求2.6 关闭服务器测试关闭S2所有的Client 和Server都崩溃了!等待服务器程序的改进版本中。2.7 V10 MBLB 测试总结BIGIP V10 已经具备了MBLB的处理能力,可以对长连接里面的TCP交易进行拆分处理,将不同的请求发送到不同的服务器上,并将服务器的返回信息发送到正确的客户端。目前发现的一些可能存在的问题:1、 对于每个客户端的长连接,BIGIP将在每个Server上建立一个连接,也就是说对于每台Server而言,都会有所有的客户端连接数的总和数量的连接,在实际应用中,需要确定服务器是否能处理全部客户端连接数量的连接数。2、 关于交易的边界定义,目前的测试中非常简单的使用了CLIENT_DATA和SERVER_DATA事件,这两个事件默认情况下是每接收一个数据包就触发一次,因此在交易小于1个MTU,通常情况是1460byte的情况下,可以不用区分交易边界,默认认为一个数据包就是一次交易。3、 如果每次发送交易的长度大于1460,就需要用irules去获取和判断交易的长度。具体的做法是在第一个数据包进来的时候查询数据包中对于交易长度的定义,然后判断当前收集到得数据是否是完整的交易,如果完整,则释放请求,如果不完整,则继续进行收集,直到收集到足够的数据后,释放交易长度的内容到服务器。4、 目前测试的应用时阻塞类型的应用,也就是Client必须等待Server应答之后才开始发送下一个请求,而且数据包都比较小,肯定在一个packet就发送完毕,因此不存在有边界界定的问题5、 如果有非阻塞型应用,也就是客户端可能一次发出多个请求,在不等待server回应的情况下可以持续发出请求,Server回应也是不等待的情况,从目前的连接状况分析也是可以工作的。但可能需要进一步的编程处理来确定每一个交易的边界6、 对于目前客户所要求的Disable服务器之后,所有的交易可以正常转发到其他服务器的需求是可以满足的。7、 基本确认这种MBLB工作模式和One Connect在目前测试配置中不能同时工作,因此当客户端关闭连接时,这个客户端对应的所有服务器连接都会被关闭。8、 从目前了解到得信息,One Connect工作模式下可以彻底的区分客户端连接和服务器端连接的关系,但服务器端的连接数量在One Connect模式下无法控制。9、 由于测试服务器软件问题,没有测试到Server端主动关闭连接,是否会造成客户端连接中断。另外,当一台server故障,而在健康检查还没有检查到服务器故障期间的交易如何处理目前测试环境中也无法测试。我的初步考虑是用inband monitor来解决普通Monitor的间隔周期和检查周期的问题。10、 还没有测试会话保持的情况,比如根据每个交易里的一些内容进行会话保持,还需要改进一下客户端和服务器软件2.8 附:TCPdump数据包分析客户端数据包发送和接收包25, 26, 27为三次握手建立连接149开始,客户端发送数据PSH,ACK,157为客户端收到一个BIGIP ACK,没有内容,表明Server已经收到客户端内容159 BIGIP给客户端发送数据PSH,ACK161 客户端给BIGIP发送ACK, 表明数据已经收到163 客户端等待1000ms后开始下一个数据包发送服务器端数据包发送和接收152,153,154为BIGIP和后台服务器三次握手建立连接,结合客户端连接建立时间,可以看到BIGIP一直等待到客户端有数据发送了才开始和后台建立连接155 BIGIP给服务器端发送数据 PSH,ACK158 服务器回应BIGIP数据 PSH,ACK160 BIGIP发送给服务器端ACK,表明数据已经收到164 在1000ms以后,BIGIP重新开始给服务器端发送数据包。数据流程图:比较有意思的地方:157和160看上去是BIGIP产生的主动发给客户端和服务器的ACK161从客户端发给BIGIP,但被BIGIP吞掉了。俺的TCP理论研究还不是很深刻,是不是一些协议性的东西导致必须这样工作?3. One Connect工作模式测试在前面的测试中,MBLB可以支持异步交易,但在一些同步工作模式下,应用希望两边的连接不存在有太大的关联性,前面一种模式客户端连接一旦中断后,服务器端这个客户端相关连接会全部中断。通过One Connect工作模式,可以消除掉这种强制的绑定关系,而使服务器端的连接不会和客户端强制绑定。因此可以在客户端是长连接和短连接模式下,BIGIP始终保持和后台服务器是长连接的结构。One Connect工作模式只支持同步阻塞模式下的TCP连接,即客户端必须等待Server端回应请求之后,再发送下一个请求。每笔交易都是以Client Request-Server Response的方式工作。和前面的MBLB工作模式最大的不同是One Connect可以在V9版本下工作。测试的结构不变,但BIGIP上配置有一些变化virtual test_vs snat automap pool test_pool destination 3:9000 ip protocol tcp rules one_connect_rule profiles oneconnect tcp 注意在VS里面必须绑定Oneconnect Profilerule one_connect_rule when CLIENT_ACCEPTED TCP:collect when CLIENT_DATA LB:detach TCP:release TCP:collect pool test_pool members 4:9000 4:9001 3.1 One Connect模式的工作原理在上图中是以HTTP协议为例,但实际上通过iRules,也可以支持任何协议类型,包括用户自行开发的TCP Socket应用。当第一个client连接到BIGIP开始发送请求的时候,BIGIP会以这个client的源IP地址和后台服务器建立一个连接,并把客户端的Request转发到服务器。此时客户端连接和服务器的TCP连接形成了绑定的关系。当服务器响应了Response之后,由于BIGIP可以识别HTTP Response,因此,当BIGIP检查到服务器端的Response结束了之后,就拆除了第一个Client TCP连接和服务器TCP连接之间的对应关系。即使在客户端关闭连接的情况下,BIGIP和后台服务器的TCP连接也保持Open的状态。当下一个用户和BIGIP建立连接并发送请求的时候,BIGIP会在当前和后台服务器之间的TCP连接里面挑选一个空闲的连接(当然,还需要满足会话保持、负载均衡的算法的前提下),将第二个用户的Request塞到空闲的连接里面发送到服务器,这时,第二个用户的客户端连接和为第一个客户端建立的服务器连接就形成了新的对应关系。在第二个用户的Response结束之后,BIGIP又拆除其对应关系。如果第三个用户连接和请求到达BIGIP的时候,第二个用户的Response并没有结束,也就是当前BIGIP和后台没有空闲连接的时候,BIGIP就会和服务器端再建立一个新的TCP连接,传送第三个客户端的请求到服务器。如果第四个用户连接和请求到达BIGIP的时候,第二个用户的Response传输完成了,第四个用户就会再使用空闲的后台服务器连接进行请求传输。这样,当客户端不停的建立连接,拆除连接的时候,BIGIP始终可以保持较少的后台服务器连接。BIGIP在这里面完成的工作主要就是根据Response结束和新的用户请求到达的时刻点,来切换连接的不同连接对应关系。3.2 TCP连接测试首先看看BIGIP上的VS状态,看加入了one connect rules之后是否会Disable CMP+- VIRTUAL test_vs SERVICE 9000 | PVA acceleration none| CMP enable on none mode: all看上去还好,CMP属于enable状态启动S1启动S2启动客户端C1,并建立连接BIGIP上的连接状态rootltm3600:Active config # b conn62:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 any6 tcp 1/1此时在Server端也看不到任何连接3.3 交易分发测试C1开始发送数据S1上可以收到数据S2上也可以收到数据由于SNAT的原因,服务器收到的TCP 连接的源端口被改变了,但从数据包中可以看出,两台机器收到的是同一个客户端的同一个源端口发送过来的请求。BIGIP上的连接状态:rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/62:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 4:9000 tcp 1/1有一个Server 端连接显示是idle状态注意idle状态的连接随时间变化而变化的:rootltm3600:Active config # b connany6 3:9000 4:9000 tcp 1/62:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 4:9001 tcp 1/1rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/62:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 4:9000 tcp 1/1在两次执行b conn的过程中,idle状态的Server端连接就在发生变化。但请求是被分配到了两台Server上。从客户端的Log看,收到了两台Server的Response3.4 启动第二个客户端的连接再启动一个客户端C2并建立连接BIGIP上的连接状况rootltm3600:Active config # b connany6 3:9000 4:9000 tcp 1/62:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 4:9001 tcp 1/4:1427 3:9000 any6 tcp 1/1C2开始发送数据有意思的是此时S1上总是C2的请求,S2上总是C1得请求S1S2BIGIP上的连接状态rootltm3600:Active config # b connany6 3:9000 4:9001 tcp 1/1any6 3:9000 4:9000 tcp 1/62:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 4:9001 tcp 1/4:1427 3:9000 4:9000 tcp 1/1而此时服务器上的真实连接状况是这样的:客户端到BIGIP VS有两个连接,分别是C1和C2,而BIGIP到后台服务器分别有两个连接,S1的两个连接都用的客户端源端口,S2的两个连接都用的其他端口。3.5 启动多个客户端观察负载均衡算法再启动4个客户端,C3,C4,C5,C6,我们来看看有什么情况出现?S1的收发状态可以看到,C2,C3,C4,C6都在S1上有请求S2上的收发状态可以看到,C1,C3,C5,C6在S2上都有请求BIGIP上的连接显示rootltm3600:Active config # b connany6 3:9000 4:9000 tcp 1/0any6 3:9000 4:9001 tcp 1/1any6 3:9000 4:9000 tcp 1/1any6 3:9000 4:9001 tcp 1/062:47774 4:ssh 4:ssh tcp 1/04:1339 3:9000 4:9001 tcp 1/4:1427 3:9000 4:9000 tcp 1/4:1522 3:9000 4:9001 tcp 1/04:1527 3:9000 4:9000 tcp 1/4:1535 3:9000 4:9001 tcp 1/4:1536 3:9000 4:9000 tcp 1/0客户端6个连接,服务器端4个连接而实际上在客户端和服务器系统里显示的呢?作为客户端发起到VS的连接共有6个,分别代表6个Client服务器S1有5个连接,S2有5个连接。过一段时间再观察,这些连接并没有发生变化3.6 手工Disable 服务器测试Disable S1刚才还在两台服务器之间摇摆不定的C6所有的请求都被转发到了S2。3.7 重新Enable服务器重新enable S1看到C5的请求被分配到两台服务器上了此时S1接收的请求请求被分配到S1的有C1,C3,C4,C5此时S2接收的请求请求被分配到S2上的有C1,C2,C3,C4,C5,C6可以确定,在one connect工作模式下,不同的客户端交易可以被分配到不同的服务器上。3.8 关闭服务器测试同样的进行关闭服务器测试,在关闭S2后,只有C1和S1在工作,其他客户端全部崩溃了!3.9 One Connect模式测试总结:1、 在One Connect模式下,也是一样的可以实现MBLB的工作,但仅限于阻塞模式的应用。2、 同样的,本次测试仅限于每笔交易小于1460byte的情况。当交易大小可能超过1460的时候,就需要用iRules来进行数据包长度的判断。3、 在one connect模式下,关闭客户端连接对服务器端的连接没有影响,这个在本次记录中没有被记下来,但实际上我已经测试过了,关闭客户端连接的时候Server端的连接不会发生变化。4、 One Connect工作模式下,BIGIP自身的b conn输出和实际的情况不大一样,估计是b conn输出的是实时信息,因此和实际上的服务器看到的连接数量不能对应5、 测试是在V10版本上进行的,但按照其工作原理,在V9平台上应该也可以工作。6、 One connect模式CMP是可以正常工作7、 在one connect工作模式下,应该也同样遇到monitor健康检查的实效期间的问题。因此,也需要用inband monitor来解决。或者考虑用when LB_FAIL的事件来进行处理。4. 附录4.1 如何使用iRules来判断交易边界当客户端的交易可能大于1460byte的时候,就必须使用iRules来判断每笔交易的边界。在进行边界分析的时候,必须知道数据包的格式,通常情况下,在长连接交易中,必然会有一个位置来表明每个交易的长度。处理流程在iRules中,需要进行的流程如下:1、 在客户端连接建立成功的时候,启用TCP:collect进行数据收集2、 当客户端请求内容发送时,将触发CLIENT_DATA事件,此时就可以通过分析TCP:payload判断接收到的内容判断交易的长度3、 判断当前收集到的payload长度和交易的实际长度进行比较,如果相等,在One Connect模式下,进行LB:detach动作,在MBLB模式下,进行TCP:notify request动作。如果没有结束,则继续收集,直到收集成功一笔完整的交易。4、 在LB:detach或TCP:notify request完成后,则释放这部分数据,将交易请求转发到服务器。收集完成后,释放交易长度的数据到服务器。5、 在数据释放完成后,重新触发TCP:collect动作,等待触发下一次CLIENT_DATA动作。示例代码下面这段代码以LDAP协议为例,演示如何使用iRules来判断一个完整的LDAP 查询请求。when CLIENT_ACCEPTED TCP:collectwhen CLIENT_DATA binary scan TCP:payload xc ber_lenif $ber_len 0 set ber_index expr 2 + 128 + $ber_len else set ber_index 2# message idbinary scan TCP:payload $ber_indexxcI ber_len ber_len_extif $ber_len (4-$ext_len)*8)+(0x100$ext_len)%(0x100$ext_len) else set ext_len 0incr ber_index expr 2 + $ext_len + $ber_len# ldap messagebinary scan TCP:payload $ber_indexc ber_type if expr $ber_type & 0x1f = 2 log local0. unbind = detachTCP:payload replace 0 TCP:payload length LB:detachTCP:releaseTCP:collect4.2 关于交易定向发送由于环境问题,交易定向发送,也就是根据交易的内容,指定将交易发送到某一个Pool或member中的功能还没有进行测试,但从一些案例上看是完全可行的。必须要注意判断完交易内容后,必须在LB:detach或TCP:notify request动作执行以前,指定将交易要转发到的Pool,否则一旦TCP:release完成后,将无法指定数据包发往的目的地。示例代码如下:when CLIENT_DATA set call_id XXXXXXif $call_id equals “abc” pool pool_a else pool pool_b TCP:releaseTCP:notify requestTCP:collect4.3 关于会话保持同样由于环境问题,会话保持目前还没有进行完全的测试。但从已有的案例上看,这两种模式都支持基于iRules的会话保持,可以根据交易里的一些特征代码,将具备相同特征代码的请求发送到同一台服务器。和Pool选择一样,Persist uie指令的位置必须放置在LB:detach或TCP:notify动作执行之前,否则将无法实现会话保持处理。示例代码如下:when CLIENT_DATA set call_id XXXXXXpersist uie $call_id 360TCP:releaseTCP:notify requestTCP:collect其中XXXXXX部分是从TCP payload 中提取特征码的函数处理。在长连接的交易处理中,经常可能出现消息串的情况,也就是连续的几笔请求都是为了完成一笔交易,在一些情况下,这些请求必须发往同一台服务器处理,这时,就可以采用会话保持模式实现。或者在有些情况下,比如同一个用户的多笔交易请求都需要发送到同一台服务器的时候,也需要使用会话保持来进行处理。4.4 关于服务器端认证在一些情况下,服务器端需要认证之后才能接受客户端的请求,当BIGIP与后台建立连接的时候必须使用客户端的认证信息先和后台建立连接后才能继续发送数据,这时通常的做法是在客户端第一次连接到BIGIP与第一台连接的服务器进行认证的时候,把客户端发送的认证报文保存下来。当B

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论