系统上线以后,一些用户反应地图上面出现了<!--StartFragment-->叉图,有的用户比较严重,放大和缩小叉图都不能消失,经在甲方的电脑重现,计算机A重现了该现象,经过httpwatch监控和调试nginx,该问题始终得不到解决。通httpwatch进行监控时发现现象更怪异:当请求一个图片的url时,请求返回的状态码是200,内容也显示出来,但是在浏览器上面却出现叉图图,甚是无语,困扰了半个月之久。
今天也就是2012/10/10在网上无意发现了这个帖子,帖子内容如下:
NGINX 负载均衡的问题
nginx 负责均衡在高压力的高并发时候,会出现图片显示不正常,或者显示图片只有一半的情况。
在发现大图片在浏览器显示时不完整,sendfile 是其中的一个原因,sendfile 必须关闭,否则会出现权限不可读取的问题。
如果在关闭sendfile 后问题依旧,就需要排查nginx的缓冲区的问题了。
proxy_buffering
语法: proxy_buffering on|off
默认值: proxy_buffering on
上下文: http, server, location
将 proxy_buffering 设为 off 后问题解决。
记录一下,备忘。
我按照这种方式去做啦,但是rest服务尽然出现了叉图,最后我报着试试的态度,将缓存区的大小调大啦,内容:
server {
listen 80;
server_name 172.16.32.73;
location / {
root html;
index index.html index.htm;
proxy_pass http://backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 328k;(默认128k)
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 40k;(默认4k)
proxy_buffers 4 320k;(默认4 32k)
proxy_busy_buffers_size 640k; (默认64k)
proxy_temp_file_write_size 640k; (默认64k)
}
在计算机A上面使用,竟然没有出现叉图,随即用户使用,也说没有发现叉图,现在自己心里也有了一点认识,在网上百度了一下这些参数的详细说明:
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
在一般的应用中,请求的文件和缓存不会太大,但是在对数据量大的图片进行访问时,如果你的缓冲区的大小过小的话,有可能导致ngnix响应浏览器的请求时,发生响应的中断,导致请求不到响应的结果,出现叉图。问题得以解决!!!
以下是Nginx的相关参数说明:
1、 proxy_buffering
语法:proxy_buffering on|off
默认值:proxy_buffering on
使用环境:http、server、location
功能:设置是否缓存后端服务器响应的内容。如果设置为on,那么nginx一旦从后端服务器读取了响应,它便会传递给客户端,同时会把响应数据存储在缓存中,使用内存空间来提供缓存,如果缓存使用完,那么响应数据就会存储到临时文件;如果设置为off,那么nginx将会在接收到后端服务器响应的同时就直接转发到客户端。Nginx不会尝试从后台的代理服务器读取整个响应,nginx能够从后台服务器接收的最大数据大小是用过proxy_buffer_size指令来设置的。
对于基于长时间轮询的Comet应用程序而言,则需要将该指令设置为off,否则异步响应数据被缓存而导致Comet无法工作。
通过设置在代理响应中的X-Accel-Buffering头,缓存可以被设置为基于每个请求的缓存。
2、 proxy_buffers
语法:proxy_buffers the_number is_size
默认值:proxy_buffers 8 4K/8K
使用环境:http、server、location
功能:设置缓存数据和大小,用于存放从后台服务器读取的响应数据。它的默认值是8个缓存。而每个缓存4kb或8kb,依赖于你的平台。
3、 proxy_buffer_size
语法:proxy_buffer_size the_size
默认值:proxy_buffer_size 4K/8K
使用环境:http、server、location
功能:该指令用于设置缓冲区的大小,进入该缓存的数据是从被代理的服务器传来的(被读取的)响应数据的开始部分,一般来说,这部分内容是一些小的响应头。对于大小的设置,在默认情况下,该指令的值等于指令proxy_buffers设置的一个缓存的大小。
4、 proxy_busy_buffers_size
语法:proxy_busy_buffers_size size
默认值:proxy_busy_buffers_size proxy_busy_buffer_size*2
使用环境:http、server、location、if
功能:该指令在官方的wike中没有描述。在代理的所有缓存区中,即通过proxy_buffers设置的缓存区,在缓存区使用的过程中,当后台的数据在缓存区中堆积的数据超过这个指定的值时,那么它将被刷新,并且将缓存的数发送至客户端。在设置该指令的值时要注意,它的大小必须小于所有的proxy_buffers减去一个buffer的值,官方指导的大小是2倍的proxy_buffer_size
5、 proxy_max_temp_file_size
语法:proxy_max_temp_file_size size
默认值:proxy_max_temp_file_size 1G
使用环境:http、server、location、if
功能:设置临时文件的最大值。当被请求的文件内容大于代理缓存的大小时,该文件会被存储到这个临时文件,但是如果被请求文件的内容大于这个值的时候,那么将会从上游的服务器(被代理的服务器)上直接同步传递,而不再使用代理缓存。该指令的默认值为1GB,如果设置为0,那么意味着禁止使用临时文件。
6、 proxy_max_temp_file_write_size
语法:proxy_temp_file_write_size size
默认值:proxy_temp_file_write_size proxy_buffer_size*2
使用环境:http、server、location、if
功能:当设置了使用存储驱动器上的临时文件时,设置缓存区大小,就是说写入临时文件的写缓存区,设置它的目的在于防止一个worker进程在传递文件时长时间地阻塞临时文件。它的大小一般设置为2倍的proxy_buffer_size。
7、proxy_send_timeout
语法:
默认值:
使用环境:
功能:该指令用于设置将请求转发到代理服务器的超时时间,单位为秒。需要注意的是,这个超时不是完成传递整个请求的超时,而是两个写操作之间的超时间隔。如果在此时间之后上游服务器没有发送新的数据,那么nginx将会自动关闭。
8、proxy_read_timeout
语法:
默认值:
使用环境:
功能:该指令用于设置读取后台代理服务器响应的超时时间,单位是秒,它决定了对于一个请求的响应,nginx服务器可以等待多久。需要注意的是,这个超时是指Tcp协议完成了两次握手协议之后,并且连续状态为Established之后的超时时间,它不是指的超时捕获的是后台服务器将放置的连接请求池中的请求,但是又为前端的nginx没有返回任何数据的这个超时时间。我们可以在不同的location中分别设置,以便能有一个高效的proxy_read_timeout设置。(需要注意的是:不 要将该指令的值设置的太低,因为代理服务器可能会花较长的时间来响应一个请求,这种情况并非偶然,比如,我们请求的页面可能需要花长时间的计算才能得出(毕竟不是静态页))
9、proxy_connect_timeout
语法:
默认值:
使用环境:
功能:该指令用于指定连接后台服务器的一个超时时间。需要注意的是,这个timeout不能够超过75秒。这个时间不是等待服务器返回页面的时间,等待服务器返回页面的时间是由proxy_read_timeout指令设置的。如果后台服务器工作正常,但是由于请求被“悬挂”(例如:可能是没有足够的线程来处理该请求,因此就需要将请求暂时放在连接请求池内,等待处理)那么这个指令就是用于设置这个时间的。