Webbench Analysis __web

Source: Internet
Author: User
Tags benchmark server port

Webbench: A Linux Web Performance stress testing tool, which can simulate up to 30,000 concurrent connections to test server pressure, the principle of which is to fork multiple child processes, each child process loop to do Web Access testing, the child process will access the results of the pipeline to tell the parent process, The parent process does the final result statistics.

The main principle of the following diagram:

Its code implementation mainly uses 4 functions: Getopt_long () system command line parsing function, Build_request () function, Bench () function, Benchcore () function.

The process is as follows:
WEBBENCH.C:
Global variable option parameter: all have default values
1. Command line parameter parsing, parameter construction (Getopt_long () function Implementation) (if the user does not pass
The parameter is set to its default value);

2. Based on some of the parameters obtained by 1, make an HTTP request construct and invoke the Build_request () function:
(1) construct the first line:
Request method: method–>request[]

URL: To determine the legality of the URL, legal:
No proxy server:
–>host[its network address], port number –>proxyport;
URL resource Path –>request[]
There are proxy servers:
The URL is filled in directly into the –>request[];

HTTP protocol version: http0.9 http1.0 http1.1

(2) Request header: name:value–>request[]
(3) Fill in the blank line –>request[]
Construction complete

3. Perform the stress test and call the bench () function:
(1) The legality test of a connection;
(2) Establishing pipeline communication;
(3) Derivation of the child process according to the number of clients;
(4) Each child process calls the Benchcore () function for a connection request:

Benchcore function:
Create a custom signal capture function to establish a benchtime time alarm:
(1) Call socket (), get connection socket;
(2) Write the request to the network;
(3) http0.9 Protocol processing (close connection write half);
(4) Read the server response message;
(5) Closing the connection;
The Faild (number of failures), bytes (number of server response bytes), speed (number of successful connections) are counted in the process above.

(5) The Benchcore function call completes, each process writes to the pipeline Faild, bytes, speed;
(6) The parent process opens the pipeline to read the information written by each process, perform statistical calculations, and output the stress test results.

SOCKET.C:
1. Set up SOCKET: Call socket ();
2. Establish connection: Call Connect ();
Return socket: sock.

The source code is as follows:
Webbench.c

#include "socket.c" #include <unistd.h> #include <sys/param.h> #include <rpc/types.h> #include & lt;getopt.h> #include <strings.h> #include <time.h> #include <signal.h>//statistical stress test final results indicated Volat  
ile int timerexpired = 0;  
int speed = 0;  
int failed = 0;

int bytes = 0; HTTP request method #define METHOD_GET 0 #define METHOD_HEAD 1 #define method_options 2 #define METHOD_TRACE 3 #define PRO    Gram_version "1.5"//default setting: Generally require the user to pass in the command line parameter set int method = Method_get;            The default request method is get way int clients = 1;              The default is to simulate only one client int force = 0;       Default need to wait for server response int force_reload = 0;         Re-request int proxyport = 80 upon failure;     The default access server port is *proxyhost char = NULL;         Default agentless server int benchtime = 30;   The default simulation request time is 30s//GLOBALS version number int http10 = 1;             0:-http/0.9, 1:-http/1.0, 2:-http/1.1 int mypipe[2]; Pipe for parent-child process communication char Host[maxhostnamelen]; Storage Server network address #define REQUEST_SIZE 2048 char Request[rEquest_size];  
Store HTTP request message array//function declaration static void Benchcore (const char* HOST,CONST int port, const char *request);  
static int Bench (void); 

