一、Nginx

1、什么是nginx?

Nginx(engine x)是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。

2、用于什么场景

Nginx适用于各种规模的网站和应用程序,特别是需要高并发处理和负载均衡的场景。

Nginx也常用于提供安全的HTTPS服务,以及作为邮件代理服务器。

国内常见的使用nginx的有:淘宝,京东,百度等。

3、nginx用在哪些具体的地方

nginx使用在网关的位置,也就是发送数据的位置。

4、nginx的组件

nginx使用 conf 配置。
nginx模块开发 handler,filter,upstream。
nginx源码 多进程网络,http状态机,多进程网络加锁。
nginx基础组件,线程池,内存池,原子,共享内存,string, list, hash, array。

二、nginx的conf文件

1、master和worker的关系

首先当我们下载好nginx后,我们要先启动一下

//nginx所咋的位置,其中包括sbin、html、conf文件。
/usr/local/nginx

//我们在这里使用
./sbin/nginx -c conf/nginx.conf

我们发现创建了两个进程,一个master和一个worker进程。那我们来看看nginx启动所需要的conf文件吧。

#user  nobody;
#创建几个工作线程
worker_processes  1;

#如果我们启动nginx不加任何东西 ./sbin/nginx 那么就会报错:events 。
events {
    worker_connections  1024;        #最大连接数
}

#提供http服务
http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #创建几个对外的端口,也可以叫服务器
    server {
        listen       80;
        server_name  localhost;

        #显示前端页面的
        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

        我们知道基本的结构之后,就可以写自己的conf文件了。我们写上最基本的工作线程,events,http,server就可以了。其中在location中要有自己写的html文件。我们创建了四个进程和四个server,那么他们的关系什么?

worker_processes 4;

events{
    worker_connections  1024;
}

http{
    upstream backend {
		server 192.168.159.130:9002 weight=2;       #weight是负载均衡
		server 192.168.159.130:9003 weight=2;
	}

	server {
		listen 9000;
		location / {
#			root /home/king/share/nginx/html9000/;
			proxy_pass http://backend;  #这里是反向代理
		}	
	}

    server{
        listen 9000;
		location / {
            root /home/tc/html/html9000/;
        }
    }

    server{
        listen 9001;
		location / {
            root /home/tc/html/html9001/;
        }
    }

    server{
        listen 9002;
		location / {
            root /home/tc/html/html9002/;
        }
    }

    server{
        listen 9003;
		location / {
            root /home/tc/html/html9003/;
        }
    }
}

        我们配置好我们自己的文件后,通过调用这个conf文件来启动nginx,我们发现是四个工作进程和一个master。当我们去连接这四个server,我们发现这四个server都在master进程中,并不在这四个进程中。那么我们就可以了解,他们的关系是通过父进程fork来分配的,我们可以使用一个代码来演示一下:

int main(int argc, char *argv[])
{
    int sock_fd, epoll_fd;
    struct epoll_event event;
    struct epoll_event *events;
        
    if(argc < 2){
        printf("usage: [port] %s", argv[1]);
        exit(1);
    }
     if((sock_fd = sock_creat_bind(argv[1])) < 0){
        perror("socket and bind");
        exit(1);
    }
    if(make_nonblocking(sock_fd) < 0){
        perror("make non blocking");
        exit(1);
    }
    if(listen(sock_fd, SOMAXCONN) < 0){
        perror("listen");
        exit(1);
    }
    if((epoll_fd = epoll_create(MAXEVENTS))< 0){
        perror("epoll_create");
        exit(1);
    }
	
	event.data.fd = sock_fd;
	event.events = EPOLLIN;
	if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock_fd, &event) < 0){
		perror("epoll_ctl");
		exit(1);
	}
	
    /*buffer where events are returned*/
    events = calloc(MAXEVENTS, sizeof(event));
    int i;
    for(i = 0; i < PROCESS_NUM; ++i){
        int pid = fork();
        if(pid == 0){
            while(1){
	
                int num, j;
                num = epoll_wait(epoll_fd, events, MAXEVENTS, -1);
                printf("process %d return from epoll_wait\n", getpid());
                sleep(2);
                for(i = 0; i < num; ++i){
                    if((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))){
                        fprintf(stderr, "epoll error\n");
                        close(events[i].data.fd);
                        continue;
                    }else if(sock_fd == events[i].data.fd){
                       
                        struct sockaddr in_addr;
                        socklen_t in_len = sizeof(in_addr);
                        if (accept(sock_fd, &in_addr, &in_len) < 0){
                            printf("process %d accept failed!\n", getpid());
                        }else{
                            printf("process %d accept successful!\n", getpid());
                        }
                    }
                }
            }
        }
    }
}

上面的代码就是父进程fork,将连接进来的连接放入到工作进程中,也就是说父进程只接收,子进程工作。

2、负载均衡和反向代理

        首先我们先了解一下正向代理,当我们去访问一个国外网站,直接连接是不行的,这时候需要一个中间商,来帮助我们,我们先访问这个中间商,然后转到国外网站,这就是正向代理。

        反向代理,当我们一个客户端去访问一个大型服务器,我们连接上服务器之后,在服务器内部会进行反向代理,将这个连接分配到不同的服务器中去。如下面的图,我们客户端去连接服务器,就是简单的客户端和服务器的关系,但是到服务器内部之后,进行反向代理,这个服务器相对于服务器1234来说就是客户端,这个客户端服务器向服务端1234发送连接请求。

        对于负载均衡来说,就是在反向代理的时候,将这些连接请求,分配到不同的服务器中,将他们均衡分配就可以了。

三、conf 文件的解析

        对于conf文件,我们在写的时候,并未使用变量,而是token。由于nginx是为了做跨平台,所以自己写了一套解析方案,也就是所谓的token,并未使用变量。

{ ngx_string("worker_processes"),
      NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      ngx_set_worker_processes,
      0,
      0,
      NULL },
#这里是 worker_processes 这个token,对于他的解析的话,也就是通过空格来进行判断。
#当读到这个单词之后,那么他的数量就会通过解析空格来解析数量

0voice · GitHub

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部