1. 程式人生 > >C語言伺服器叢集排程演算法

C語言伺服器叢集排程演算法

依賴項

直接複製然後儲存為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); }

執行截圖 在這裡插入圖片描述