在超过容量的情况下,在严重队列中持续大量丢弃数据包是很常见的,并且可能会影响客户。

应密切监控以下严重队列中的计数器。

vc_queue_net_sch、vc_queue_link_select 和 vc_queue_link_sch - 这些调度程序适用于为发送到 Edge 的数据包选择链路,设置 QOS 以及计划链路。Orchestrator 从全局数据包调度程序 (vc_queue_net_sch) 中接收数据包,选择用于发送它们的相应链路 (vc_queue_link_select),并将其排队以由链路级别数据包调度程序 (vc_queue_link_sch) 进行处理。

在其中丢弃数据包表示,网关无法足够快地将 VCMP 流量(例如,从 Internet 返回的数据包)发送到 Edge。

vc_queue_link_encrypt_0 和 vc_queue_link_encrypt_1 - 这是基于软件的数据包加密,它管理数据包加密和封装以及在发送数据包之前进行的类似处理。

在启用了 DPDK 的网关上,首先在该队列中发现容量问题(即,丢弃了数据包)。在该队列中丢弃数据包表示,网关无法足够快地加密流量。

vc_queue_vcmp_tx - 这是指发送 VCMP 数据包。该队列负责在接口上发送数据包,并根据需要排队进行潜在的重新发送以及清除数据包。在该队列中丢弃数据包表示,网关无法足够快地将 VCMP 流量(例如,从 Internet 返回的数据包)发送到 Edge。

以下是一个用于检查 vcmp_tx 数据包丢弃的示例 Python 脚本。请对在队列中丢弃数据包的网关运行 Python 脚本以查看问题详细信息。

#!/usr/bin/env python
"""
Check VCG vcmp handoff drops packet check
"""
import os
import sys
import subprocess
import commands
import re
import json
from optparse import OptionParser

# Parse commandline options:
parser = OptionParser(usage="%prog -w <warning threshold> -c <critical threshold> [ -h ]")
parser.add_option("-w", "--warning", action="store", type="string", dest="warn_threshold", help="Count Warning threshold should be in <value>")
parser.add_option("-c", "--critical",action="store", type="string", dest="crit_threshold", help="Count Critical threshold should be in <value>")
(options, args) = parser.parse_args()

json_data= {"vcg_handoff_data": {"count":0,"drops":[]}}
vcg_handoff_file="/tmp/vcg_handoff_drop_check"
bw_threshold=768000

def find_bw_throughput():
    total_bw = 0
    value = 2
    flag = os.path.exists("/opt/vc/etc/dpdk-override.json")
    if flag is True:
       with open("/opt/vc/etc/dpdk-override.json") as json_file:
            data = json.load(json_file)
       value = data["enabled"]
    if value == 0:
      status,output = commands.getstatusoutput("ifstat  -bqTn 1 1")
      if status == 0:
         total_bw = float(output.splitlines()[-1].split()[-1]) + float(output.splitlines()[-1].split()[-2])
    return int(total_bw)

def store_vcg_hanoff_queue_qlength():
    samples_count = 5
    if not os.path.isfile(vcg_handoff_file):
       with open(vcg_handoff_file, 'w') as outfile:
           json.dump(json_data, outfile )

    if os.path.isfile(vcg_handoff_file):
       with open(vcg_handoff_file) as vcg_handoff_data:
           handoff_data = json.load(vcg_handoff_data)
    else:
       with open(vcg_handoff_file, 'w') as outfile:
           json.dump(json_data, outfile )

    if os.path.isfile('/opt/vc/bin/debug.py'):
       L=[]
       f=subprocess.check_output(["/opt/vc/bin/debug.py","--handoff"])
       x=[r.split() for r in f.split('\n')]
       res = list(filter(None, x))

       if handoff_data["vcg_handoff_data"]["count"] == 0:
           for item in res:
              if not item[0] == "name":
                 #handoff_data["vcg_handoff_data"]["drops"].append({item[0]:[item[13]]})
                 handoff_data["vcg_handoff_data"]["drops"].append({item[0]:["1"] * samples_count})
                 handoff_data["vcg_handoff_data"]["count"] = 1
           with open(vcg_handoff_file, 'w') as outfile:
                json.dump(handoff_data, outfile )

       if not handoff_data["vcg_handoff_data"]["count"] == 0:
        count_status = handoff_data["vcg_handoff_data"]["count"] - 1
        for item in res:
            if not item[0] == "name":
               for key in  handoff_data["vcg_handoff_data"]["drops"]:
                   field_num = len(item) - 6
                   if item[0] == key.keys()[0]:
                      key[key.keys()[0]].append(item[field_num])
                      del key[key.keys()[0]][0]
                      #key[key.keys()[0]][count_status]=item[field_num]
        handoff_data["vcg_handoff_data"]["count"] += 1
        if handoff_data["vcg_handoff_data"]["count"] == samples_count + 1:
           handoff_data["vcg_handoff_data"]["count"] = 1

        with open(vcg_handoff_file, 'w') as outfile:
           json.dump(handoff_data, outfile )