static void Build_request (const char *url); Use with each parameter verbose meaning static void usage (void) {fprintf (stderr, webbench [option] ... Url\n "//Usage"-f|--force Don t wait for reply from server.\n ""-r|--reload S End Reload request-pragma:no-cache.\n ""-t|--time <sec> Run benchmark for <sec> seconds.         Default 30.\n ""-p|--proxy <server:port> use proxy server for request.\n ""-c|--clients <n> Run <n> HTTP clients at once. Default one.\n "" -9|--http09 use http/0.9 style requests.\n "" -1|--HTTP10 use HT tp/1.0 protocol.\n "" " -2|--http11 Use http/1.1 protocol.\n" "--get use Get Request Method.\n ""--head Use head requEST method.\n ""--options Use options request method.\n ""--trace use TRAC E request Method.\n ""-?|  
-h|--help this information.\n ""-v|--version Display program version.\n ");  

}; Structure array: Each element is formatted as: {long option, with parameters after option, int* pointer (null), corresponding short option or static const struct option long_options[]=//NOT NULL, The fourth parameter value is given to the third parameter} {{"force", no_argument,&force,1}, {"Reload", no_argument,&force_reload,1}, {"Time ", Required_argument,null, ' t '}, {" Help ", No_argument,null, '? '}, {" http09 ", No_argument,null, ' 9 '}, {" Http10 " , No_argument,null, ' 1 '}, {"Http11", No_argument,null, ' 2 '}, {"Get", no_argument,&method,method_get}, { "Head", No_argument,&method,method_head}, {"Options", no_argument,&method,method_options}, {"Trace", no_a Rgument,&method,method_trace}, {"Version", No_argument,null, ' V '}, {"Proxy", Required_argument,null,' P '}, {"Clients", Required_argument,null, ' C '}, {null,0,null,0}};  
    int main (int argc, char *argv[]) {int opt = 0;  
    int options_index = 0;  

    char *tmp = NULL;  
        First, verify the command line parameter//1. Direct output usage Help information if (argc = = 1) {usage () without option;  
    return 2; //2. With the option to parse the command-line arguments and related settings based on the incoming options//Getopt_long The library functions that are parsed for the command line, depending on argc to find (argv, "912vfrt:p:c:?h") the two string matching options,// Fruit is a short option, then return this option directly to opt,//if it is a long option, then go to option long_options[] structure array to find a match for its long option, return its corresponding short option to opt,///Jochi The third argument is not NULL, and the fourth parameter value to the third argument, and returns 0 to opt//This function has its own global variables://optarg: The parameter after the option:-T 100, pointing to//optind: The argv index value that is currently accessed//opterr: its value is not 0 o'clock, it represents an invalid option, missing parameter, output error message//optopt: When an invalid option is found, the function returns "? /: "To set its value to an invalid option character while (opt = Getopt_long (argc,argv," 912vfrt:p:c:?h ", long_options/* structure array pointer */,&options_index))!  
            = EOF) {switch (OPT)//to judge the parameters passed in by the user based on the return value {case 0:break;        Case ' f ': force = 1;break; Force=1 representative does not wait for serviceResponse case ' r ': force_reload = 1;break;  
            Send Reload request case ' 9 ': Http10 = 0;break;  
            Case ' 1 ': Http10 = 1;break;  
            Case ' 2 ': Http10 = 2;break;  
                      Case ' V ': printf (program_version "\ n");  

            Exit (0);   Case ' t ': Benchtime = atoi (Optarg);  
            Set the elapsed time break that the user passed in;     Case ' C ': Clients = atoi (OPTARG);  

            Sets the number of clients created to break; Case ' P '://using proxy server, set its proxy network number and port number: format:-p server:port tmp = STRRCHR (Optarg, ': '   );       Find ":" The position of the last occurrence in the optarg proxyhost = Optarg;  
                      Set network number if (TMP = NULL)//No: number, no port number {break;  
          The IF (tmp = = optarg)//port number is in the first position, error: Missing host name {                fprintf (stderr, "Error in option--proxy%s:missing hostname.\n", Optarg);  
                      return 2;  
                          } if (tmp = = Optarg + strlen (optarg)-1)//: number is at the bottom, missing port number {  
                          fprintf (stderr, "Error in option--proxy%s Port number is missing.\n", optarg);  
                      return 2;  } *tmp = ' I ';  Place: Number to "proxyport" = Atoi (tmp+1);  

            Set a new port number break; 
        Case ': ': Case ' h ': Case '? ': Usage (), return 2;break; 

    } when the//getopt_long function resolves the option, it reads that the URL is not read, at which point Argv[optind] points to the URL//optind is Getopt_long set to the next element of the value that is not read in the command line argument  
        if (Optind = = argc)//If the equality is not entered URL {fprintf (stderr, "webbench:missing url!\n");  
        Usage ();  
    return 2; ///If the parameter is set to 0 after the client option, change if (clients = 0) ClieNTS = 1;  

    if (Benchtime = = 0) Benchtime = 60; Output Webbench version-related information fprintf (stderr, "Webbench-simple Web Benchmark" program_version "\ n" "Copyright (c) Radim  

    Kolar 1997-2004, GPL Open Source software.\n ");   Constructing the HTTP request to the request array build_request (Argv[optind]);    Incoming URL//http request after construction success//The following output prompt information printf ("\nbenchmarking:"); Pressure start switch (method)///using the request methods {case METHOD_GET:default:printf (' get '); BR  
        Eak  
        Case method_options:printf ("Options");  
        Case method_head:printf ("Head");  
    Case method_trace:printf ("TRACE");   printf ("%s", Argv[optind]);  
        Access URL switch (HTTP10)//http protocol version number {case 0:printf ("(using http/0.9)");  
    Case 2:printf ("(using http/1.1)");  

    printf ("\ n"); Number of analog connection clients if (clients = 1) printf ("1 ClieNT ");  

    else printf ("%d clients", clients); 

    Connection test time printf (", Running%d sec", benchtime);

    if (force) printf (", Early socket Close"); 

    Output proxy information if (proxyhost!= NULL) printf (", via Proxy server%s:%d", proxyhost,proxyport);  
    if (force_reload) printf (", forcing Reload");  

    printf (". \ n");  
Start the stress test, return the bench function to perform the result returns bench ();  
    "//II, constructing HTTP request to request array void Build_request (const char *url) {char tmp[10];  

    int i;  
    Initialization of bzero (Host,maxhostnamelen);  

    Bzero (request,request_size);  
    Determine which HTTP protocol should be used if (force_reload && proxyhost!= NULL && http10 < 1) http10 = 1;  
    if (method = = Method_head && http10 < 1) http10 = 1;  
    if (method = = Method_options && http10 < 2) HTTP10 = 2;  

    if (method = = Method_trace && http10 < 2) HTTP10 = 2; 1. Fill in the HTTP request first line//fill requestMethod switch (methods) {Default:case method_get:strcpy (request, "get");  
        Case method_head:strcpy (Request, "Head");  
        Case method_options:strcpy (Request, "options");  
    Case method_trace:strcpy (Request, "TRACE");  

    } strcat (Request, ""); URL legality judgement//If no "://" is not valid if (NULL = = strstr (URL, "://")) {fprintf (stderr, "\n%s:is not a valid U  
        rl.\n ", url);  
    Exit (2);  
        //If the URL is too long illegal if (strlen (URL) >1500) {fprintf (stderr, "url is too long.\n");  
    Exit (2); 
        } if (ProxyHost = NULL)//If no proxy server {if (0!= strncasecmp ("http://", url,7))//Ignore case comparison {//only supports HTTP address fprintf (stderr, "\nonly HTTP protocol is directly supported, set--proxy for OT  
            Hers.\n ");  
        Exit (2); }///find where the host name begins: http://baidu.com:80/i = strstr (URL, "://")-url+3; I==7//Must be in/over if (STRCHR (url+i, '/') ==null)//Find "/" in string, no illegal URL {fprintf (stderr, "\ninvali")  
        D URL syntax-hostname don ' t ends with '/'. \ n ');  
    Exit (2); } if (proxyhost = null)//If no proxy server {//Get port number from host name if (Index (Url+i, ': ')!= NULL && IND Ex (Url+i, ': ') < index (url+i, '/'))//If with port number, the index function is similar to STRCHR {//Set network number strncpy (host,u    RL+I,STRCHR (Url+i, ': ')-url-i);  
            If the baidu.com is copied into the host array, the network address//initialization bzero (tmp,10); strncpy (Tmp,index (url+i, ': ') +1,strchr (url+i, '/')-index (Url+i, ': ')-1);  
            Copy port number into TMP array/set port ProxyPort = Atoi (TMP);  

        if (proxyport==0) proxyport=80;  else//No port number, direct copy domain name to host array {strncpy (host,url+i,strcspn (Url+i, "/")); Strcspn find Url+i to "/" the number of characters}//Enter the resource path into the request line strcat Request+strlen (request), URL+I+STRCSPN (Url+i, "/"));  else//If there is a proxy server {strcat (request,url);  
    Directly fill in the URL to the request line}//fill in the HTTP version number to the request line if (HTTP10 = 1) strcat (Request, "http/1.0");  
    else if (http10==2) strcat (Request, "http/1.1");  

    strcat (Request, "\ r \ n");  

    2. Fill in the request header: Name:value if (Http10 > 0) strcat (Request, "User-agent:webbench" program_version "\ r \ n");  
        if (ProxyHost = = NULL && http10 > 0) {strcat (Request, "Host:");  
        strcat (Request,host);  
    strcat (Request, "\ r \ n");  
    } if (Force_reload && proxyhost!= NULL) {strcat (Request, "pragma:no-cache\r\n");  

    if (Http10 > 1) strcat (Request, "connection:close\r\n");  

    3. Fill in the empty line if (http10>0) strcat (Request, "\ r \ n");  
    Construct completion} The static int bench (void)//parent process does work {int i,j,k;  
    pid_t pid = 0;  

    FILE *f; To establish a network connection: test first, whether the server can connect successfully  
    i = Socket (ProxyHost = NULL host:proxyhost, proxyport); if (I < 0) {fprintf (stderr, "\nconnect to server failed.")  
        Aborting benchmark.\n ");  
    return 1;   Close (i);  
        Test successful, one connection complete shutdown//Establish pipe communication if (pipe (mypipe)) {perror ("pipe failed.");  
    return 3;  
        ///derived child process stress test: How many clients are passed in to establish the number of child processes to connect for (i = 0;i < clients;i++) {pid = fork ();
            if (PID <= (pid_t) 0) {sleep (1);     Break Causes the child to jump out of the loop immediately, or continue fork the child process}//Subprocess creation failure if (PID < (pid_t) 0) {fprintf (Stder  
        R, "problems forking worker No.%d\n", i);  
        Perror ("Fork failed.");  
    return 3; The//subprocess executes if (PID = = (pid_t) 0) {//child process makes the actual request if (ProxyHost = NULL) benc  
        Hcore (host,proxyport,request);  

        else Benchcore (proxyhost,proxyport,request); 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.