23 Star 57 Fork 15

hotmocha / sbalance

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
sbalgorithm.c 4.29 KB
一键复制 编辑 原始数据 按行查看 历史
hotmocha 提交于 2015-05-12 23:13 . 基本稳定版本
#include "sbalance.h"
#include <string.h>
/* rand [1,10]
use : j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
not use: j = 1 + (rand() % 10);
*/
unsigned int sb_sdbm_hash(char *str)
{
unsigned int hash = 0;
while(*str) {
hash = (*str++) + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
/* return ms */
int sb_time_difference(struct timeval *a, struct timeval *b)
{
int i = a->tv_sec * 1000 + a->tv_usec / 1000;
int j = b->tv_sec * 1000 + b->tv_usec / 1000;
return i - j;
}
void sb_set_server_failed(struct sb_cycle_env *env, struct sb_conf_server *server)
{
server->fails++;
memcpy(&server->find_unhealth_time, &cache_time, sizeof(struct timeval));
}
void sb_set_server_ok(struct sb_conf_server *server)
{
server->fails = 0;
server->try_connect = 0;
}
int sb_check_server_available(struct sb_cycle_env *env, struct sb_conf_server *server)
{
if (server->fails < server->max_fails) {
return SB_OK;
}
else { /* fails >= max_fails */
/* timeout */
if (sb_time_difference(&cache_time, &server->find_unhealth_time) > server->fail_timeout) {
server->try_connect = 1;
return SB_OK;
}
}
return SB_ERROR;
}
struct sb_conf_server* sb_load_balance_rr(struct sb_cycle_env *env, struct sb_forward_rule *rule)
{
int i;
struct sb_conf_server *server = NULL;
for (i = 0; i < rule->server_num; i++) {
if (rule->current_server_index >= rule->server_num)
rule->current_server_index = 0;
server = &rule->server_addr[rule->current_server_index];
if (sb_check_server_available(env, server) == SB_OK) {
rule->current_server_index++;
return server;
}
rule->current_server_index++;
}
return NULL;
}
struct sb_conf_server* sb_load_balance_random(struct sb_cycle_env *env, struct sb_forward_rule *rule)
{
int index, i;
struct sb_conf_server *server = NULL;
srand((unsigned int)cache_time.tv_sec * 13 + (unsigned int)cache_time.tv_usec * 19);
for (i = 0; i < rule->server_num * 10; i++) {
index = rand() % rule->server_num;
server = &rule->server_addr[index];
if (sb_check_server_available(env, server) == SB_OK)
return server;
}
return NULL;
}
struct sb_conf_server* sb_load_balance_weight(struct sb_cycle_env *env, struct sb_forward_rule *rule)
{
int index, i;
int current_weight = 0;
struct sb_conf_server* server = NULL;
index = 1 + rand() % rule->server_total_weight;
for (i = 0; i < rule->server_num; i++) {
server = &rule->server_addr[i];
if (current_weight <= index && index <= current_weight + server->weight) {
if (sb_check_server_available(env, server) == SB_OK) {
return server;
}
return NULL;
}
else {
current_weight += server->weight;
}
}
return NULL;
}
struct sb_conf_server* sb_load_balance_iphash(struct sb_cycle_env *env, struct sb_forward_rule *rule, char *ip_port)
{
int index;
struct sb_conf_server* server = NULL;
index = sb_sdbm_hash(ip_port) % rule->server_num;
server = &rule->server_addr[index];
if (sb_check_server_available(env, server) == SB_OK) {
return server;
}
return NULL;
}
/*******
#define BALANCE_MODE_RR "rr" // fail: rr -> rr
#define BALANCE_MODE_RANDOM "random" // fail: random -> random
#define BALANCE_MODE_WEIGHT "weight" // fail: random weight - > random
#define BALANCE_MODE_IPHASH "iphash" // fail: iphash -> random
******/
struct sb_conf_server* sb_load_balance_get_server(struct sb_cycle_env *env, struct sb_forward_rule *rule, char *ip_port)
{
struct sb_conf_server *server = NULL;
if (memcmp(rule->balance_mode, BALANCE_MODE_RR, sizeof(BALANCE_MODE_RR) - 1) == 0) {
return sb_load_balance_rr(env, rule);
}
else if (memcmp(rule->balance_mode, BALANCE_MODE_RANDOM, sizeof(BALANCE_MODE_RANDOM) - 1) == 0) {
return sb_load_balance_random(env, rule);
}
else if (memcmp(rule->balance_mode, BALANCE_MODE_IPHASH, sizeof(BALANCE_MODE_IPHASH) - 1) == 0) {
if ((server = sb_load_balance_iphash(env, rule, ip_port)) != NULL)
return server;
else
return sb_load_balance_random(env, rule);
}
else if (memcmp(rule->balance_mode, BALANCE_MODE_WEIGHT, sizeof(BALANCE_MODE_WEIGHT) - 1) == 0) {
if ((server = sb_load_balance_weight(env, rule)) != NULL)
return server;
else
return sb_load_balance_random(env, rule);
}
return NULL;
}
C
1
https://gitee.com/hotmocha/sbalance.git
git@gitee.com:hotmocha/sbalance.git
hotmocha
sbalance
sbalance
master

搜索帮助