def get_status_of_drops(warn_value,crit_value):
    result = []
    diff_drops_data = []
    both_value = False
    total_bw = find_bw_throughput()
    if os.path.isfile(vcg_handoff_file):
       with open(vcg_handoff_file) as vcg_handoff_data:
           handoff_data = json.load(vcg_handoff_data)

    for drops in handoff_data["vcg_handoff_data"]["drops"]:
       for key,value in drops.items():
           if key == "vc_queue_vcmp_tx_0":
               for cumlative_data in range(len(value)):
                  if not cumlative_data == 4:
                     drop_value = int(value[cumlative_data+1]) - int(value[cumlative_data])
                     diff_drops_data.append(drop_value)
                     warn_counter = 0
                     crit_counter = 0
                     for data in diff_drops_data:
                        if int(data) >= int(crit_value) and int(total_bw) > int(bw_threshold):
                           both_value = True
                        if int(data) > int(crit_value):
                          crit_counter +=1
                        if int(data) > int(warn_value) and  int(data) < int(crit_value):
                          warn_counter +=1
                     if both_value == True:
                        if not result:
                           result.append({key:diff_drops_data,"current_bw":total_bw,"status":"critical"})
                     if crit_counter  == 4:
                        result.append({key:diff_drops_data,"current_bw":total_bw,"status":"critical"})
                     if warn_counter == 4:
                        result.append({key:diff_drops_data,"status":"warning"})
    if not result:
       return "OK",diff_drops_data,total_bw
    else:
       return result

if __name__ == '__main__':

   crit_threshold = options.crit_threshold
   warn_threshold = options.warn_threshold
   crit = 0
   if not options.crit_threshold:
      print "CRITICAL: Missing critical threshold value."
      sys.exit(2)
   if not options.warn_threshold:
      print "CRITICAL: Missing warning threshold value."
      sys.exit(2)

   store_vcg_hanoff_queue_qlength()
   result = get_status_of_drops(warn_threshold,crit_threshold)
   result_type = isinstance(result, tuple)
   if result_type != True:
      for item in result:
         if item["status"] == "critical":
            crit = 1

   if result[0] == "OK":
      print "OK: Handoff drops with 5 samples are good and Current drop values %s and Current BW is %s Kbps" %(result[1],result[2])
      sys.exit(0)
   elif crit == 1:
      print "Critical: List of drops which are above %s packets: %s. Current_bw value is in kbps" %(crit_threshold, result)
      sys.exit(2)
   else:
      print "Warning: List of drops which are above %s packets: %s. Current_bw value is in kbps" %(warn_threshold,result)
      sys.exit(1)

vc_queue_vcmp_data_0 和 vc_queue_vcmp_data_1 - 这是在 VCMP 隧道上接收的 VCMP 数据数据包的第一处理阶段。该队列处理数据包重新排序和缺少的数据包。将从此处开始处理在 VCMP 隧道上传入的数据包。

在该队列中丢弃数据包表示,网关无法足够快地从 Edge 接收流量。这可能间接地表示在网关上丢失数据包,这需要对数据包进行大量重新排序。

vc_queue_natt_0、vc_queue_natt_1、vc_queue_esp_0 和 vc_queue_esp_1 - 这是指解密 NATT/ESP 加密的流量。在加密的隧道上传入的流量发送到此处以设置解密所需的状态,然后将其传送到解密处理队列。

在该队列中丢弃数据包表示,网关无法足够快地解密 Non VMware SD-WAN Site 流量。

ipv4_bh - 这是从 Internet 接收的返回数据包(对于 NAT 流量)或从 PE 路由器接收的返回数据包(对于 VLAN/VRF 流量)的 IPv4 数据包处理,例如,路由、QoS、流量和对等项关联。

在未启用 DPDK 的网关以外的所有网关上,首先在该队列中发现容量问题(即,丢弃了数据包)。在该队列中丢弃数据包表示,网关无法足够快地接收数据包。