Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/access_log/access_log.h" 4 : #include "envoy/common/callback.h" 5 : #include "envoy/common/random_generator.h" 6 : #include "envoy/config/core/v3/health_check.pb.h" 7 : #include "envoy/data/core/v3/health_check_event.pb.h" 8 : #include "envoy/event/timer.h" 9 : #include "envoy/runtime/runtime.h" 10 : #include "envoy/stats/scope.h" 11 : #include "envoy/type/matcher/string.pb.h" 12 : #include "envoy/upstream/health_checker.h" 13 : 14 : #include "source/common/common/logger.h" 15 : #include "source/common/common/matchers.h" 16 : #include "source/common/network/transport_socket_options_impl.h" 17 : 18 : namespace Envoy { 19 : namespace Upstream { 20 : 21 : /** 22 : * All health checker stats. @see stats_macros.h 23 : */ 24 : #define ALL_HEALTH_CHECKER_STATS(COUNTER, GAUGE) \ 25 50 : COUNTER(attempt) \ 26 50 : COUNTER(failure) \ 27 50 : COUNTER(network_failure) \ 28 50 : COUNTER(passive_failure) \ 29 50 : COUNTER(success) \ 30 50 : COUNTER(verify_cluster) \ 31 50 : GAUGE(degraded, Accumulate) \ 32 50 : GAUGE(healthy, Accumulate) 33 : 34 : /** 35 : * Definition of all health checker stats. @see stats_macros.h 36 : */ 37 : struct HealthCheckerStats { 38 : ALL_HEALTH_CHECKER_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT) 39 : }; 40 : 41 : /** 42 : * Base implementation for all health checkers. 43 : */ 44 : class HealthCheckerImplBase : public HealthChecker, 45 : protected Logger::Loggable<Logger::Id::hc>, 46 : public std::enable_shared_from_this<HealthCheckerImplBase> { 47 : public: 48 : // Upstream::HealthChecker 49 0 : void addHostCheckCompleteCb(HostStatusCb callback) override { callbacks_.push_back(callback); } 50 : void start() override; 51 69 : std::shared_ptr<const Network::TransportSocketOptionsImpl> transportSocketOptions() const { 52 69 : return transport_socket_options_; 53 69 : } 54 69 : MetadataConstSharedPtr transportSocketMatchMetadata() const { 55 69 : return transport_socket_match_metadata_; 56 69 : } 57 : 58 : protected: 59 : class ActiveHealthCheckSession : public Event::DeferredDeletable { 60 : public: 61 : ~ActiveHealthCheckSession() override; 62 : HealthTransition setUnhealthy(envoy::data::core::v3::HealthCheckFailureType type, 63 : bool retriable); 64 : void onDeferredDeleteBase(); 65 46 : void start() { onInitialInterval(); } 66 : 67 : protected: 68 : ActiveHealthCheckSession(HealthCheckerImplBase& parent, HostSharedPtr host); 69 : 70 : void handleSuccess(bool degraded = false); 71 : void handleFailure(envoy::data::core::v3::HealthCheckFailureType type, bool retriable = false); 72 : 73 : HostSharedPtr host_; 74 : 75 : private: 76 : // Clears the pending flag if it is set. By clearing this flag we're marking the host as having 77 : // been health checked. 78 : // Returns the changed state to use following the flag update. 79 : HealthTransition clearPendingFlag(HealthTransition changed_state); 80 : virtual void onInterval() PURE; 81 : void onIntervalBase(); 82 : virtual void onTimeout() PURE; 83 : void onTimeoutBase(); 84 : virtual void onDeferredDelete() PURE; 85 : void onInitialInterval(); 86 : 87 : HealthCheckerImplBase& parent_; 88 : Event::TimerPtr interval_timer_; 89 : Event::TimerPtr timeout_timer_; 90 : uint32_t num_unhealthy_{}; 91 : uint32_t num_healthy_{}; 92 : bool first_check_{true}; 93 : TimeSource& time_source_; 94 : }; 95 : 96 : using ActiveHealthCheckSessionPtr = std::unique_ptr<ActiveHealthCheckSession>; 97 : 98 : HealthCheckerImplBase(const Cluster& cluster, const envoy::config::core::v3::HealthCheck& config, 99 : Event::Dispatcher& dispatcher, Runtime::Loader& runtime, 100 : Random::RandomGenerator& random, HealthCheckEventLoggerPtr&& event_logger); 101 : ~HealthCheckerImplBase() override; 102 : 103 : virtual ActiveHealthCheckSessionPtr makeSession(HostSharedPtr host) PURE; 104 : virtual envoy::data::core::v3::HealthCheckerType healthCheckerType() const PURE; 105 : 106 : const bool always_log_health_check_failures_; 107 : const Cluster& cluster_; 108 : Event::Dispatcher& dispatcher_; 109 : const std::chrono::milliseconds timeout_; 110 : const uint32_t unhealthy_threshold_; 111 : const uint32_t healthy_threshold_; 112 : HealthCheckerStats stats_; 113 : Runtime::Loader& runtime_; 114 : Random::RandomGenerator& random_; 115 : const bool reuse_connection_; 116 : HealthCheckEventLoggerPtr event_logger_; 117 : 118 : private: 119 : struct HealthCheckHostMonitorImpl : public HealthCheckHostMonitor { 120 : HealthCheckHostMonitorImpl(const std::shared_ptr<HealthCheckerImplBase>& health_checker, 121 : const HostSharedPtr& host) 122 46 : : health_checker_(health_checker), host_(host) {} 123 : 124 : // Upstream::HealthCheckHostMonitor 125 : void setUnhealthy(UnhealthyType type) override; 126 : 127 : std::weak_ptr<HealthCheckerImplBase> health_checker_; 128 : std::weak_ptr<Host> host_; 129 : }; 130 : 131 : void addHosts(const HostVector& hosts); 132 : void decHealthy(); 133 : void decDegraded(); 134 : HealthCheckerStats generateStats(Stats::Scope& scope); 135 : void incHealthy(); 136 : void incDegraded(); 137 : std::chrono::milliseconds interval(HealthState state, HealthTransition changed_state) const; 138 : std::chrono::milliseconds intervalWithJitter(uint64_t base_time_ms, 139 : std::chrono::milliseconds interval_jitter) const; 140 : void onClusterMemberUpdate(const HostVector& hosts_added, const HostVector& hosts_removed); 141 : void runCallbacks(HostSharedPtr host, HealthTransition changed_state); 142 : void setUnhealthyCrossThread(const HostSharedPtr& host, 143 : HealthCheckHostMonitor::UnhealthyType type); 144 : static std::shared_ptr<const Network::TransportSocketOptionsImpl> 145 : initTransportSocketOptions(const envoy::config::core::v3::HealthCheck& config); 146 : static MetadataConstSharedPtr 147 : initTransportSocketMatchMetadata(const envoy::config::core::v3::HealthCheck& config); 148 : 149 : std::list<HostStatusCb> callbacks_; 150 : const std::chrono::milliseconds interval_; 151 : const std::chrono::milliseconds no_traffic_interval_; 152 : const std::chrono::milliseconds no_traffic_healthy_interval_; 153 : const std::chrono::milliseconds initial_jitter_; 154 : const std::chrono::milliseconds interval_jitter_; 155 : const uint32_t interval_jitter_percent_; 156 : const std::chrono::milliseconds unhealthy_interval_; 157 : const std::chrono::milliseconds unhealthy_edge_interval_; 158 : const std::chrono::milliseconds healthy_edge_interval_; 159 : absl::node_hash_map<HostSharedPtr, ActiveHealthCheckSessionPtr> active_sessions_; 160 : const std::shared_ptr<const Network::TransportSocketOptionsImpl> transport_socket_options_; 161 : const MetadataConstSharedPtr transport_socket_match_metadata_; 162 : const Common::CallbackHandlePtr member_update_cb_; 163 : }; 164 : 165 : } // namespace Upstream 166 : } // namespace Envoy