C語言伺服器叢集排程演算法
阿新 • • 發佈:2018-12-20
依賴項
直接複製然後儲存為main.c.然後三個檔案放到一個目錄.
cd 目錄
#編譯
make
#執行
./cluster
直接上程式碼
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include "instr_time.h"
#ifndef __cplusplus
#ifndef bool
typedef char bool;
#endif
#ifndef true
#define true ((bool) 1)
#endif
#ifndef false
#define false ((bool) 0)
#endif
#endif
//伺服器數量
#define SERVER_COUNT (5)
#define RANGE_RANDOM(x,y) (x+rand()%(y-x+1))
#define SE_PTR_ISNULL(ptr) (NULL == ptr )
#define SE_check_nullptr(ptr) do{\
if (SE_PTR_ISNULL(ptr)){\
fprintf(stdout, "Memory overflow\n");\
goto SE_ERROR_CLEAR; \
}\
} while (0)
//各伺服器的配置資訊
struct SE_SERVER_ITEM {
int32_t weight; //初始化設定的許可權係數.這個值不會改變
int32_t current_weight; //當前權重係數.
int32_t serid; //伺服器編號
int32_t id; //當前連線自定義編號
//其它連線資訊略
};
//伺服器叢集資訊
struct SE_SERVER_CLUSTER {
uint32_t count;
struct SE_SERVER_ITEM **items;
};
//伺服器叢集配置資訊
struct SE_SERVER_CONF {
//當前伺服器編號
int32_t id;
//其它連線資訊略
//當前伺服器允許的最大連線數
uint32_t max_conn;
};
void cluster_free(struct SE_SERVER_CLUSTER **ptr) {
struct SE_SERVER_CLUSTER *cluster = *ptr;
uint32_t i = 0;
if (!SE_PTR_ISNULL(cluster)) {
for (i = 0; i < cluster->count; ++i) {
if (!SE_PTR_ISNULL(cluster->items[i]))
free(cluster->items[i]);
}
if (!SE_PTR_ISNULL(cluster->items))
free(cluster->items);
free(cluster);
}
*ptr = NULL;
}
struct SE_SERVER_ITEM * get_next_server_index(struct SE_SERVER_CLUSTER *cluster) {
uint32_t i = 0, total = 0, index = 0;
for (i = 0; i < cluster->count; ++i) {
cluster->items[i]->current_weight += cluster->items[i]->weight;
total += cluster->items[i]->weight;
if (-1 == index || cluster->items[index]->current_weight < cluster->items[i]->current_weight)
index = i;
}
cluster->items[index]->current_weight -= total;
return cluster->items[index];
}
bool init_cluster(struct SE_SERVER_CONF *serconf, uint32_t sconf_count, struct SE_SERVER_CLUSTER **ptr) {
struct SE_SERVER_CLUSTER *cluster = NULL;
uint32_t i = 0, index = 0;
SE_check_nullptr((cluster = (struct SE_SERVER_CLUSTER *) calloc(1, sizeof (struct SE_SERVER_CLUSTER))));
for (i = 0; i < sconf_count; ++i)
cluster->count += serconf[i].max_conn;
fprintf(stdout, "all connection count:%u\n", cluster->count);
SE_check_nullptr((cluster->items = (struct SE_SERVER_ITEM **) calloc(cluster->count, sizeof (struct SE_SERVER_ITEM *))));
for (i = 0; i < cluster->count; ++i) {
SE_check_nullptr((cluster->items[index] = (struct SE_SERVER_ITEM *) malloc(sizeof (struct SE_SERVER_ITEM))));
//訪問權重可以在配置檔案中設定 ,這裡預設所有伺服器的訪問機會均等
cluster->items[index]->current_weight = 1;
cluster->items[index]->weight = 1;
//按物理伺服器的順序依次使用各個伺服器
cluster->items[index]->serid = serconf[ i % sconf_count ].id;
cluster->items[index]->id = index;
++index;
}
(*ptr) = cluster;
return true;
SE_ERROR_CLEAR:
cluster_free(&cluster);
return false;
}
int main(int argc, char** argv) {
//3臺伺服器
struct SE_SERVER_CONF serconf[SERVER_COUNT];
struct SE_SERVER_CLUSTER *cluster = NULL;
int32_t i = 0;
instr_time before, after;
double elapsed_msec = 0;
srand(time(NULL));
//初始化服務配置資訊
for (i = 0; i < SERVER_COUNT; ++i) {
serconf[i].id = i;
serconf[i].max_conn = RANGE_RANDOM(16, 64);
}
//根據服務配置資訊,初始化伺服器叢集
if (!init_cluster(serconf, SERVER_COUNT, &cluster))
goto SE_ERROR_CLEAR;
INSTR_TIME_SET_CURRENT(before);
//訪問伺服器10000次
for (i = 0; i < 10000; ++i) {
struct SE_SERVER_ITEM *item = get_next_server_index(cluster);
fprintf(stdout, "%d request\tuse server:%d\titem:%d\n", i, item->serid, item->id);
}
INSTR_TIME_SET_CURRENT(after);
INSTR_TIME_SUBTRACT(after, before);
elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
fprintf(stdout, "Time: %.3f ms\n", elapsed_msec);
cluster_free(&cluster);
return (EXIT_SUCCESS);
SE_ERROR_CLEAR:
cluster_free(&cluster);
return (EXIT_FAILURE);
}
執行截圖