负载均衡服务器

来源:互联网 发布:主播都用什么唱歌软件 编辑:程序博客网 时间:2024/05/16 05:55

每次有客户端连接时选择当前连接数(CR)最小的http服务器进行连接,然后转发请求和应答,用线程实现:

#include"unp.h"#include <semaphore.h>#include<stdlib.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include    <pthread.h>#include    <time.h>#include<syslog.h>#define gettid() syscall(__NR_gettid)#define         SESSIONNUM   10000int myreadline(int fd, char *buf, int n);static void *http(void* connfd);void init();struct httpServerInfo{    char ip[20];    char port[10];    char OS[10];volatile    int  CR;    double ACR;    double cpuUse;    int    memUse;} httpServer[4];struct SessionAdhesions{    int ip;    int choice;} sessionList[SESSIONNUM];int sessionIndex;char  balanceServerIp[20];char  balanceServerPort[10];volatile int    CR;double ACR;double cpuUse;int    memUse;static pthread_mutex_t mutex;struct eachThreadInfo{int choice;int fd;};int main(int argc, char **argv){    intlistenfd, connfd;    pthread_t       tid;    socklen_tclilen;    struct sockaddr_in  cliaddr, servaddr;    listenfd = Socket(AF_INET, SOCK_STREAM, 0);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family     = AF_INET;//-------------------初始化结构体----------------------------    init();//----------------------------------------------------------    inet_pton(AF_INET,balanceServerIp,&servaddr.sin_addr);    servaddr.sin_port=htons(atoi(balanceServerPort));    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));    Listen(listenfd, LISTENQ);    signal(SIGPIPE,SIG_IGN);    for ( ; ; )    {        clilen = sizeof(cliaddr);        if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0)        {            if (errno == EINTR) continue;            else err_sys("accept error");        }       // printf("connected from %s:%u...http\n",inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port);struct eachThreadInfo *arg=malloc(sizeof(struct eachThreadInfo));arg->fd=connfd;//-------------------------------------SessionAdhesions---------------------------------------------------------       /* int j=0;int clientIp=cliaddr.sin_addr.s_addr;        for(j=0; j<sessionIndex; j++)        {            if(clientIp!=sessionList[j].ip)            {                arg->choice=sessionList[j].choice;                break;            }        }        if(j==sessionIndex)        {            sessionList[sessionIndex].ip=clientIp;*///---------------------------------------balance  connect--------------------------------------------------------    int i;            int eachCR=99999;            for(i=0; i<4; i++)            {                if(httpServer[i].CR<eachCR)                {                    arg->choice=i;                    eachCR=httpServer[i].CR;                }            }    sessionList[sessionIndex].choice=arg->choice;            sessionIndex=(sessionIndex+1)%SESSIONNUM;    printf("choose httpServer %d!\n\n",arg->choice);            pthread_create(&tid,NULL,http,(void*)arg);        }}static void *http(void* arg){    pthread_detach(pthread_self());    struct eachThreadInfo *each=arg;    pthread_mutex_lock(&mutex);    httpServer[each->choice].CR++;    CR++;                   pthread_mutex_unlock(&mutex);    int httpd;    struct sockaddr_inhttpservaddr;    httpd = Socket(AF_INET, SOCK_STREAM, 0);    bzero(&httpservaddr, sizeof(httpservaddr));    httpservaddr.sin_family = AF_INET;    httpservaddr.sin_port = htons(atoi(httpServer[each->choice].port));    Inet_pton(AF_INET, httpServer[each->choice].ip, &httpservaddr.sin_addr);    connect(httpd, (SA *) &httpservaddr, sizeof(httpservaddr));    //perror("connect");    char receiveline[MAXLINE];    ssize_t n;    char temp[50];    while((n=myreadline(each->fd,receiveline,MAXLINE))>2)    {        sscanf(receiveline,"%s",temp);        writen(httpd,receiveline,n);    }    writen(httpd,"\r\n",2);    char judge[100];    unsigned long intfileLength=0;    while((n=myreadline(httpd,receiveline,MAXLINE))>2)    {        writen(each->fd,receiveline,n);        sscanf(receiveline,"%s",judge);        if(!strcmp(judge,"Content-Length:")){            sscanf(receiveline,"%*s%lu",&fileLength);}    }    writen(each->fd,"\r\n",2);       while(1)    {        if(MAXLINE<fileLength)        {            fileLength-=read(httpd, receiveline, MAXLINE);;            writen(each->fd,receiveline,MAXLINE);        }        else        {            read(httpd, receiveline, fileLength);            writen(each->fd,receiveline,fileLength);            break;        }    }    pthread_mutex_lock(&mutex);    httpServer[each->choice].CR--;    CR--;                   pthread_mutex_unlock(&mutex);    close(each->fd);    close(httpd);    free(arg);    return NULL;}int myreadline(int fd, char *buf, int n){    char ch;    char *base=buf;    while(1)    {        if(read(fd, &ch, 1)!=1)        {            if(errno==EINTR) continue;            return -1;        }        if((*(buf++)=ch)=='\n') break;    }    *buf='\0';    return buf-base;}void init(){    int conf=open("balance.conf",O_RDONLY);    char temp[40];    myreadline(conf,temp,40);    sscanf(temp,"%*s%s",balanceServerIp);    myreadline(conf,temp,40);    sscanf(temp,"%*s%s",balanceServerPort);    int i=0,j=0;    int num=4;    num=num*2;    for(; i<num; i++)    {        myreadline(conf,temp,30);        if(!(i%2)) sscanf(temp,"%*s%s",httpServer[j].ip);        else    sscanf(temp,"%*s%s",httpServer[j++].port);    }    close(conf);}

把webbench改为线程版本,用10W连接测试1300k.jpg请求,时间50秒,结果如下:

0 0
原创粉丝点击