Skip to content

Commit

Permalink
Removed anycast functionality from traffic control (#62)
Browse files Browse the repository at this point in the history
* removed anycast functionality from traffic control

* added changelog for pr

* corrected formatting in traffic_monitor/datareq/datareq.go

---------

Co-authored-by: serDrem <[email protected]>
  • Loading branch information
2 people authored and rimashah25 committed Dec 4, 2023
1 parent fa231d7 commit 0248c37
Show file tree
Hide file tree
Showing 18 changed files with 22 additions and 424 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#7870](https://github.com/apache/trafficcontrol/pull/7870) *Traffic Portal*: Adds a hyperlink to the DSR page to the DS itself for ease of navigation.

### Changed
- [#62] (https://github.com/comcast-cdn/trafficcontrol/pull/62) *Traffic Monitor, Documentation* Removed anycast functionality from traffic control
- [#7614](https://github.com/apache/trafficcontrol/pull/7614) *Traffic Ops* The database upgrade process no longer overwrites changes users may have made to the initially seeded data.
- [#7832](https://github.com/apache/trafficcontrol/pull/7832) *t3c* Removed perl dependency
- Updated the CacheGroups Traffic Portal page to use a more performant AG-Grid-based table.
Expand Down
1 change: 0 additions & 1 deletion docs/source/admin/traffic_monitor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ traffic_monitor.cfg
- ``health.polling.interval``
- ``peers.polling.interval``
- ``heartbeat.polling.interval``
- ``tm.sameipservers.enabled`` - When set to true, performs an AND operation on the availability statuses of servers with same ip. Any unavailable server(s) with same ip as other server(s) will cause the other server(s) to be set to unavailable.

Upon receiving this configuration, Traffic Monitor begins polling :term:`cache server` s. Once every :term:`cache server` has been polled, :ref:`health-proto` state is available via RESTful JSON endpoints and a web browser UI.

Expand Down
5 changes: 0 additions & 5 deletions docs/source/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ Glossary
- :term:`forward proxy`: Used by Traffic Control for Mid-tier :dfn:`cache servers`.
- transparent proxy: These are not used by Traffic Control. If you are interested you can learn more about transparent proxies on `wikipedia <http://en.wikipedia.org/wiki/Proxy_server#Transparent_proxy>`_.

anycast group
Anycast group
Anycast Group
A group of caching HTTP proxy servers that have the same service address that is equal cost multi path routed at the last hop

Cache Group
Cache Groups
A group of caching HTTP proxy servers that together create a combined larger cache using consistent hashing. Traffic Router treats all servers in a :dfn:`Cache Group` as though they are in the same geographic location, though they are in fact only in the same general area. A :dfn:`Cache Group` has one single set of geographical coordinates even if the :term:`cache servers` that make up the :dfn:`Cache Group` are actually in :term:`Physical Locations`. The :term:`cache servers` in a :dfn:`Cache Group` are not aware of the other :term:`cache servers` in the group - there is no clustering software or communications between :term:`cache servers` in a :dfn:`Cache Group`.
Expand Down
4 changes: 0 additions & 4 deletions docs/source/overview/traffic_monitor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,3 @@ The optimistic quorum prevents invalid state propagation caused by a Traffic Mon
Protocol Engagement
-------------------
Short polling intervals of both the :term:`cache servers` and Traffic Monitor peers help to reduce customer impact of outages. It is not uncommon for a :term:`cache server` to be marked unavailable by Traffic Monitor - in fact, it is business as usual for many CDNs. Should a widely requested video asset cause a single :term:`cache server` to get close to its interface capacity, the Health Protocol will "kick in," and Traffic Monitor marks the :term:`cache server` as unavailable. New clients want to see the same asset, and now :ref:`tr-overview` will send these customers to another :term:`cache server` in the same :term:`Cache Group`. The load is now shared between the two :term:`cache servers`. As clients finish watching the asset on the overloaded :term:`cache server`, it will drop below the threshold and gets marked available again, and new clients will begin to be directed to it once more. It is less common for a :term:`Delivery Service` to be marked unavailable by Traffic Monitor. The :term:`Delivery Service` thresholds are usually used for overflow situations at extreme peaks to protect other :term:`Delivery Services` in the CDN from being impacted.

Handling Cache Servers with Same Service IP
-------------------------------------------
Traffic Monitor is able to direct Traffic Router to route traffic to groups of :term:`cache servers` with the same service IP address, but not to an individual :term:`cache server` within that group. To monitor :term:`cache servers` within that group, HTTP :mailheader:`Keep-Alive` header is omitted with the ``health.polling.keepalive`` and ``stat.polling.keepalive`` Traffic Monitor :term:`profile` :term:`parameters` so that the Traffic Monitor source port changes for those connections and the Traffic Monitor can get to all the :term:`cache servers` within that group via `ECMP <https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing>`(Equal Cost Multi Path). ECMP rules govern routing to destinations with equal cost. Changing the source port ensures all the routes to :term:`cache servers` within an ECMP group are taken. Then Traffic Monitor updates the responses using the :mailheader:`Via` header. In the event of :dfn:`Health Protocol` determining the overall health of one of the :term:`cache servers` in an anycast group by evaluating network throughput and load against values configured in :ref:`to-overview` to exceed their limit, it declares the whole groups as unhealthy.
1 change: 0 additions & 1 deletion lib/go-rfc/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const (
Age = "Age" // RFC7234§5.1
Location = "Location" // RFC7231§7.1.2
Authorization = "Authorization" // RFC7235§4.2
Via = "Via" // RFC3261§8.1.1.7
Cookie = "Cookie" // RFC7873
)

Expand Down
1 change: 0 additions & 1 deletion lib/go-tc/crstates.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ type IsAvailable struct {
DirectlyPolled bool `json:"-"`
Status string `json:"status"`
LastPoll time.Time `json:"lastPoll"`
LastPollV6 time.Time `json:"lastPollV6"`
}

// NewCRStates creates a new CR states object, initializing pointer members.
Expand Down
18 changes: 0 additions & 18 deletions traffic_monitor/cache/astats.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,17 @@ import (
"errors"
"fmt"
"io"
"regexp"
"strings"

"github.com/apache/trafficcontrol/v8/lib/go-log"
"github.com/apache/trafficcontrol/v8/lib/go-rfc"
"github.com/apache/trafficcontrol/v8/traffic_monitor/dsdata"
"github.com/apache/trafficcontrol/v8/traffic_monitor/poller"
"github.com/apache/trafficcontrol/v8/traffic_monitor/todata"

jsoniter "github.com/json-iterator/go"
)

func init() {
registerDecoder("astats", astatsParse, astatsPrecompute)
hostnameRegex = regexp.MustCompile(`(?:http|https)/\d+\.\d+ ([A-Za-z0-9\-]{0,61})`)
}

// AstatsSystem represents fixed system stats returned from the
Expand Down Expand Up @@ -120,22 +116,8 @@ func astatsParse(cacheName string, rdr io.Reader, pollCTX interface{}) (Statisti
astats.Ats["system.proc.loadavg"] = astats.System.ProcLoadavg
astats.Ats["system.proc.net.dev"] = astats.System.ProcNetDev

via := ctx.HTTPHeader.Get(rfc.Via)
if via != "" {
viaRegexSubmatch := hostnameRegex.FindStringSubmatch(via)
if len(viaRegexSubmatch) > 0 {
astats.Ats[rfc.Via] = viaRegexSubmatch[1]
}
}
return stats, astats.Ats, nil
} else if ctype == "text/csv" {
via := ctx.HTTPHeader.Get(rfc.Via)
if via != "" {
viaRegexSubmatch := hostnameRegex.FindStringSubmatch(via)
if len(viaRegexSubmatch) > 0 {
cacheName = viaRegexSubmatch[1]
}
}
return astatsCsvParseCsv(cacheName, rdr)
} else {
return stats, nil, fmt.Errorf("stats Content-Type (%s) can not be parsed by astats", ctype)
Expand Down
3 changes: 0 additions & 3 deletions traffic_monitor/cache/astats_csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"strings"

"github.com/apache/trafficcontrol/v8/lib/go-log"
"github.com/apache/trafficcontrol/v8/lib/go-rfc"
)

type astatsDataCsv struct {
Expand Down Expand Up @@ -129,7 +128,5 @@ func astatsCsvParseCsv(cacheName string, data io.Reader) (Statistics, map[string
return stats, nil, fmt.Errorf("cache '%s' had no interfaces", cacheName)
}

statMap[rfc.Via] = cacheName

return stats, statMap, nil
}
8 changes: 0 additions & 8 deletions traffic_monitor/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@ package cache
*/

import (
"fmt"
"io"
"regexp"
"time"

"github.com/apache/trafficcontrol/v8/lib/go-log"
"github.com/apache/trafficcontrol/v8/lib/go-rfc"
"github.com/apache/trafficcontrol/v8/lib/go-tc"
"github.com/apache/trafficcontrol/v8/traffic_monitor/todata"
)
Expand All @@ -37,8 +34,6 @@ type Handler struct {
ToData *todata.TODataThreadsafe
}

var hostnameRegex *regexp.Regexp

func (h Handler) ResultChan() <-chan Result {
return h.resultChan
}
Expand Down Expand Up @@ -316,9 +311,6 @@ func (handler Handler) Handle(id string, rdr io.Reader, format string, reqTime t
}
result.Time = time.UnixMilli(int64(valInt))
}
if value, ok := miscStats[rfc.Via]; ok {
result.ID = fmt.Sprintf("%v", value)
}

result.Statistics = stats
result.Miscellaneous = miscStats
Expand Down
4 changes: 0 additions & 4 deletions traffic_monitor/cache/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ type AvailableStatus struct {
UnavailableStat string
// Poller is the name of the poller which set this availability status.
Poller string
// Time of last poll
LastPoll time.Time
// Time of v6 last poll
LastPollV6 time.Time
}

// CacheAvailableStatuses is the available status of each cache.
Expand Down
13 changes: 0 additions & 13 deletions traffic_monitor/cache/stats_over_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ import (
"fmt"
"io"
"math"
"regexp"
"strconv"
"strings"

"github.com/apache/trafficcontrol/v8/lib/go-log"
"github.com/apache/trafficcontrol/v8/lib/go-rfc"
"github.com/apache/trafficcontrol/v8/traffic_monitor/poller"
"github.com/apache/trafficcontrol/v8/traffic_monitor/todata"

Expand All @@ -55,7 +53,6 @@ const LOADAVG_SHIFT = 65536

func init() {
registerDecoder("stats_over_http", statsOverHTTPParse, statsOverHTTPPrecompute)
hostnameRegex = regexp.MustCompile(`(?:http|https)/\d+\.\d+ ([A-Za-z0-9\-]{0,61})`)
}

type stats_over_httpData struct {
Expand All @@ -74,14 +71,6 @@ func statsOverHTTPParse(cacheName string, data io.Reader, pollCTX interface{}) (

ctx := pollCTX.(*poller.HTTPPollCtx)

via := ctx.HTTPHeader.Get(rfc.Via)
if via != "" {
viaRegexSubmatch := hostnameRegex.FindStringSubmatch(via)
if len(viaRegexSubmatch) > 0 {
cacheName = viaRegexSubmatch[1]
}
}

ctype := ctx.HTTPHeader.Get("Content-Type")

if ctype == "text/json" || ctype == "text/javascript" || ctype == "application/json" || ctype == "" {
Expand All @@ -105,8 +94,6 @@ func statsOverHTTPParse(cacheName string, data io.Reader, pollCTX interface{}) (

statMap := sohData.Global

statMap[rfc.Via] = cacheName

if stats.Loadavg, err = parseLoadAvg(statMap); err != nil {
return stats, nil, fmt.Errorf("Error parsing loadavg for cache '%s': %v", cacheName, err)
}
Expand Down
77 changes: 13 additions & 64 deletions traffic_monitor/datareq/crstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,10 @@ import (
"fmt"
"net/http"
"net/url"
"strings"

"github.com/apache/trafficcontrol/v8/lib/go-log"
"github.com/apache/trafficcontrol/v8/lib/go-tc"
"github.com/apache/trafficcontrol/v8/traffic_monitor/health"
"github.com/apache/trafficcontrol/v8/traffic_monitor/peer"
"github.com/apache/trafficcontrol/v8/traffic_monitor/threadsafe"
"github.com/apache/trafficcontrol/v8/traffic_monitor/todata"
)

func srvTRState(
Expand All @@ -39,13 +35,11 @@ func srvTRState(
combinedStates peer.CRStatesThreadsafe,
peerStates peer.CRStatesPeersThreadsafe,
distributedPollingEnabled bool,
toData todata.TODataThreadsafe,
monitorConfig threadsafe.TrafficMonitorConfigMap,
) ([]byte, int, error) {
_, raw := params["raw"] // peer polling case
_, local := params["local"] // distributed peer polling case
if raw {
data, err := srvTRStateData(localStates, distributedPollingEnabled, toData, monitorConfig)
data, err := srvTRStateSelf(localStates, distributedPollingEnabled)

Check warning on line 42 in traffic_monitor/datareq/crstate.go

View check run for this annotation

Codecov / codecov/patch

traffic_monitor/datareq/crstate.go#L42

Added line #L42 was not covered by tests
return data, http.StatusOK, err
}

Expand All @@ -64,11 +58,19 @@ func srvTRState(
}
}

data, err := srvTRStateData(combinedStates, local && distributedPollingEnabled, toData, monitorConfig)
data, err := srvTRStateDerived(combinedStates, local && distributedPollingEnabled)

Check warning on line 61 in traffic_monitor/datareq/crstate.go

View check run for this annotation

Codecov / codecov/patch

traffic_monitor/datareq/crstate.go#L61

Added line #L61 was not covered by tests

return data, http.StatusOK, err
}

func srvTRStateDerived(combinedStates peer.CRStatesThreadsafe, directlyPolledOnly bool) ([]byte, error) {
if !directlyPolledOnly {
return tc.CRStatesMarshall(combinedStates.Get())
}
unfiltered := combinedStates.Get()
return tc.CRStatesMarshall(filterDirectlyPolledCaches(unfiltered))

Check warning on line 71 in traffic_monitor/datareq/crstate.go

View check run for this annotation

Codecov / codecov/patch

traffic_monitor/datareq/crstate.go#L66-L71

Added lines #L66 - L71 were not covered by tests
}

func filterDirectlyPolledCaches(crstates tc.CRStates) tc.CRStates {
filtered := tc.CRStates{
Caches: make(map[tc.CacheName]tc.IsAvailable),
Expand All @@ -82,63 +84,10 @@ func filterDirectlyPolledCaches(crstates tc.CRStates) tc.CRStates {
return filtered
}

func srvTRStateData(localStates peer.CRStatesThreadsafe, directlyPolledOnly bool, toData todata.TODataThreadsafe, monitorConfig threadsafe.TrafficMonitorConfigMap) ([]byte, error) {
if val, ok := monitorConfig.Get().Config["tm.sameipservers.enabled"]; ok && val.(string) == "true" {
localStatesC := updateStatusSameIpServers(localStates, toData)
if !directlyPolledOnly {
return tc.CRStatesMarshall(localStatesC)
}
return tc.CRStatesMarshall(filterDirectlyPolledCaches(localStatesC))
}
func srvTRStateSelf(localStates peer.CRStatesThreadsafe, directlyPolledOnly bool) ([]byte, error) {

Check warning on line 87 in traffic_monitor/datareq/crstate.go

View check run for this annotation

Codecov / codecov/patch

traffic_monitor/datareq/crstate.go#L87

Added line #L87 was not covered by tests
if !directlyPolledOnly {
return tc.CRStatesMarshall(localStates.Get())
}
return tc.CRStatesMarshall(filterDirectlyPolledCaches(localStates.Get()))
}

func updateStatusSameIpServers(localStates peer.CRStatesThreadsafe, toData todata.TODataThreadsafe) tc.CRStates {
localStatesC := localStates.Get()
toDataC := toData.Get()

for cache, _ := range localStatesC.Caches {
if _, ok := toDataC.SameIpServers[cache]; ok {
// all servers with same ip must be available if they are in reported state
allAvailableV4 := true
allAvailableV6 := true
allIsAvailable := true
for partner, _ := range toDataC.SameIpServers[cache] {
if partnerState, ok := localStatesC.Caches[partner]; ok {
// a partner host is reported but is marked down for exceeding a threshold
// this host also needs to be marked down to divert all traffic for their
// common ip
if strings.Contains(partnerState.Status, string(tc.CacheStatusReported)) &&
strings.Contains(partnerState.Status, health.TooHigh.String()) {
if !partnerState.Ipv4Available {
allAvailableV4 = false
}
if !partnerState.Ipv6Available {
allAvailableV6 = false
}
if !partnerState.IsAvailable {
allIsAvailable = false
}
if !allAvailableV4 && !allAvailableV6 && !allIsAvailable {
break
}
}
}
}
newIsAvailable := tc.IsAvailable{}
newIsAvailable.DirectlyPolled = localStatesC.Caches[cache].DirectlyPolled
newIsAvailable.Status = localStatesC.Caches[cache].Status
newIsAvailable.LastPoll = localStatesC.Caches[cache].LastPoll
newIsAvailable.LastPollV6 = localStatesC.Caches[cache].LastPollV6
newIsAvailable.IsAvailable = localStatesC.Caches[cache].IsAvailable && allIsAvailable
newIsAvailable.Ipv4Available = localStatesC.Caches[cache].Ipv4Available && allAvailableV4
newIsAvailable.Ipv6Available = localStatesC.Caches[cache].Ipv6Available && allAvailableV6

localStatesC.Caches[cache] = newIsAvailable
}
}
return localStatesC
unfiltered := localStates.Get()
return tc.CRStatesMarshall(filterDirectlyPolledCaches(unfiltered))

Check warning on line 92 in traffic_monitor/datareq/crstate.go

View check run for this annotation

Codecov / codecov/patch

traffic_monitor/datareq/crstate.go#L91-L92

Added lines #L91 - L92 were not covered by tests
}
Loading

0 comments on commit 0248c37

Please sign in to comment.