Michiro Hibari
l0510****@shiba*****
2015年 8月 6日 (木) 16:26:09 JST
皆様 ひばりです。 >> socket optionでtcpkeepaliveが有効にできれば >> 良いのですが、無効でハードコーディングされてしまって >> いるので設定で有効にはできません。 上記についてですが、簡単に実装できそうでしたので patchを作ってみました。 l7directord.cf の virtualセクションで socketoptionにkeepaliveを指定できるようになっています。 (l7directord.cf 設定例) : snip : virtual = XXX.XXX.XXX.XXX:YY socketoption = keepalive : snip : tcp_keepaliveのtimeoutやprobe間隔については OSの設定をそのまま使っているので、 変更が必要な場合は/etc/sysctl.confに 設定を加えてください。 (sysctl.conf 設定例) : snip : net.ipv4.tcp_keepalive_time = 60 net.ipv4.tcp_keepalive_intvl = 5 net.ipv4.tcp_keepalive_probes = 5 田沼さんのおっしゃるとおり、ハーフコネクションが 残らないようにするのがベストかと思いますが、 興味がある方はお試し下さい。 以上、よろしくお願いいたします。 2015/08/06 16:14 <tanum****@nttda*****>: > 小林様 > > 田沼と申します。 > > 残ったコネクションを強制的に切るよりも > コネクションが残らないようにするアプローチの方がよいかと思います。 > (※最近のUltraMonkey-L7の仕様を把握していませんが、 > たぶん環境の問題だと思います) > > Apache側(及びクライアント)にはESTABLISHEDで残っていないということは、 > Apacheでは切断処理を行っているということで、 > その際に対向のUltraMonkey-L7に対して、FINまたはRSTのパケットを > 送っているはずです。 > それにもかかわらず、UltraMonkey-L7にESTABLISHEDで残るということは、 > Apacheから送信したFINやRSTがUltraMonkey-L7に届かなかったと > いうことになります。 > > どういう場合にパケットが届かなくなるかというと、 > ケーブルが抜けたとか、NWが輻輳してパケットロストしたとか、 > 様々なケースが考えられますが、最もありがちなのが、 > ファイアウォールやNATルータが間にあって、セッションタイムアウトで > パケットを破棄しているパターンです。 > > ということで、UltraMonkey-L7の前後にファイアウォールやNATルータ等の > 機器が存在していないでしょうか。 > 存在する場合は、ApacheのKeepAliveTimeoutやTimeout設定よりも > 機器のセッションタイムアウト設定が長くなっているかどうかを > 確認してみてください。 > > そのような機器が無い場合は、UltraMonkey-L7とApacheの両方で > tcpdump等でパケットキャプチャを行って解析することが > 解決への近道かと思います。 > > 以上、よろしくお願いします。 > > > From: ultra****@lists***** [mailto: > ultra****@lists*****] On Behalf Of Michiro Hibari > Sent: Thursday, August 06, 2015 2:07 PM > To: 小林 年伸 <toshi****@jig-s*****> > Cc: ultra****@lists***** > Subject: [Ultramonkey-l7-users 594] Re: UltraMonkey-L7 v3系においてのtimeoutについて > > 小林さま > > ひばり と申します。 > > ハーフコネクションが残ってしまった場合、 > 現状 有効なタイムアウト設定はなさそうです。 > > socket optionでtcpkeepaliveが有効にできれば > 良いのですが、無効でハードコーディングされてしまって > いるので設定で有効にはできません。 > > ちなみにserver_connect_timeoutは振り分け先との > コネクションが確立するまでのタイムアウトなので、 > ESTABLISHEDとなったコネクションに対して有効なものでは > ございません。 > > netstat等で観察しつつ、あまりにも多くハーフコネクションが > 残るようなら再起動するしかないと思います。 > > 以上、宜しくお願い致します。 > > 2015/08/05 18:42 "小林 年伸" <toshi****@jig-s*****>: > 開発者の皆様 > > jig-sawの小林と申します。 > > UltraMonkey-L7 v3系においてのtimeout値について > ご質問させて頂いてよろしいでしょうか > > 現在UltraMonkey-L7 3.1.1を使用させて頂いていますが > 運用中にhttpの接続が切れないで > ESTABLISHED 状態のまま残り続けるものが溜まっていくという > 事象がありました。 > > アクセスの傾向としては07:00~22:00以外はグッと下がる傾向にあるのですが > /usr/sbin/l7vsadm -l -n > で確認すると ActiveConn が落ちること無く日増しに増えていっていました。 > > l7vs.cfに「server_connect_timeout」を設定してみましたが > 効果が見られなかったです。 > クライアント(GIP)、リアルサーバー(LIP)共にESTABLISHED 状態のまま残り続け > ていました。 > 只、リアルサーバー側ではLBのIPとESTABLISHED になっているものは無い状況で > した。 > > 他に強制的にタイムアウトをさせるような設定はあるかどうか > ご教授いただけますでしょうか。 > > 以下環境を記載させていただきます。 > 足りないものがありましたらお手数ですがご教授ください。 > > 【環境】 > <ロードバランサー> > OS:CentOS 6.6 64bit > Kernel:2.6.32-504.12.2.el6 > UltraMonkey-l7バージョン:3.1.1 > > <Webサーバー> > OS:CentOS 5.5 64bit > Apache:2.2.21 > > <l7vs.cf> > ----------------------------------------------------------- > # > # l7vsadm setting > # > [l7vsadm] > cmd_interval = 1 > cmd_count = 10 > con_interval = 1 > con_count = 1 > > # > # l7vsd setting > # > [l7vsd] > maxfileno = 65535 > > # > # virtualservice setting > # > [virtualservice] > session_thread_pool_size = 32 > throughput_calc_interval = 500 > > # > # Session Settings > # > [session] > #upstream_buffer_size = 8192 > #downstream_buffer_size = 8192 > server_connect_timeout = 61 > > # > # l7vsd replication setting > # > [replication] > #ip_addr = "192.168.0.254" > #service_name = "40000" > #recv_ip_addr = "192.168.0.253" > #interval = 1000 > #compulsorily_interval = 40 > > #cmponent_id_00 = "virtualservice" > #cmponent_size_00 = 64 > #cmponent_id_01 = "chash" > #cmponent_size_01 = 1 > #cmponent_id_02 = "sslid" > #cmponent_size_02 = 222 > > # > # snmpagent settings > # > [snmpagent] > enable = "false" > cache_update_interval = 1 > logtrap = "false" > logtrap_level = "warn" > qos_up_alert_on = 85 > qos_up_alert_off = 50 > qos_down_alert_on = 85 > qos_down_alert_off = 50 > sessionpool_alert_on = 5 > sessionpool_alert_off = 8 > trap_queue_polling_interval = 100000000 > trap_queue_max_size = 1000 > ----------------------------------------------------------- > ※[logger]セクションは省略しております。 > > <l7directord.cf> > ----------------------------------------------------------- > # - Monitor Settings > checktimeout = 5 > negotiatetimeout = 5 > checkinterval = 10 > retryinterval = 5 > checkcount = 3 > quiescent = yes > configinterval = 10 > autoreload = yes > > virtual = {service_IP}:80 > real = {realserver01_IP}:80 masq 10 > real = {realserver02_IP}:80 masq 10 > real = {realserver03_IP}:80 masq 10 > sorryserver = {sorryserver_IP}:8085 > module = sessionless --forwarded-for > scheduler = lc > qosup = 125M > qosdown = 125M > checktype = connect > service = http > quiescent = no > checkcount = 2 > session_thread_pool_size = 2000 > maxconn = 10000 > ----------------------------------------------------------- > > > お手数ですが、何卒よろしくお願いいたします。 > > -- > -------------------------------------------- > ジグソー株式会社 > 小林 年伸 > E-mail:toshi****@jig-s***** > Tel:011-737-0240 Fax:011-737-0241 > 〒060-0808 > 北海道札幌市北区北8条西3丁目32番 > > _______________________________________________ > Ultramonkey-l7-users mailing list > Ultra****@lists***** > http://lists.osdn.me/mailman/listinfo/ultramonkey-l7-users > _______________________________________________ > Ultramonkey-l7-users mailing list > Ultra****@lists***** > http://lists.osdn.me/mailman/listinfo/ultramonkey-l7-users > -------------- next part -------------- HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B... 下载 -------------- next part -------------- diff -Naurp ultramonkeyl7-3.1.2/l7directord/l7directord ultramonkeyl7-3.1.2.tcpkeepalive/l7directord/l7directord --- ultramonkeyl7-3.1.2/l7directord/l7directord 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7directord/l7directord 2015-08-06 15:41:46.305913927 +0900 @@ -987,10 +987,10 @@ sub validate_config { config_error($line, 'ERR0124', $config); } my @option_value = split /,/, $value; - # OPTION:transparent,deferaccept,nodelay,cork,quickackon|quickackoff + # OPTION:transparent,deferaccept,nodelay,cork,keepalive,quickackon|quickackoff for my $option (@option_value) { $option =~ s/ //g; - if($option !~ /^transparent|deferaccept|nodelay|cork|quickackon|quickackoff$/) { + if($option !~ /^transparent|deferaccept|nodelay|cork|keepalive|quickackon|quickackoff$/) { config_error($line, 'ERR0124', $config); } } @@ -4953,6 +4953,10 @@ Set TCP_NODELAY option to the Client and Set TCP_CORK option to the Client and RealServer socket. +=item B<keepalive> + +Set SO_KEEPALIVE option to the Client and RealServer socket. + =item B<quickackon> or B<quickackoff> Set or unset TCP_QUICKACK option to the Client and RealServer socket. diff -Naurp ultramonkeyl7-3.1.2/l7vsd/include/tcp_socket.h ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/tcp_socket.h --- ultramonkeyl7-3.1.2/l7vsd/include/tcp_socket.h 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/tcp_socket.h 2015-08-06 14:46:38.882234717 +0900 @@ -76,6 +76,17 @@ public: Logger::putLogError(LOG_CAT_L7VSD_SESSION, 101, fmt.str(), __FILE__, __LINE__); } } + // set TCP_KEEPALIVE option + if (opt_info.keepalive_opt) { + int val = opt_info.keepalive_val; + int err = ::setsockopt(my_socket->native(), SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int)); + if (unlikely(err)) { + error_code = boost::system::error_code(errno, boost::asio::error::get_system_category()); + boost::format fmt("Thread ID[%d] socket option(SO_KEEPALIVE) set failed"); + fmt % boost::this_thread::get_id(); + Logger::putLogError(LOG_CAT_L7VSD_SESSION, 102, fmt.str(), __FILE__, __LINE__); + } + } } // connect diff -Naurp ultramonkeyl7-3.1.2/l7vsd/include/tcp_socket_option.h ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/tcp_socket_option.h --- ultramonkeyl7-3.1.2/l7vsd/include/tcp_socket_option.h 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/tcp_socket_option.h 2015-08-06 14:48:10.413761197 +0900 @@ -42,6 +42,10 @@ struct tcp_socket_option_info { bool cork_opt; //! TCP_CORK option value (false:off,true:on) bool cork_val; + //! TCP_KEEPALIVE (false:not set,true:set option) + bool keepalive_opt; + //! TCP_KEEPALIVE option value (false:off,true:on) + bool keepalive_val; //! TCP_QUICKACK (false:not set,true:set option) bool quickack_opt; //! TCP_QUICKACK option value (false:off,true:on) diff -Naurp ultramonkeyl7-3.1.2/l7vsd/include/tcp_ssl_socket.h ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/tcp_ssl_socket.h --- ultramonkeyl7-3.1.2/l7vsd/include/tcp_ssl_socket.h 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/tcp_ssl_socket.h 2015-08-06 14:51:26.288467740 +0900 @@ -100,6 +100,17 @@ public: Logger::putLogError(LOG_CAT_L7VSD_SESSION, 101, fmt.str(), __FILE__, __LINE__); } } + // set TCP_KEEPALIVE + if (opt_info.keepalive_opt) { + int val = opt_info.keepalive_val; + int err = ::setsockopt(my_socket->lowest_layer().native(), SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int)); + if (unlikely(err)) { + error_code = boost::system::error_code(errno, boost::asio::error::get_system_category()); + boost::format fmt("Thread ID[%d] socket option(SO_KEEPALIVE) set failed"); + fmt % boost::this_thread::get_id(); + Logger::putLogError(LOG_CAT_L7VSD_SESSION, 102, fmt.str(), __FILE__, __LINE__); + } + } } // close diff -Naurp ultramonkeyl7-3.1.2/l7vsd/include/virtualservice_element.h ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/virtualservice_element.h --- ultramonkeyl7-3.1.2/l7vsd/include/virtualservice_element.h 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/include/virtualservice_element.h 2015-08-06 14:55:04.748563609 +0900 @@ -83,6 +83,7 @@ public: int socket_option_tcp_defer_accept; int socket_option_tcp_nodelay; int socket_option_tcp_cork; + int socket_option_tcp_keepalive; int socket_option_tcp_quickack; std::string socket_option_string; @@ -105,6 +106,7 @@ public: socket_option_tcp_defer_accept(0), socket_option_tcp_nodelay(0), socket_option_tcp_cork(0), + socket_option_tcp_keepalive(0), socket_option_tcp_quickack(0), http_total_count(0ULL), http_get_count(0ULL), @@ -134,6 +136,7 @@ public: socket_option_tcp_defer_accept(in.socket_option_tcp_defer_accept), socket_option_tcp_nodelay(in.socket_option_tcp_nodelay), socket_option_tcp_cork(in.socket_option_tcp_cork), + socket_option_tcp_keepalive(in.socket_option_tcp_keepalive), socket_option_tcp_quickack(in.socket_option_tcp_quickack), socket_option_string(in.socket_option_string), http_total_count(in.http_total_count), @@ -177,6 +180,7 @@ public: socket_option_tcp_defer_accept = in.socket_option_tcp_defer_accept; socket_option_tcp_nodelay = in.socket_option_tcp_nodelay; socket_option_tcp_cork = in.socket_option_tcp_cork; + socket_option_tcp_keepalive = in.socket_option_tcp_keepalive; socket_option_tcp_quickack = in.socket_option_tcp_quickack; socket_option_string = in.socket_option_string; http_total_count = in.http_total_count; @@ -219,6 +223,7 @@ public: elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept && elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay && elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork && + elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive && elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack && elem1.socket_option_string == elem2.socket_option_string && elem1.http_total_count == elem2.http_total_count && @@ -280,6 +285,7 @@ public: elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept && elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay && elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork && + elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive && elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack && elem1.socket_option_string == elem2.socket_option_string && elem1.http_total_count == elem2.http_total_count && @@ -385,6 +391,7 @@ public: "socket_option_tcp_defer_accept=%d, " "socket_option_tcp_nodelay=%d, " "socket_option_tcp_cork=%d, " + "socket_option_tcp_keepalive=%d, " "socket_option_tcp_quickack=%d, " "socket_option_string=%s; " "http_total_count=%d; " @@ -410,6 +417,7 @@ public: % elem.socket_option_tcp_defer_accept % elem.socket_option_tcp_nodelay % elem.socket_option_tcp_cork + % elem.socket_option_tcp_keepalive % elem.socket_option_tcp_quickack % elem.socket_option_string % elem.http_total_count @@ -459,6 +467,7 @@ private: ar &socket_option_tcp_defer_accept; ar &socket_option_tcp_nodelay; ar &socket_option_tcp_cork; + ar &socket_option_tcp_keepalive; ar &socket_option_tcp_quickack; ar &socket_option_string; ar &http_total_count; diff -Naurp ultramonkeyl7-3.1.2/l7vsd/src/l7vsadm.cpp ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/src/l7vsadm.cpp --- ultramonkeyl7-3.1.2/l7vsd/src/l7vsadm.cpp 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/src/l7vsadm.cpp 2015-08-06 15:00:37.424572076 +0900 @@ -1111,11 +1111,13 @@ bool l7vs::l7vsadm::parse_opt_vs_socket_ bool is_set_defer_accept = false; bool is_set_nodelay = false; bool is_set_cork = false; + bool is_set_keepalive = false; bool is_set_quickack = false; request.vs_element.socket_option_tcp_defer_accept = 0; request.vs_element.socket_option_tcp_nodelay = 0; request.vs_element.socket_option_tcp_cork = 0; + request.vs_element.socket_option_tcp_keepalive = 0; request.vs_element.socket_option_tcp_quickack = 0; std::string socket_option_string = argv[pos]; @@ -1159,6 +1161,18 @@ bool l7vs::l7vsadm::parse_opt_vs_socket_ Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 105, buf.str(), __FILE__, __LINE__); return false; } + } else if (option == "keepalive") { + if (!is_set_keepalive) { + is_set_keepalive = true; + request.vs_element.socket_option_tcp_keepalive = 1; + } else { + // keepalive is duplicated + std::stringstream buf; + buf << "socket option keepalive is duplicated.(--sockopt)"; + l7vsadm_err.setter(true, buf.str()); + Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 108, buf.str(), __FILE__, __LINE__); + return false; + } } else if (option == "quickackon" || option == "quickackoff") { if (!is_set_quickack) { is_set_quickack = true; @@ -2288,7 +2302,7 @@ bool l7vs::l7vsadm::parse_help_func(l7vs " --qos-up -Q QoSval-up QoS Threshold(bps) set to real server direction\n" " --qos-down -q QoSval-down QoS Threshold(bps) set to client direction\n" " --ssl -z ssl-config-file SSL configuration file(Use SSL)\n" - " --sockopt -O socket-option deferaccept,nodelay,cork,quickackon or quickackoff set to socket option\n" + " --sockopt -O socket-option deferaccept,nodelay,cork,keepalive,quickackon or quickackoff set to socket option\n" " --access-log -L access-log-flag access log flag 0(none) or 1(output)\n" " --access-log-name -a access-log-file access log file\n" " [logrotate-args]\n" @@ -2621,10 +2635,12 @@ void l7vs::l7vsadm::disp_list_verbose() " TCP_DEFER_ACCEPT %s\n" " TCP_NODELAY %s\n" " TCP_CORK %s\n" + " TCP_KEEPALIVE %s\n" " TCP_QUICKACK %s\n") % ((0 == vse.socket_option_tcp_defer_accept) ? "disable" : "enable") % ((0 == vse.socket_option_tcp_nodelay) ? "disable" : "enable") % ((0 == vse.socket_option_tcp_cork) ? "disable" : "enable") + % ((0 == vse.socket_option_tcp_keepalive) ? "disable" : "enable") % ((0 == vse.socket_option_tcp_quickack) ? "auto" : ((1 == vse.socket_option_tcp_quickack) ? "enable" : "disable")); diff -Naurp ultramonkeyl7-3.1.2/l7vsd/src/virtualservice_tcp.cpp ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/src/virtualservice_tcp.cpp --- ultramonkeyl7-3.1.2/l7vsd/src/virtualservice_tcp.cpp 2014-11-27 16:05:54.000000000 +0900 +++ ultramonkeyl7-3.1.2.tcpkeepalive/l7vsd/src/virtualservice_tcp.cpp 2015-08-06 15:04:34.831155068 +0900 @@ -1861,6 +1861,10 @@ void l7vs::virtualservice_tcp::set_socke set_sock_opt.cork_opt = false; //! TCP_CORK option value (false:off,true:on) set_sock_opt.cork_val = false; + //! TCP_KEEPALIVE (false:not set,true:set option) + set_sock_opt.keepalive_opt = false; + //! TCP_KEEPALIVE option value (false:off,true:on) + set_sock_opt.keepalive_val = false; //! TCP_QUICKACK (false:not set,true:set option) set_sock_opt.quickack_opt = false; //! TCP_QUICKACK option value (false:off,true:on) @@ -1888,6 +1892,13 @@ void l7vs::virtualservice_tcp::set_socke } } + if (element.socket_option_tcp_keepalive != 0) { + set_sock_opt.keepalive_opt = true; + if (element.socket_option_tcp_keepalive == 1) { + set_sock_opt.keepalive_val = true; + } + } + if (element.socket_option_tcp_quickack != 0) { set_sock_opt.quickack_opt = true; if (element.socket_option_tcp_quickack == 1) { @@ -1904,6 +1915,8 @@ void l7vs::virtualservice_tcp::set_socke " nodelay_val[%s]" " cork_opt[%s]" " cork_val[%s]" + " keepalive_opt[%s]" + " keepalive_val[%s]" " quickack_opt[%s]" " quickack_val[%s]"); formatter @@ -1913,6 +1926,8 @@ void l7vs::virtualservice_tcp::set_socke % (set_sock_opt.nodelay_val ? "true" : "false") % (set_sock_opt.cork_opt ? "true" : "false") % (set_sock_opt.cork_val ? "true" : "false") + % (set_sock_opt.keepalive_opt ? "true" : "false") + % (set_sock_opt.keepalive_val ? "true" : "false") % (set_sock_opt.quickack_opt ? "true" : "false") % (set_sock_opt.quickack_val ? "true" : "false"); Logger::putLogDebug(LOG_CAT_L7VSD_VIRTUALSERVICE, 97, formatter.str(), __FILE__, __LINE__);