UltraMonkey-L7 V3(multi-thread implementation)
Revisión | 0faa6cc26a90d358901d46ec6785d7ca9b3f6d07 (tree) |
---|---|
Tiempo | 2015-10-08 17:15:04 |
Autor | Michiro Hibari <l05102@shib...> |
Commiter | Michiro Hibari |
socketoptionにkeepaliveを指定できるようにした。
l7directord.cf の virtualセクションで
socketoptionにkeepaliveを指定できるようになっています。
(l7directord.cf 設定例)
:
snip
:
virtual = XXX.XXX.XXX.XXX:YY
:
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
@@ -987,10 +987,10 @@ sub validate_config { | ||
987 | 987 | config_error($line, 'ERR0124', $config); |
988 | 988 | } |
989 | 989 | my @option_value = split /,/, $value; |
990 | - # OPTION:transparent,deferaccept,nodelay,cork,quickackon|quickackoff | |
990 | + # OPTION:transparent,deferaccept,nodelay,cork,keepalive,quickackon|quickackoff | |
991 | 991 | for my $option (@option_value) { |
992 | 992 | $option =~ s/ //g; |
993 | - if($option !~ /^transparent|deferaccept|nodelay|cork|quickackon|quickackoff$/) { | |
993 | + if($option !~ /^transparent|deferaccept|nodelay|cork|keepalive|quickackon|quickackoff$/) { | |
994 | 994 | config_error($line, 'ERR0124', $config); |
995 | 995 | } |
996 | 996 | } |
@@ -4953,6 +4953,10 @@ Set TCP_NODELAY option to the Client and RealServer socket. | ||
4953 | 4953 | |
4954 | 4954 | Set TCP_CORK option to the Client and RealServer socket. |
4955 | 4955 | |
4956 | +=item B<keepalive> | |
4957 | + | |
4958 | +Set SO_KEEPALIVE option to the Client and RealServer socket. | |
4959 | + | |
4956 | 4960 | =item B<quickackon> or B<quickackoff> |
4957 | 4961 | |
4958 | 4962 | Set or unset TCP_QUICKACK option to the Client and RealServer socket. |
@@ -76,6 +76,17 @@ public: | ||
76 | 76 | Logger::putLogError(LOG_CAT_L7VSD_SESSION, 101, fmt.str(), __FILE__, __LINE__); |
77 | 77 | } |
78 | 78 | } |
79 | + // set TCP_KEEPALIVE option | |
80 | + if (opt_info.keepalive_opt) { | |
81 | + int val = opt_info.keepalive_val; | |
82 | + int err = ::setsockopt(my_socket->native(), SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int)); | |
83 | + if (unlikely(err)) { | |
84 | + error_code = boost::system::error_code(errno, boost::asio::error::get_system_category()); | |
85 | + boost::format fmt("Thread ID[%d] socket option(SO_KEEPALIVE) set failed"); | |
86 | + fmt % boost::this_thread::get_id(); | |
87 | + Logger::putLogError(LOG_CAT_L7VSD_SESSION, 102, fmt.str(), __FILE__, __LINE__); | |
88 | + } | |
89 | + } | |
79 | 90 | } |
80 | 91 | |
81 | 92 | // connect |
@@ -42,6 +42,10 @@ struct tcp_socket_option_info { | ||
42 | 42 | bool cork_opt; |
43 | 43 | //! TCP_CORK option value (false:off,true:on) |
44 | 44 | bool cork_val; |
45 | + //! TCP_KEEPALIVE (false:not set,true:set option) | |
46 | + bool keepalive_opt; | |
47 | + //! TCP_KEEPALIVE option value (false:off,true:on) | |
48 | + bool keepalive_val; | |
45 | 49 | //! TCP_QUICKACK (false:not set,true:set option) |
46 | 50 | bool quickack_opt; |
47 | 51 | //! TCP_QUICKACK option value (false:off,true:on) |
@@ -100,6 +100,17 @@ public: | ||
100 | 100 | Logger::putLogError(LOG_CAT_L7VSD_SESSION, 101, fmt.str(), __FILE__, __LINE__); |
101 | 101 | } |
102 | 102 | } |
103 | + // set TCP_KEEPALIVE | |
104 | + if (opt_info.keepalive_opt) { | |
105 | + int val = opt_info.keepalive_val; | |
106 | + int err = ::setsockopt(my_socket->lowest_layer().native(), SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int)); | |
107 | + if (unlikely(err)) { | |
108 | + error_code = boost::system::error_code(errno, boost::asio::error::get_system_category()); | |
109 | + boost::format fmt("Thread ID[%d] socket option(SO_KEEPALIVE) set failed"); | |
110 | + fmt % boost::this_thread::get_id(); | |
111 | + Logger::putLogError(LOG_CAT_L7VSD_SESSION, 102, fmt.str(), __FILE__, __LINE__); | |
112 | + } | |
113 | + } | |
103 | 114 | } |
104 | 115 | |
105 | 116 | // close |
@@ -83,6 +83,7 @@ public: | ||
83 | 83 | int socket_option_tcp_defer_accept; |
84 | 84 | int socket_option_tcp_nodelay; |
85 | 85 | int socket_option_tcp_cork; |
86 | + int socket_option_tcp_keepalive; | |
86 | 87 | int socket_option_tcp_quickack; |
87 | 88 | std::string socket_option_string; |
88 | 89 |
@@ -105,6 +106,7 @@ public: | ||
105 | 106 | socket_option_tcp_defer_accept(0), |
106 | 107 | socket_option_tcp_nodelay(0), |
107 | 108 | socket_option_tcp_cork(0), |
109 | + socket_option_tcp_keepalive(0), | |
108 | 110 | socket_option_tcp_quickack(0), |
109 | 111 | http_total_count(0ULL), |
110 | 112 | http_get_count(0ULL), |
@@ -134,6 +136,7 @@ public: | ||
134 | 136 | socket_option_tcp_defer_accept(in.socket_option_tcp_defer_accept), |
135 | 137 | socket_option_tcp_nodelay(in.socket_option_tcp_nodelay), |
136 | 138 | socket_option_tcp_cork(in.socket_option_tcp_cork), |
139 | + socket_option_tcp_keepalive(in.socket_option_tcp_keepalive), | |
137 | 140 | socket_option_tcp_quickack(in.socket_option_tcp_quickack), |
138 | 141 | socket_option_string(in.socket_option_string), |
139 | 142 | http_total_count(in.http_total_count), |
@@ -177,6 +180,7 @@ public: | ||
177 | 180 | socket_option_tcp_defer_accept = in.socket_option_tcp_defer_accept; |
178 | 181 | socket_option_tcp_nodelay = in.socket_option_tcp_nodelay; |
179 | 182 | socket_option_tcp_cork = in.socket_option_tcp_cork; |
183 | + socket_option_tcp_keepalive = in.socket_option_tcp_keepalive; | |
180 | 184 | socket_option_tcp_quickack = in.socket_option_tcp_quickack; |
181 | 185 | socket_option_string = in.socket_option_string; |
182 | 186 | http_total_count = in.http_total_count; |
@@ -219,6 +223,7 @@ public: | ||
219 | 223 | elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept && |
220 | 224 | elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay && |
221 | 225 | elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork && |
226 | + elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive && | |
222 | 227 | elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack && |
223 | 228 | elem1.socket_option_string == elem2.socket_option_string && |
224 | 229 | elem1.http_total_count == elem2.http_total_count && |
@@ -280,6 +285,7 @@ public: | ||
280 | 285 | elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept && |
281 | 286 | elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay && |
282 | 287 | elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork && |
288 | + elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive && | |
283 | 289 | elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack && |
284 | 290 | elem1.socket_option_string == elem2.socket_option_string && |
285 | 291 | elem1.http_total_count == elem2.http_total_count && |
@@ -385,6 +391,7 @@ public: | ||
385 | 391 | "socket_option_tcp_defer_accept=%d, " |
386 | 392 | "socket_option_tcp_nodelay=%d, " |
387 | 393 | "socket_option_tcp_cork=%d, " |
394 | + "socket_option_tcp_keepalive=%d, " | |
388 | 395 | "socket_option_tcp_quickack=%d, " |
389 | 396 | "socket_option_string=%s; " |
390 | 397 | "http_total_count=%d; " |
@@ -410,6 +417,7 @@ public: | ||
410 | 417 | % elem.socket_option_tcp_defer_accept |
411 | 418 | % elem.socket_option_tcp_nodelay |
412 | 419 | % elem.socket_option_tcp_cork |
420 | + % elem.socket_option_tcp_keepalive | |
413 | 421 | % elem.socket_option_tcp_quickack |
414 | 422 | % elem.socket_option_string |
415 | 423 | % elem.http_total_count |
@@ -459,6 +467,7 @@ private: | ||
459 | 467 | ar &socket_option_tcp_defer_accept; |
460 | 468 | ar &socket_option_tcp_nodelay; |
461 | 469 | ar &socket_option_tcp_cork; |
470 | + ar &socket_option_tcp_keepalive; | |
462 | 471 | ar &socket_option_tcp_quickack; |
463 | 472 | ar &socket_option_string; |
464 | 473 | ar &http_total_count; |
@@ -1111,11 +1111,13 @@ bool l7vs::l7vsadm::parse_opt_vs_socket_func(int &pos, int argc, char *argv[]) | ||
1111 | 1111 | bool is_set_defer_accept = false; |
1112 | 1112 | bool is_set_nodelay = false; |
1113 | 1113 | bool is_set_cork = false; |
1114 | + bool is_set_keepalive = false; | |
1114 | 1115 | bool is_set_quickack = false; |
1115 | 1116 | |
1116 | 1117 | request.vs_element.socket_option_tcp_defer_accept = 0; |
1117 | 1118 | request.vs_element.socket_option_tcp_nodelay = 0; |
1118 | 1119 | request.vs_element.socket_option_tcp_cork = 0; |
1120 | + request.vs_element.socket_option_tcp_keepalive = 0; | |
1119 | 1121 | request.vs_element.socket_option_tcp_quickack = 0; |
1120 | 1122 | |
1121 | 1123 | std::string socket_option_string = argv[pos]; |
@@ -1159,6 +1161,18 @@ bool l7vs::l7vsadm::parse_opt_vs_socket_func(int &pos, int argc, char *argv[]) | ||
1159 | 1161 | Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 105, buf.str(), __FILE__, __LINE__); |
1160 | 1162 | return false; |
1161 | 1163 | } |
1164 | + } else if (option == "keepalive") { | |
1165 | + if (!is_set_keepalive) { | |
1166 | + is_set_keepalive = true; | |
1167 | + request.vs_element.socket_option_tcp_keepalive = 1; | |
1168 | + } else { | |
1169 | + // keepalive is duplicated | |
1170 | + std::stringstream buf; | |
1171 | + buf << "socket option keepalive is duplicated.(--sockopt)"; | |
1172 | + l7vsadm_err.setter(true, buf.str()); | |
1173 | + Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 108, buf.str(), __FILE__, __LINE__); | |
1174 | + return false; | |
1175 | + } | |
1162 | 1176 | } else if (option == "quickackon" || option == "quickackoff") { |
1163 | 1177 | if (!is_set_quickack) { |
1164 | 1178 | is_set_quickack = true; |
@@ -2288,7 +2302,7 @@ bool l7vs::l7vsadm::parse_help_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, | ||
2288 | 2302 | " --qos-up -Q QoSval-up QoS Threshold(bps) set to real server direction\n" |
2289 | 2303 | " --qos-down -q QoSval-down QoS Threshold(bps) set to client direction\n" |
2290 | 2304 | " --ssl -z ssl-config-file SSL configuration file(Use SSL)\n" |
2291 | - " --sockopt -O socket-option deferaccept,nodelay,cork,quickackon or quickackoff set to socket option\n" | |
2305 | + " --sockopt -O socket-option deferaccept,nodelay,cork,keepalive,quickackon or quickackoff set to socket option\n" | |
2292 | 2306 | " --access-log -L access-log-flag access log flag 0(none) or 1(output)\n" |
2293 | 2307 | " --access-log-name -a access-log-file access log file\n" |
2294 | 2308 | " [logrotate-args]\n" |
@@ -2621,10 +2635,12 @@ void l7vs::l7vsadm::disp_list_verbose() | ||
2621 | 2635 | " TCP_DEFER_ACCEPT %s\n" |
2622 | 2636 | " TCP_NODELAY %s\n" |
2623 | 2637 | " TCP_CORK %s\n" |
2638 | + " TCP_KEEPALIVE %s\n" | |
2624 | 2639 | " TCP_QUICKACK %s\n") |
2625 | 2640 | % ((0 == vse.socket_option_tcp_defer_accept) ? "disable" : "enable") |
2626 | 2641 | % ((0 == vse.socket_option_tcp_nodelay) ? "disable" : "enable") |
2627 | 2642 | % ((0 == vse.socket_option_tcp_cork) ? "disable" : "enable") |
2643 | + % ((0 == vse.socket_option_tcp_keepalive) ? "disable" : "enable") | |
2628 | 2644 | % ((0 == vse.socket_option_tcp_quickack) ? "auto" : ((1 == vse.socket_option_tcp_quickack) ? "enable" : "disable")); |
2629 | 2645 | |
2630 | 2646 |
@@ -1861,6 +1861,10 @@ void l7vs::virtualservice_tcp::set_socket_option() | ||
1861 | 1861 | set_sock_opt.cork_opt = false; |
1862 | 1862 | //! TCP_CORK option value (false:off,true:on) |
1863 | 1863 | set_sock_opt.cork_val = false; |
1864 | + //! TCP_KEEPALIVE (false:not set,true:set option) | |
1865 | + set_sock_opt.keepalive_opt = false; | |
1866 | + //! TCP_KEEPALIVE option value (false:off,true:on) | |
1867 | + set_sock_opt.keepalive_val = false; | |
1864 | 1868 | //! TCP_QUICKACK (false:not set,true:set option) |
1865 | 1869 | set_sock_opt.quickack_opt = false; |
1866 | 1870 | //! TCP_QUICKACK option value (false:off,true:on) |
@@ -1888,6 +1892,13 @@ void l7vs::virtualservice_tcp::set_socket_option() | ||
1888 | 1892 | } |
1889 | 1893 | } |
1890 | 1894 | |
1895 | + if (element.socket_option_tcp_keepalive != 0) { | |
1896 | + set_sock_opt.keepalive_opt = true; | |
1897 | + if (element.socket_option_tcp_keepalive == 1) { | |
1898 | + set_sock_opt.keepalive_val = true; | |
1899 | + } | |
1900 | + } | |
1901 | + | |
1891 | 1902 | if (element.socket_option_tcp_quickack != 0) { |
1892 | 1903 | set_sock_opt.quickack_opt = true; |
1893 | 1904 | if (element.socket_option_tcp_quickack == 1) { |
@@ -1904,6 +1915,8 @@ void l7vs::virtualservice_tcp::set_socket_option() | ||
1904 | 1915 | " nodelay_val[%s]" |
1905 | 1916 | " cork_opt[%s]" |
1906 | 1917 | " cork_val[%s]" |
1918 | + " keepalive_opt[%s]" | |
1919 | + " keepalive_val[%s]" | |
1907 | 1920 | " quickack_opt[%s]" |
1908 | 1921 | " quickack_val[%s]"); |
1909 | 1922 | formatter |
@@ -1913,6 +1926,8 @@ void l7vs::virtualservice_tcp::set_socket_option() | ||
1913 | 1926 | % (set_sock_opt.nodelay_val ? "true" : "false") |
1914 | 1927 | % (set_sock_opt.cork_opt ? "true" : "false") |
1915 | 1928 | % (set_sock_opt.cork_val ? "true" : "false") |
1929 | + % (set_sock_opt.keepalive_opt ? "true" : "false") | |
1930 | + % (set_sock_opt.keepalive_val ? "true" : "false") | |
1916 | 1931 | % (set_sock_opt.quickack_opt ? "true" : "false") |
1917 | 1932 | % (set_sock_opt.quickack_val ? "true" : "false"); |
1918 | 1933 | Logger::putLogDebug(LOG_CAT_L7VSD_VIRTUALSERVICE, 97, formatter.str(), __FILE__, __LINE__); |