日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

流量管理的实现

發布時間:2023/12/25 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 流量管理的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

VPP police

源碼:https://docs.fd.io/vpp/20.01/d1/d66/police_8h_source.html

#ifndef __POLICE_H__

#define __POLICE_H__

typedef enum

{

POLICE_CONFORM = 0,

POLICE_EXCEED = 1,

POLICE_VIOLATE = 2,

} policer_result_e;

#define POLICER_TICKS_PER_PERIOD_SHIFT 17

#define POLICER_TICKS_PER_PERIOD (1 << POLICER_TICKS_PER_PERIOD_SHIFT)

typedef struct

{

u32 lock; // for exclusive access to the struct

u32 single_rate; // 1 = single rate policer, 0 = two rate policer

u32 color_aware; // for hierarchical policing

u32 scale; // power-of-2 shift amount for lower rates

u8 action[3];

u8 mark_dscp[3];

u8 pad[2];

// Fields are marked as 2R if they are only used for a 2-rate policer,

// and MOD if they are modified as part of the update operation.

// 1 token = 1 byte.

u32 cir_tokens_per_period; // # of tokens for each period

u32 pir_tokens_per_period; // 2R

u32 current_limit;

u32 current_bucket; // MOD

u32 extended_limit;

u32 extended_bucket; // MOD

u64 last_update_time; // MOD

u64 pad64;

} policer_read_response_type_st;

static inline policer_result_e

vnet_police_packet (policer_read_response_type_st * policer,

u32 packet_length,

policer_result_e packet_color, u64 time)

{

u64 n_periods;

u64 current_tokens, extended_tokens;

policer_result_e result;

// Scale packet length to support a wide range of speeds

packet_length = packet_length << policer->scale;

// Compute the number of policer periods that have passed since the last

// operation.

n_periods = time - policer->last_update_time;

policer->last_update_time = time;

if (policer->single_rate){

// Compute number of tokens for this time period

current_tokens = policer->current_bucket + n_periods * policer->cir_tokens_per_period;

if (current_tokens > policer->current_limit)

{

current_tokens = policer->current_limit;

}

extended_tokens = policer->extended_bucket + n_periods * policer->cir_tokens_per_period;

if (extended_tokens > policer->extended_limit)

{

extended_tokens = policer->extended_limit;

}

// Determine color

if ((!policer->color_aware || (packet_color == POLICE_CONFORM))

&& (current_tokens >= packet_length))

{

policer->current_bucket = current_tokens - packet_length;

policer->extended_bucket = extended_tokens - packet_length;

result = POLICE_CONFORM;

}

else if ((!policer->color_aware || (packet_color != POLICE_VIOLATE))

&& (extended_tokens >= packet_length))

{

policer->current_bucket = current_tokens;

policer->extended_bucket = extended_tokens - packet_length;

result = POLICE_EXCEED;

}

else

{

policer->current_bucket = current_tokens;

policer->extended_bucket = extended_tokens;

result = POLICE_VIOLATE;

}

}

else

{

// Two-rate policer

// Compute number of tokens for this time period

current_tokens = policer->current_bucket + n_periods * policer->cir_tokens_per_period;

extended_tokens =policer->extended_bucket + n_periods * policer->pir_tokens_per_period;

if (current_tokens > policer->current_limit)

{

current_tokens = policer->current_limit;

}

if (extended_tokens > policer->extended_limit)

{

extended_tokens = policer->extended_limit;

}

// Determine color

if ((policer->color_aware && (packet_color == POLICE_VIOLATE))

|| (extended_tokens < packet_length))

{

policer->current_bucket = current_tokens;

policer->extended_bucket = extended_tokens;

result = POLICE_VIOLATE;

}

else if ((policer->color_aware && (packet_color == POLICE_EXCEED))

|| (current_tokens < packet_length))

{

policer->current_bucket = current_tokens;

policer->extended_bucket = extended_tokens - packet_length;

result = POLICE_EXCEED;

}

else

{

policer->current_bucket = current_tokens - packet_length;

policer->extended_bucket = extended_tokens - packet_length;

result = POLICE_CONFORM;

}

}

return result;

}

#endif // __POLICE_H__

根據限速規則的設置,主要操作就是計算保證速率和峰值速率當前獲得的令牌數,剩下就是根據配置的策略,來判斷當前報文的決策。

// Compute the number of policer periods that have passed since the lastoperation.

n_periods = time - policer->last_update_time;

policer->last_update_time = time;

// Compute number of tokens for this time period

current_tokens = policer->current_bucket + n_periods * policer->cir_tokens_per_period;

if (current_tokens > policer->current_limit){

current_tokens = policer->current_limit;

}

extended_tokens = policer->extended_bucket + n_periods * policer->cir_tokens_per_period;

if (extended_tokens > policer->extended_limit){

extended_tokens = policer->extended_limit;

}

RateLimiter

源碼:https://github.com/mfycheng/ratelimiter

std::chrono::microseconds RateLimiter::claim_next(double permits) {

using namespace std::chrono;

std::lock_guard<std::mutex> lock(mut_);

unsigned long long now

= duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();

// Make sure we're synced

sync(now);

// Since we synced before hand, this will always be >= 0.

unsigned long long wait = next_free_ - now;

// Determine how many stored and freh permits to consume

double stored = std::min(permits, stored_permits_);

double fresh = permits - stored;

// In the general RateLimiter, stored permits have no wait time,

// and thus we only have to wait for however many fresh permits we consume

long next_free = (long)(fresh * interval_);

next_free_ += next_free;

stored_permits_ -= stored;

return microseconds(wait);

}

相比上面的代碼,核心思想也是利用令牌桶,但使用起來更簡單。

總結

以上是生活随笔為你收集整理的流量管理的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。