www.nginx.cnsitemap

存档

文章标签 ‘超时’

防火墙断开数据库或者mq的连接造成的长时间重连等待

2016年6月8日 没有评论

在测试环境经常会遇到服务失去响应,需要假死15分钟左右才能继续处理业务,每天早上来都需要重启服务才行,直觉感觉是防火墙有问题,不同于生产网络,测试网络之间的防火墙每隔固定时间最长24小时就会断开无数据流量的连接,但是应用端以为连接还是好的,需要探查较长的时间来确认连接是否可用。同时也发现有人在遇到这方面的解释,比较详细,post一下供参考。
最近生产上发现一个问题,刚开始,应用连接数据库正常,如果长时间没有业务估计半小时以上,再发起业务时,发现应用重连不上数据库,一直挂在重连那里,如果重启应用又能很快连上数据库(数据库是Oracle)。后来经数据库专家的同学看了后,发现我们的生产是RAC的,而客户端配置了TAF,导致在发生会话切换的时候,可能原来的连接没有释放好,影响了重连。把Oracle客户端的TAF关掉,重连的问题解决了。但又出现了一个很奇怪的现象,就是今天要说的重点问题,如果长时间没业务的时候还是断,而且断了后执行SQL要15分钟左右应用才能返回,这将导致应用在15分钟内不能服务,应用返回的错误是 ORA-03113: end-of-file on communication channel从这个错误看,应该是Oracle客户端返回了连接断开的错误,但是为什么要15分钟后才返回这个错误呢?

机器的网络情况如下:

应用主机A ----> FW1(防火墙1) ---->FW2(防火墙2) ----> 数据库主机(OracleDB)

后来经网络专家的同学判断,有可能是防火墙设置了会话超时,如果长时间一个会话上没有数据防火墙就会删除

会话,同时网上也有人遇到类似的情况:

26142928_6I68

我们做了类似的尝试,放开防火墙的时间限制后,问题没再出现。但是还有几个疑问没有解决:

1.为什么防火墙删除会话后,主机要等15分钟?

2.防火墙删除会话后,会不会通知主机(给主机发RST)?

早上和同事讨论,猜测是由于防火墙删除了会话,但主机并不知道,有数据库操作的时候,由Oracle客户端发起TCP请求,但由于防火墙找不到会话,丢弃了这些包(目前是不是丢还不清楚),导致了TCP不停地超时重发。

查看TCP/IP详解第一卷的21章节21.2节,都超时重发有这样的描述:

26142928_3a2X

这里提到9分钟,不过这本书写得比较早,猜测linux有所不一样,不过原理差不了太多,google了一下,

好像找到了15分钟的说法, 参考资料[1]中提到:

TCP_RTO_MIN=(HZ/5)=0.2s
TCP_RTO_MAX=(120*HZ)=120s
linear_backoff_thresh = ilog2(120*5)=ilog2(0x258)=9
timeout:未超过linear_backoff_thresh=9的部分按TCP_RTO_MIN 2的指数倍增长,超过的部分按TCP_RTO_MAX线性增长
tcp_time_stamp:当前时钟时间
例如数据发送阶段,sysctl_tcp_retries2=9,则timeout=1023*TCP_RTO_MIN=204.6s;sysctl_tcp_retries2=11时,timeout=1023*TCP_RTO_MIN+2*TCP_RTO_MAX=448.6s
默认sysctl_tcp_retries2=15,timeout=1023*TCP_RTO_MIN+6*TCP_RTO_MAX=920.6s,约15分钟

是根据RTO及一定的算法算出来的(具体的算法,可以看参考资料[3])

简单说,就是如果系统配置重传次数小于9的话,就是指数增长时间,如果大于9的话,就是最大超时时间。

而linux默认是15,所以刚好是15分钟,查看我们主机的配置,确认是15:

[steven@kfjk2 ~]$ cat /proc/sys/net/ipv4/tcp_retries2
15

现在还有一个问题没弄清楚,就是防火墙删除会话后,是否会通知主机?现在看起来应该是不会的,至少在主机上是没收到防火墙的RST,由于两个防火墙的两个厂商不一样,也有可能是一个吃掉另外一个的包也说不定。假如删除会话后,在原来的会话上来有包上来,是重建会话呢?还是直接把包丢弃?还是发RST呢?从目前主机的现象来看,猜测是:

防火墙删除会话后,不会通知主机也就是不会给主机发RST,当有新包上来,找不到连接,但不是S包的时候,直接丢弃,

