面试题:腾讯2012面试题

问题描述: 例如手机朋友网有n个服务器,为了方便用户的访问会在服务器上缓存数据,因此用户每次访问的时候最好能保持同一台服务器。已有的做法是根据ServerIPIndex[QQNUM%n]得到请求的服务器,这种方法很方便将用户分到不同的服务器上去。但是如果一台服务器死掉了,那么n就变为了n-1,那么ServerIPIndex[QQNUM%n]与ServerIPIndex[QQNUM%(n-1)]基本上都不一样了,所以大多数用户的请求都会转到其他服务器,这样会发生大量访问错误。

问: 如何改进或者换一种方法,使得:(1)一台服务器死掉后,不会造成大面积的访问错误,(2)原有的访问基本还是停留在同一台服务器上;(3)尽量考虑负载均衡。

       思路是在服务器与用户之间多加一层映射关系,不再将用户号码直接映射到服务器上,而是将用户号码映射到与服务器一对一的一组索引表上面。

1、索引表与服务器一对一绑定,正常工作时,用户名索引到的是对应服务器的IP(与原有方式相同)。

2、当某台服务器异常时,分配到本服务器的号码,按照顺序索引平均分配到其它服务器上。

 

目前只处理了单台服务器故障,很容易可以扩展到多台服务器故障的情况。

#include <iostream>
#include <time.h>

#define MAX_SERVER	200

int server_ip[MAX_SERVER]   = {0};
typedef struct 
{
    int state;	// 1-work
    int server;

    int index;	
}SI_MAP;

SI_MAP si_map[MAX_SERVER] = {0};

void init()
{
    // 初始化服务IP表
    for(int i= 0;i< MAX_SERVER;i++)
    {
	server_ip[i]	    = i+1;

	si_map[i].state	    = 1;
	si_map[i].server    = i;
	si_map[i].index	    = 0;
    }
}

int GetServer(int index)
{
    if( si_map[index].state == 0 )
    {
	si_map[index].index = (si_map[index].index+1)%MAX_SERVER;
	if( si_map[index].index == index ) 
	    si_map[index].index = (si_map[index].index+1)%MAX_SERVER;

	return si_map[index].index;
    }

    return si_map[index].server;
}

int change(char c,int old)
{
    // 恢复原有的坏服务器
    si_map[old].state = 1; 
    // 选定个坏的服务器
    int bad = rand()%MAX_SERVER;
    si_map[bad].state = 0; 

    printf("\nthe server %d is bad~!\n", bad);

    return bad;
}

void work()
{
    int n   = 0;
    int index	= 0;
    int ip	= 0;
    char c	= 0;
    int bad	= 0;
    while(c != 'e' && c != 'E')
    {
	srand(time(NULL));
	for(int i= 0;i< MAX_SERVER;i++)
	{
	    n	= rand()%MAX_SERVER;
	    ip	= GetServer(n);

	    printf( "map:<%d,%d>", n, ip );
	    if( i%4 == 0 )
		printf("\n");
	    else
		printf("\t");
	}
	c=getchar();
	// 随机改变坏的服务器
	if( c == 's' || c == 'S' )
	{
	    bad = change(c,bad);
	    for( int j= 0;j<100;j++ )
	    {
		ip  = GetServer(bad);
		printf( "map:<%d,%d>", bad, ip );
		if( j%4 == 0 )
		    printf("\n");
		else
		    printf("\t");
	    }
	}
    }
}

void main()
{
    init();
    work();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值