Documentation ¶
Index ¶
- Constants
- Variables
- func NewParentHealthPtr() *util.AtomicPtr[ParentHealth]
- func NewParentServiceHealthPtr() *util.AtomicPtr[ParentServiceHealth]
- func StartParentHealthPoller(pi *ParentInfo, numWorkers int, pollInterval time.Duration, ...) (chan<- struct{}, error)
- func StartParentServiceHealthPoller(pi *ParentInfo, numWorkers int, pollInterval time.Duration, ...) chan<- struct{}
- func StartTrafficMonitorHealthPoller(pi *ParentInfo, updateHealthSignal func()) chan<- struct{}
- type FailOver
- type Host
- type MarkdownServer
- type ParentHealth
- type ParentHealthPollResult
- type ParentHealthPollResultAndFQDN
- type ParentHealthPollType
- type ParentHealthServer
- type ParentInfo
- func (pi *ParentInfo) GetCacheParents() []string
- func (pi *ParentInfo) GetCacheStatuses() (tc.CRStates, error)
- func (pi *ParentInfo) GetParents() []string
- func (pi *ParentInfo) GetTOData(cfg *config.Cfg) error
- func (pi *ParentInfo) LoadOrStoreParentStatus(fdqn string, status ParentStatus) (ParentStatus, bool)
- func (pi *ParentInfo) LoadParentStatus(fqdn string) (ParentStatus, bool)
- func (pi *ParentInfo) StoreParentStatus(fqdn string, st ParentStatus)
- func (pi *ParentInfo) UpdateParentInfo(cfg *config.Cfg) error
- func (pi *ParentInfo) WritePollState() error
- type ParentServiceHealth
- type ParentServiceHealthErrFQDN
- type ParentServiceHealthPollResult
- type ParentStatus
- type Protocol
- type RecursiveParentHealth
- type StatusReason
- type Strategies
- type Strategy
- type TOData
- type TrafficMonitorHealth
Constants ¶
const ( TrafficCtl = "traffic_ctl" ParentsFile = "parent.config" StrategiesFile = "strategies.yaml" )
const HealthSafetyRatio = 0.3 // TODO make configurable?
HealthSafetyRatio is the ratio of unhealthy parents after which no parents will be marked down.
This is a safety mechanism: if for any reason most or all parents are marked down, something is seriously wrong, possibly with the health code itself, and therefore don't mark any parents down,
const ParentHealthPollTypeInvalid = ParentHealthPollType("")
const ParentHealthPollTypeL4 = ParentHealthPollType("l4")
const ParentHealthPollTypeL7 = ParentHealthPollType("l7")
const ParentHealthVersion = "1.0"
Variables ¶
var ParentServicePollTimeoutService = 2 * time.Second
ParentServicePollTimeoutService is the timeout for PollParent. TODO make configurable.
Functions ¶
func NewParentHealthPtr ¶
func NewParentHealthPtr() *util.AtomicPtr[ParentHealth]
NewParentHealthPtr is a convenience func for NewAtomicPtr(NewParentHealth()).
func NewParentServiceHealthPtr ¶
func NewParentServiceHealthPtr() *util.AtomicPtr[ParentServiceHealth]
NewParentServiceHealthPtr is a convenience func for NewAtomicPtr(NewParentServiceHealth()).
func StartParentHealthPoller ¶
func StartParentHealthPoller(pi *ParentInfo, numWorkers int, pollInterval time.Duration, pollType ParentHealthPollType, updateHealthSignal func()) (chan<- struct{}, error)
StartParentHealthPoller polls parents for health every pollInterval. Returns a done channel, which will terminate the polling loop when written to.
func StartParentServiceHealthPoller ¶
func StartParentServiceHealthPoller(pi *ParentInfo, numWorkers int, pollInterval time.Duration, updateHealthSignal func()) chan<- struct{}
StartParentServiceHealthPoller polls parents for health every pollInterval. Note only parents which are caches are polled. Returns a done channel, which will terminate the polling loop when written to.
func StartTrafficMonitorHealthPoller ¶
func StartTrafficMonitorHealthPoller(pi *ParentInfo, updateHealthSignal func()) chan<- struct{}
StartTrafficMonitorHealthPoller The main polling function that keeps the parents list current if with any changes to the trafficserver 'parent.config' or 'strategies.yaml'. Also, it keeps parent status current with the the trafficserver HostStatus subsystem. Finally, on each poll cycle a trafficmonitor is queried to check that all parents used by this trafficserver are available for use based upon the trafficmonitors idea from it's health protocol. Parents are marked up or down in the trafficserver subsystem based upon that hosts current status and the status that trafficmonitor health protocol has determined for a parent.
Types ¶
type FailOver ¶
type FailOver struct { MaxSimpleRetries int `yaml:"max_simple_retries,omitempty"` RingMode string `yaml:"ring_mode,omitempty"` ResponseCodes []int `yaml:"response_codes,omitempty"` MarkDownCodes []int `yaml:"markdown_codes,omitempty"` HealthCheck []string `yaml:"health_check,omitempty"` }
when reading the 'strategies.yaml', these fields are used to help parse out fail_over objects.
type MarkdownServer ¶
type MarkdownServer struct { // Shutdown signals the MarkdownService to stop its goroutines and release all resources. // // It is not buffered. Writes will block until the markdown service is done with any // ongoing markdown operation. Once a write returns, the MarkdownService will begin // shutdown. // TODO: add signal to callers when shutdown has finished. Shutdown chan<- struct{} // UpdateHealth signals to the markdown service that health status has changed, and it should process markdowns again. UpdateHealth func() }
MarkdownServer contains symbols for manipulating a running MarkdownService started by StartMarkdownService.
func StartMarkdownService ¶
func StartMarkdownService(pi *ParentInfo, pollInterval time.Duration) *MarkdownServer
type ParentHealth ¶
type ParentHealth struct { // Version is the direct version of this parent health, which applies to // direct RecursiveParentHealth which are ParentHealth. // // This does not apply to RecursiveParentHealth which are ParentServiceHealth; // rather, their own Version applies. // // Note this is the version of the service sending the result, not the service doing the polling. Version string `json:"version"` // Since is the RFC3339Nano-formatted time that this health result was polled. // Note this is the time of the service doing the polling, not the service sending the result. Since string `json:"since"` ParentHealthPollResults map[string]ParentHealthPollResult `json:"parent_health_poll_results"` }
func DeserializeParentHealth ¶
func DeserializeParentHealth(bts []byte) (*ParentHealth, error)
DeserializeParentHealth deserializes the ParentHealth from network or disk output, as previously serialized with Serialize.
func NewParentHealth ¶
func NewParentHealth() *ParentHealth
type ParentHealthPollResult ¶
type ParentHealthPollResult struct { Healthy bool `json:"healthy"` // UnhealthyReason is a human-readable string as to why the parent was unhealthy. // This will be empty if Healthy is true. UnhealthyReason string `json:"unhealthy_reason,omitempty"` // TODO rename to HealthChangeReason? }
ParentHealthPollResult is the health data from polling a parent. This is currently just a boolean, but may include other data in the future.
type ParentHealthPollResultAndFQDN ¶
type ParentHealthPollResultAndFQDN struct { ParentHealthPollResult ParentFQDN string }
type ParentHealthPollType ¶
type ParentHealthPollType string
func ParentHealthPollTypeFromStr ¶
func ParentHealthPollTypeFromStr(st string) ParentHealthPollType
func (ParentHealthPollType) String ¶
func (pt ParentHealthPollType) String() string
type ParentHealthServer ¶
type ParentHealthServer struct {
// contains filtered or unexported fields
}
func NewParentHealthServer ¶
func NewParentHealthServer(pi *ParentInfo, addr string, readTimeout time.Duration) *ParentHealthServer
func StartParentHealthService ¶
func StartParentHealthService(pi *ParentInfo, port int, readTimeout time.Duration) *ParentHealthServer
StartParentHealthService is a helper function that calls NewParentHealthServer, runs ListenAndServe in a goroutine, and returns the ParentHealthServer. If ListenAndServe returns an error, it's logged to the error log.
func (*ParentHealthServer) ListenAndServe ¶
func (sv *ParentHealthServer) ListenAndServe() error
func (*ParentHealthServer) ListenAndServeTLS ¶
func (sv *ParentHealthServer) ListenAndServeTLS(certFile, keyFile string) error
func (*ParentHealthServer) ServeHTTP ¶
func (sv *ParentHealthServer) ServeHTTP(w http.ResponseWriter, req *http.Request)
type ParentInfo ¶
type ParentInfo struct { ParentDotConfig util.ConfigFile StrategiesDotYaml util.ConfigFile TrafficServerBinDir string TrafficServerConfigDir string Cfg *util.AtomicPtr[config.Cfg] TOData *util.AtomicPtr[TOData] TrafficMonitorHealth *util.AtomicPtr[TrafficMonitorHealth] ParentHealthL4 *util.AtomicPtr[ParentHealth] ParentHealthL7 *util.AtomicPtr[ParentHealth] ParentServiceHealth *util.AtomicPtr[ParentServiceHealth] ParentHealthLog io.WriteCloser MarkdownMethods map[config.HealthMethod]struct{} HealthMethods map[config.HealthMethod]struct{} // ParentHostFQDNs maps hostnames to fqdns, of parents. // This is necessary because Traffic Monitor's CRStates API only maps hostnames to health, // which is mostly okay for CDN caches; but we can't key on hostname anywhere else, because hostnames for non-cache parents aren't unique or meaningful. // So, we key on FQDN everywhere, and this mapping is used to map TM hostnames to their FQDNs. // // Don't use this for anything that includes non-cache (origin) servers. // Hostnames for any servers but caches are not unique and cannot be used as keys. ParentHostFQDNs util.SyncMap[string, string] // contains filtered or unexported fields }
ParentInfo contains the necessary data required to keep track of trafficserver config files, lists of parents a trafficserver instance uses, and directory locations used for configuration and trafficserver executables.
All AtomicPtr members MUST NOT be modified. All AtomicPtr members are accessed concurrently by multiple goroutines, and their objects must be atomically replaced by a single writer, and never modified.
func NewParentInfo ¶
used at startup to load a trafficservers list of parents from it's 'parent.config', 'strategies.yaml' and current parent status from trafficservers HostStatus subsystem.
func (*ParentInfo) GetCacheParents ¶
func (pi *ParentInfo) GetCacheParents() []string
GetCacheParents returns a list of parent FQDNs which are caches (as opposed to origins). See GetParents for concurrency and other details.
func (*ParentInfo) GetCacheStatuses ¶
func (pi *ParentInfo) GetCacheStatuses() (tc.CRStates, error)
Queries a traffic monitor that is monitoring the trafficserver instance running on a host to obtain the availability, health, of a parent used by trafficserver.
func (*ParentInfo) GetParents ¶
func (pi *ParentInfo) GetParents() []string
GetParents returns a list of parent FQDNs. The map of parents is not locked during execution, so if the map data is changed concurrently, whether or not changes are returned will be nondeterministic. It is safe for multiple goroutines.
func (*ParentInfo) GetTOData ¶
func (pi *ParentInfo) GetTOData(cfg *config.Cfg) error
GetTOData fetches data needed from Traffic Ops and refreshes it in the ParentInfo object.
Note it takes a Config, even though ParentInfo has a AtomicPtr[Config], because callers typically need to atomically operate on a single Config. If a caller doesn't already have a Config, simply call pi.GetTOData(pi.Cfg.Get()).
func (*ParentInfo) LoadOrStoreParentStatus ¶
func (pi *ParentInfo) LoadOrStoreParentStatus(fdqn string, status ParentStatus) (ParentStatus, bool)
LoadOrStoreParentStatus adds the given status if fqdn does not exist, and returns the existing value if it does exist. Returns true if the value was loaded, false if it was stored.
This behaves identical to sync.Map.LoadOrStore.
It is safe for multiple goroutines.
func (*ParentInfo) LoadParentStatus ¶
func (pi *ParentInfo) LoadParentStatus(fqdn string) (ParentStatus, bool)
LoadParentStatus returns parent's status and whether the parent existed. It is safe for multiple goroutines.
func (*ParentInfo) StoreParentStatus ¶
func (pi *ParentInfo) StoreParentStatus(fqdn string, st ParentStatus)
StoreParentStatus Sets a parent's status. It is safe for multiple goroutines.
func (*ParentInfo) UpdateParentInfo ¶
func (pi *ParentInfo) UpdateParentInfo(cfg *config.Cfg) error
Used by the polling function to update the parents list from changes to 'parent.config' and 'strategies.yaml'. The parents availability is also updated to reflect the current state from the trafficserver HostStatus subsystem.
func (*ParentInfo) WritePollState ¶
func (pi *ParentInfo) WritePollState() error
type ParentServiceHealth ¶
type ParentServiceHealth struct { // Version is the direct version of this parent health, which applies to // direct RecursiveParentHealth which are ParentHealth. // // This does not apply to RecursiveParentHealth which are ParentServiceHealth; // rather, their own Version applies. Version string `json:"version"` ParentServiceHealthPollResults map[string]RecursiveParentHealth `json:"parent_service_health_poll_results"` // Since is the RFC3339Nano-formatted time that this health result was polled. // Note this is the time of the service doing the polling, not the service sending the result. Since time.Time `json:"since"` }
ParentServiceHealth is the recursive parent health polled from other Parent Health Services.
Parents will be recursively polled. If a parent is a cache, its Parent Health Service will be polled and the result placed in its map key. If a parent is not a cache, its ordinary Parent Health will be placed in its map key. See StartParentHealthPoller.
func CombineParentHealth ¶
func CombineParentHealth(parentHealthL4 *ParentHealth, parentHealthL7 *ParentHealth, parentServiceHealth *ParentServiceHealth) *ParentServiceHealth
CombineParentHealth takes a ParentHealth directly queried from the parent service (ATS or the Origin) and the ParentServiceHealth directly queried from the parent's HealthService, combines them, and returns a ParentServiceHealth with each direct parent's RecursiveParentHealth containing both the direct ParentHealth and the ParentServiceHealth.
If any parent exists in the direct ParentHealth but not ParentServiceHealth (which may be common, if cache parents aren't running the Health Service; and will always be true for origin parents), the direct parent will be inserted into the ParentServiceHealth.
If any parent exists in the ParentServiceHealth but not ParentHealth, that means the actual parent service (ATS or the Origin) was unreachable, even though the Parent Health Service was reachable. In which case, we don't want to ever consider that parent healthy, so it will not be included.
func DeserializeParentServiceHealth ¶
func DeserializeParentServiceHealth(bts []byte) (*ParentServiceHealth, error)
DeserializeParentServiceHealth deserializes the ParentHealth from network or disk output, as previously serialized with Serialize.
func NewParentServiceHealth ¶
func NewParentServiceHealth() *ParentServiceHealth
type ParentServiceHealthErrFQDN ¶
type ParentServiceHealthErrFQDN struct { Health RecursiveParentHealth Err error FQDN string }
ParentServiceHealthErrFQDN contains the health, any error, and the parent fqdn. This is used to return on a result chan from a poll worker.
type ParentServiceHealthPollResult ¶
type ParentServiceHealthPollResult struct { Healthy bool // UnhealthyReason is a human-readable string as to why the parent was unhealthy. // This will be empty if Healthy is true. UnhealthyReason string // TODO rename to HealthChangeReason? }
ParentServiceHealthPollResult is the health data from polling a parent. This is currently just a boolean, but may include other data in the future. TODO delete
type ParentStatus ¶
type ParentStatus struct { Fqdn string ActiveReason bool LocalReason bool ManualReason bool LastTmPoll int64 MarkUpPollCount int }
ParentStatus contains the trafficserver 'HostStatus' fields that are necessary to interface with the trafficserver 'traffic_ctl' command.
func (ParentStatus) Status ¶
func (p ParentStatus) Status() string
used to log that a parent's status is either UP or DOWN based upon the HostStatus reason codes. to be considered UP, all reason codes must be 'true'.
type Protocol ¶
type Protocol struct { Scheme string `yaml:"scheme"` Port int `yaml:"port"` Health_check_url string `yaml:"health_check_url,omitempty"` Weight float64 `yaml:"weight,omitempty"` }
the protocol object in 'strategies.yaml' that help to describe a parent.
type RecursiveParentHealth ¶
type RecursiveParentHealth struct { ParentHealthL4 *ParentHealthPollResult `json:"parent_health_l4"` ParentHealthL7 *ParentHealthPollResult `json:"parent_health_l7"` ParentServiceHealth *ParentServiceHealth `json:"parent_service_health"` // debug }
RecursiveParentHealth is either a poll from a direct parent poll of a non-cache or a ParentServiceHealth from a parent service poll of a cache.
Either ParentHealth or ParentServiceHealth will not be nil, but never both.
This would be more elegant as an interface, but a struct with two pointers is easier to deserialize.
type StatusReason ¶
type StatusReason int
const ( ACTIVE StatusReason = iota LOCAL MANUAL )
these are the HostStatus reason codes used within trafficserver.
func (StatusReason) String ¶
func (s StatusReason) String() string
used for logging a parent's HostStatus reason code setting.
type Strategies ¶
type Strategies struct { Strategy []Strategy `yaml:"strategies"` Hosts []Host `yaml:"hosts"` Groups []interface{} `yaml:"groups"` }
the top level array defintions in a trafficserver 'strategies.yaml' configuration file.
type Strategy ¶
type Strategy struct { Strategy string `yaml:"strategy"` Policy string `yaml:"policy"` HashKey string `yaml:"hash_key,omitempty"` GoDirect bool `yaml:"go_direct,omitempty"` ParentIsProxy bool `yaml:"parent_is_proxy,omitempty"` CachePeerResult bool `yaml:"cache_peer_result,omitempty"` Scheme string `yaml:"scheme"` FailOvers FailOver `yaml:"failover,omitempty"` }
a trafficserver strategy object from 'strategies.yaml'.
type TOData ¶
type TOData struct { UserAgent string TOClient *toclient.Session Monitors map[string]struct{} `json:"trafficmonitors,omitempty"` // set[fqdn] Caches map[string]struct{} `json:"caches,omitempty"` // set[fqdn] }
TOData is the Traffic Ops data needed by various services.
type TrafficMonitorHealth ¶
type TrafficMonitorHealth struct { // PollTime is the local time this TM health was obtained PollTime time.Time CacheStatuses map[tc.CacheName]tc.IsAvailable }
func NewTrafficMonitorHealth ¶
func NewTrafficMonitorHealth() *TrafficMonitorHealth