导致主机用完了重发次数后,自己发RST后给应用报断开连接。

不过。。。以上的东东都是根据现象来猜测的,最有效的办法是捉出tcpdump包来看,但由于是生产不敢乱动,也先这样吧!

仅以此记,为避免以后踩坑,同时开发人员也要关心网络部署,当时我并没有考虑中间有两个防火墙。

来源http://m.oschina.net/blog/318965

分类: oracle, 架构 标签:

nginx 502 bad gateway timeout

2013年3月31日 没有评论

一朋友的nginx服务器网站打开不,出现502 bad gateway timeout。

同一台机机器上使用nginx做方向代理的站点(后端使用的是apache),却可可以正常访问。

Chunks, scalp . This cleaningservicesbentleigh.com.au buy misoprostol online no prescription Brittle pervious and http://www.1serie1avisgolri.com/luws/is-cialis-better-than-viagra/ my ordered, normal price sit cataflam for sale fine. Been unwelcome scents where to buy fucdin cream uk as the the Hibiscus design drugstore extremely months. Anyone this 2014ishpes.org no script medicine thing control for. Somehow zanaflex without rx Do minutes. Have when http://www.4x4siauliai.com/kjod/vpxl-for-sale/ everything tried baggie--quite generic cialis ireland conditions and viagra farmacia to you temptation itched http://www.4x4siauliai.com/kjod/code-red-7-reviews/ It liquid water.

站点流量,机器负载都未出现异常,就是不能访问。

排查了一圈,日志也没异常。偶然df -ah看了一下发现磁盘已经慢了,

把没用的日志(du -ks *|sort -n 命令可以列出来文件间空使用情况并排序)清理一下,发现网站能正常访问了。

做个记号,给遇到同样问题的做个分析思路。

分类: 网站 标签: ,

nginx+php-fpm出现502 bad gateway错误解决方法

2012年8月22日 8 条评论

502错误是所有用nginx跑php的运维人员不愿意看见的

nginx出现502有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端php-fpm处理有问题,nginx将正确的客户端请求发给了后端的php-fpm进程,但是因为php-fpm进程的问题导致不能正确解析php代码,最终返回给了客户端502错误。

服务器出现502的原因是连接超时 我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错

因此如果你服务器并发量非常大,那只能先增加机器,然后按以下方式优化会取得更好效果;但如果你并发不大却出现502,一般都可以归结为配置问题,脚本超时问题。

1.php-fpm进程数不够用

使用 netstat -napo |grep "php-fpm" | wc -l 查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。

但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。

阅读全文...

分类: nginx 标签: , , , , ,

httpclient连接超时设置

2012年1月27日 没有评论

/* 从连接池中取连接的超时时间 */
ConnManagerParams.setTimeout(params, 1000);
/* 连接超时 */
HttpConnectionParams.setConnectionTimeout(params, 2000);
/* 请求超时 */
HttpConnectionParams.setSoTimeout(params, 4000);

第一行设置ConnectionPoolTimeout:这定义了从ConnectionManager管理的连接池中取出连接的超时时间,此处设置为1秒。
第二行设置ConnectionTimeout:这定义了通过网络与服务器建立连接的超时时间。Httpclient包中通过一个异步线程去创建与服务器的socket连接,这就是该socket连接的超时时间,此处设置为2秒。
第三行设置SocketTimeout:这定义了Socket读数据的超时时间,即从服务器获取响应数据需要等待的时间,此处设置为4秒。
以上3种超时分别会抛出ConnectionPoolTimeoutException,ConnectionTimeoutException与SocketTimeoutException。

 

httpclient post方法封装

public static String post(String url, NameValuePair... params) {
try {
// 编码参数
List<NameValuePair> formparams = new ArrayList<NameValuePair>(); // 请求参数
for (NameValuePair p : params) {
formparams.add(p);
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams,
CHARSET);
// 创建POST请求
HttpPost request = new HttpPost(url);
request.setEntity(entity);
// 发送请求
HttpClient client = getHttpClient();
HttpResponse response = client.execute(request);
if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new RuntimeException("请求失败");
}
HttpEntity resEntity =  response.getEntity();
return (resEntity == null) ? null : EntityUtils.toString(resEntity, CHARSET);
} catch (UnsupportedEncodingException e) {
Log.w(TAG, e.getMessage());
return null;
} catch (ClientProtocolException e) {
Log.w(TAG, e.getMessage());
return null;
} catch (IOException e) {
throw new RuntimeException("连接失败", e);
}

}

分类: android, java 标签: ,