UltraMonkey-L7 V3(multi-thread implementation)
Révision | 9a42cba8f6a3ef11e1315fb54cbd822c2cae9d00 (tree) |
---|---|
l'heure | 2012-07-30 15:55:41 |
Auteur | Hiroaki Nakano <nakano.hiroaki@nttc...> |
Commiter | Hiroaki Nakano |
ticket 29142 リアルサーバ切り離し時クラッシュ対処
SSL+sessionless+リアルサーバ切り離しで、まれに以下の現象が出る。
- l7vsdがクラッシュ(コアダンプ)する
- l7vsdプロセスのCPU使用率が100%に張り付く
原因は、非同期処理の待ち合わせを行うactive_sessions.do_all()を
l7vsadm -d実行時の通信スレッド停止・再開でも流用していたため。
そのために、非同期で待ち合わせていたスレッドが、l7vsadm -dで
再開させられていた。
対処として、active_sessions.do_all()を廃止し、l7vsadm -d時は
各スレッドに終了処理に入るようメッセージを飛ばす方式とした。
また、新規接続処理に、l7vsadmコマンドの待ち合わせ処理を追加。
@@ -129,7 +129,7 @@ public: | ||
129 | 129 | void down_thread_run(); |
130 | 130 | //! realserver remove |
131 | 131 | //! @param[in] target endpoint |
132 | - void realserver_remove(boost::asio::ip::tcp::endpoint &); | |
132 | + void realserver_remove(const boost::asio::ip::tcp::endpoint &); | |
133 | 133 | protected: |
134 | 134 | typedef data_buff_base<boost::asio::ip::tcp> tcp_data; |
135 | 135 | typedef boost::asio::ip::tcp::endpoint endpoint; |
@@ -268,6 +268,10 @@ protected: | ||
268 | 268 | bool downqos_alert_flag; //! downstream QoS alert flag |
269 | 269 | bool sessionpool_alert_flag; //! sessionpool alert flag |
270 | 270 | |
271 | + bool adm_cmd_wait_flag; //! wait for l7vsadm done | |
272 | + boost::mutex adm_cmd_wait_flag_mutex; | |
273 | + boost::condition adm_cmd_wait_flag_cond; | |
274 | + | |
271 | 275 | void load_parameter(l7vs::error_code &); |
272 | 276 | |
273 | 277 | virtual void handle_replication_interrupt( |
@@ -595,7 +595,9 @@ void tcp_session::set_virtual_service_message(const TCP_VIRTUAL_SERVICE_MESSAGE_ | ||
595 | 595 | fmt % boost::this_thread::get_id(); |
596 | 596 | Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 999, fmt.str(), __FILE__, __LINE__); |
597 | 597 | } |
598 | - break; | |
598 | + //break; | |
599 | + realserver_remove(endpoint_); | |
600 | + return; | |
599 | 601 | case SORRY_STATE_ENABLE: |
600 | 602 | //----Debug log---------------------------------------------------------------------- |
601 | 603 | if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_SESSION))) { |
@@ -1199,22 +1201,40 @@ void tcp_session::up_thread_client_accept_fail_event(const TCP_PROCESS_TYPE_TAG | ||
1199 | 1201 | |
1200 | 1202 | //! real server remove |
1201 | 1203 | //! @param[in] target endpoint |
1202 | -void tcp_session::realserver_remove(endpoint &target_endpoint) | |
1204 | +void tcp_session::realserver_remove(const endpoint &target_endpoint) | |
1203 | 1205 | { |
1206 | + | |
1207 | + if (target_endpoint != realserver_endpoint && target_endpoint != connecting_endpoint) return; | |
1208 | + | |
1204 | 1209 | tcp_thread_message *up_msg = new tcp_thread_message; |
1205 | - up_thread_function_pair up_func = up_thread_function_array[UP_FUNC_REALSERVER_CHECK]; | |
1210 | + up_thread_function_pair up_func = up_thread_function_array[UP_FUNC_EXIT]; | |
1206 | 1211 | up_msg->message = up_func.second; |
1207 | 1212 | up_msg->endpoint_info = target_endpoint; |
1208 | 1213 | #ifdef DEBUG |
1209 | - up_msg->func_tag_name = func_tag_to_string(UP_FUNC_REALSERVER_CHECK); | |
1214 | + up_msg->func_tag_name = func_tag_to_string(UP_FUNC_EXIT); | |
1210 | 1215 | { |
1211 | 1216 | boost::format fmt("Thread ID[%d] up_queue.push : %s"); |
1212 | - fmt % boost::this_thread::get_id() % func_tag_to_string(UP_FUNC_REALSERVER_CHECK); | |
1217 | + fmt % boost::this_thread::get_id() % func_tag_to_string(UP_FUNC_EXIT); | |
1213 | 1218 | Logger::putLogInfo(LOG_CAT_L7VSD_SESSION, 999, fmt.str(), __FILE__, __LINE__); |
1214 | 1219 | } |
1215 | 1220 | #endif |
1216 | 1221 | while (!up_thread_message_que.push(up_msg)) {} |
1217 | 1222 | upthread_status_cond.notify_one(); |
1223 | + | |
1224 | + tcp_thread_message *down_msg = new tcp_thread_message; | |
1225 | + down_thread_function_pair down_func = down_thread_function_array[DOWN_FUNC_EXIT]; | |
1226 | + down_msg->message = down_func.second; | |
1227 | + down_msg->endpoint_info = target_endpoint; | |
1228 | +#ifdef DEBUG | |
1229 | + down_msg->func_tag_name = func_tag_to_string(DOWN_FUNC_EXIT); | |
1230 | + { | |
1231 | + boost::format fmt("Thread ID[%d] down_queue.push : %s"); | |
1232 | + fmt % boost::this_thread::get_id() % func_tag_to_string(DOWN_FUNC_EXIT); | |
1233 | + Logger::putLogInfo(LOG_CAT_L7VSD_SESSION, 999, fmt.str(), __FILE__, __LINE__); | |
1234 | + } | |
1235 | +#endif | |
1236 | + while (!down_thread_message_que.push(down_msg)) {} | |
1237 | + downthread_status_cond.notify_one(); | |
1218 | 1238 | } |
1219 | 1239 | |
1220 | 1240 |
@@ -69,6 +69,7 @@ l7vs::virtualservice_base::virtualservice_base(const l7vs::l7vsd &invsd, | ||
69 | 69 | upqos_alert_flag = false; |
70 | 70 | downqos_alert_flag = false; |
71 | 71 | sessionpool_alert_flag = false; |
72 | + adm_cmd_wait_flag = false; | |
72 | 73 | |
73 | 74 | rs_list.clear(); |
74 | 75 | protomod = NULL; |
@@ -352,6 +352,13 @@ void l7vs::virtualservice_tcp::handle_accept(const l7vs::session_thread_control | ||
352 | 352 | return; |
353 | 353 | } |
354 | 354 | |
355 | + { | |
356 | + boost::mutex::scoped_lock lock(adm_cmd_wait_flag_mutex); | |
357 | + if (unlikely(adm_cmd_wait_flag)){ | |
358 | + adm_cmd_wait_flag_cond.wait(lock); | |
359 | + } | |
360 | + } | |
361 | + | |
355 | 362 | session_thread_control *stc_ptr_noconst = const_cast<session_thread_control *>(stc_ptr); |
356 | 363 | |
357 | 364 | if (unlikely(err == boost::asio::error::operation_aborted)) { // nomal exit case |
@@ -1290,9 +1297,6 @@ void l7vs::virtualservice_tcp::add_realserver(const l7vs::virtualservice_element | ||
1290 | 1297 | } |
1291 | 1298 | } |
1292 | 1299 | |
1293 | - //pause active sessions | |
1294 | - active_sessions.do_all(boost::bind(&session_thread_control::session_pause_on, _1)); | |
1295 | - | |
1296 | 1300 | //add realserver |
1297 | 1301 | for (std::vector<realserver_element>::iterator itr = in_element.realserver_vector.begin(); |
1298 | 1302 | itr != in_element.realserver_vector.end(); |
@@ -1305,9 +1309,6 @@ void l7vs::virtualservice_tcp::add_realserver(const l7vs::virtualservice_element | ||
1305 | 1309 | rs_list.push_back(rs); |
1306 | 1310 | } |
1307 | 1311 | |
1308 | - //run active sessions | |
1309 | - active_sessions.do_all(boost::bind(&session_thread_control::session_pause_off, _1)); | |
1310 | - | |
1311 | 1312 | if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_VIRTUALSERVICE))) { |
1312 | 1313 | boost::format formatter("out_function: void virtualservice_tcp::add_realserver( " |
1313 | 1314 | "const l7vs::virtualservice_element& in," |
@@ -1384,8 +1385,11 @@ void l7vs::virtualservice_tcp::edit_realserver(const l7vs::virtualservice_elemen | ||
1384 | 1385 | } |
1385 | 1386 | } |
1386 | 1387 | |
1387 | - //pause active sessions | |
1388 | - active_sessions.do_all(boost::bind(&session_thread_control::session_pause_on, _1)); | |
1388 | + //lock adm_cmd_wait_flag on | |
1389 | + adm_cmd_wait_flag_mutex.lock(); | |
1390 | + adm_cmd_wait_flag = true; | |
1391 | + adm_cmd_wait_flag_cond.notify_one(); | |
1392 | + adm_cmd_wait_flag_mutex.unlock(); | |
1389 | 1393 | |
1390 | 1394 | //edit realserver |
1391 | 1395 | for (std::vector<realserver_element>::iterator itr = in_element.realserver_vector.begin(); |
@@ -1406,8 +1410,11 @@ void l7vs::virtualservice_tcp::edit_realserver(const l7vs::virtualservice_elemen | ||
1406 | 1410 | } |
1407 | 1411 | } |
1408 | 1412 | |
1409 | - //run active sessions | |
1410 | - active_sessions.do_all(boost::bind(&session_thread_control::session_pause_off, _1)); | |
1413 | + //lock adm_cmd_wait_flag off | |
1414 | + adm_cmd_wait_flag_mutex.lock(); | |
1415 | + adm_cmd_wait_flag = false; | |
1416 | + adm_cmd_wait_flag_cond.notify_one(); | |
1417 | + adm_cmd_wait_flag_mutex.unlock(); | |
1411 | 1418 | |
1412 | 1419 | err.setter(false, ""); |
1413 | 1420 | if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_VIRTUALSERVICE))) { |
@@ -1486,8 +1493,11 @@ void l7vs::virtualservice_tcp::del_realserver(const l7vs::virtualservice_element | ||
1486 | 1493 | } |
1487 | 1494 | } |
1488 | 1495 | |
1489 | - //pause active sessions | |
1490 | - active_sessions.do_all(boost::bind(&session_thread_control::session_pause_on, _1)); | |
1496 | + //lock adm_cmd_wait_flag on | |
1497 | + adm_cmd_wait_flag_mutex.lock(); | |
1498 | + adm_cmd_wait_flag = true; | |
1499 | + adm_cmd_wait_flag_cond.notify_one(); | |
1500 | + adm_cmd_wait_flag_mutex.unlock(); | |
1491 | 1501 | |
1492 | 1502 | //del realserver |
1493 | 1503 | for (std::vector<realserver_element>::iterator itr = in_element.realserver_vector.begin(); |
@@ -1503,8 +1513,11 @@ void l7vs::virtualservice_tcp::del_realserver(const l7vs::virtualservice_element | ||
1503 | 1513 | } |
1504 | 1514 | } |
1505 | 1515 | |
1506 | - //run active sessions | |
1507 | - active_sessions.do_all(boost::bind(&session_thread_control::session_pause_off, _1)); | |
1516 | + //lock adm_cmd_wait_flag off | |
1517 | + adm_cmd_wait_flag_mutex.lock(); | |
1518 | + adm_cmd_wait_flag = false; | |
1519 | + adm_cmd_wait_flag_cond.notify_one(); | |
1520 | + adm_cmd_wait_flag_mutex.unlock(); | |
1508 | 1521 | |
1509 | 1522 | if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_VIRTUALSERVICE))) { |
1510 | 1523 | boost::format formatter("out_function: void virtualservice_tcp::del_realserver( " |