Ich versuche, meine Anwendung send Rate zu 900kbps zu begrenzen, aber das Problem ist, dass das Protokoll, das ich verwende, Nachrichtenorientiert ist und die Nachrichten sehr unterschiedliche Größen haben. Ich kann Nachrichten von 40 Bytes bis zu 125000 Bytes haben und alle Nachrichten werden als atomare Einheiten gesendet.Token Bucket oder Leaking Bucket für Nachrichten
Ich habe versucht, einen Token-Bucket-Puffer zu implementieren, aber wenn ich eine niedrige Bucket-Größe einstelle, werden die großen Pakete niemals gesendet und ein größerer Bucket führt zu einem großen Burst ohne jegliche Ratenbegrenzung.
Das ist meine kleine Implementierung in C:
typedef struct token_buffer {
size_t capacity;
size_t tokens;
double rate;
uint64_t timestamp;
} token_buffer;
static uint64_t time_now()
{
struct timeval ts;
gettimeofday(&ts, NULL);
return (uint64_t)(ts.tv_sec * 1000 + ts.tv_usec/1000);
}
static int token_buffer_init(token_buffer *tbf, size_t max_burst, double rate)
{
tbf->capacity = max_burst;
tbf->tokens = max_burst;
tbf->rate = rate;
tbf->timestamp = time_now();
}
static size_t token_buffer_consume(token_buffer *tbf, size_t bytes)
{
// Update the tokens
uint64_t now = time_now();
size_t delta = (size_t)(tbf->rate * (now - tbf->timestamp));
tbf->tokens = (tbf->capacity < tbf->tokens+delta)?tbf->capacity:tbf->tokens+delta;
tbf->timestamp = now;
fprintf(stdout, "TOKENS %d bytes: %d\n", tbf->tokens, bytes);
if(bytes <= tbf->tokens) {
tbf->tokens -= bytes;
} else {
return -1;
}
return 0;
}
dann irgendwo in main():
while(1) {
len = read_msg(&msg, file);
// Loop until we have enough tokens.
// if len is larger than the bucket capacity the loop never ends.
// if the capacity is too large then no rate limit occurs.
while(token_buffer_consume(&tbf,msg, len) != 0) {}
send_to_net(&msg, len);
}