nginx 负载均衡与反向代理

概述

nginx是一个高性能的 静态http 和 方向代理服务器,目的是为了实现解决高并发的问题,即当多个请求同时进来时,会先通过nginx进程进行识别,然后访问到对应的后端服务器,可以说nginx是一个高效的中介,同时可以接纳多个请求

Nginx和apache

nginx相对于apache的优点:

  1. 轻量级,同样起web 服务,比apache 占用更少的内存及资源
  2. 抗并发,nginx 处理请求是异步非阻塞(可参考文章https://zhuanlan.zhihu.com/p/82935440)的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能 NIO netty NIO
  3. 高度模块化的设计,编写模块相对简单
  4. 社区活跃,各种高性能模块出品迅速

apache 相对于nginx 的优点

  1. rewrite ,比nginx 的rewrite 强大
  2. 模块超多,基本想到的都可以找到
  3. 少bug ,nginx 的bug 相对较多
  4. Nginx 配置简洁, Apache 复杂
  5. 最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程

nginx源码安装

准备工作

克隆一个纯净的虚拟机,修改名,并进行网络配置

安装

1.安装依赖的库

yum install gcc gcc-c++ pcre  pcre-devel openssl openssl-devel zlib  zlib-devel vim -y

2.创建源文件夹

首先在目录/opt下创建apps目录,用于存放源文件以及解压后的文件,将解压后的文件放在/opt/apps中

3.上传Nginx到2创建的目录

4.解压 Nginx:在/opt/apps下解压

tar -zxvf nginx-1.16.1.tar.gz

进入到/opt/apps 目录中的 Nginx 解压包目录,查看 Nginx 的目录。

其中各个目录中存放的文件作用为:

  • auto:存放 Nginx 自动安装的相关文件
  • conf:存放 Nginx 服务器配置文件
  • configure:命令,用于对即将安装的软件的配置,完成 Makefile 编译文件的生成
  • contrib:存放由其他机构贡献的文档材料
  • html:存放 Nginx 欢迎页面
  • man:manual,手册,存放 Nginx 帮助文档
  • src:存放 Nginx 源码

5.生成makefile文件

在 Nginx 解压目录下运行 make 命令,用于完成编译。但此时会给出提示:没有指定目标,并且没有发现编译文件 makefile。编译命令 make 需要根据编译文件 makefile 进行编译,所以在编译之前需要先生成编译文件 makefile。**使用 configure 命令可以生成该文件。**那么,configure 命令需要配置些什么参数呢?使用–help 可以查看到可以使用的参数说明。这些参数可以分为三类:

  • 第一类:基本信息的配置。
  • 第二类:默认没有安装,可以指定安装的模块,使用–with 开头。Nginx 的高扩展性就体现在这里。
  • 第三类:默认已经安装,可以指定卸载的模块,使用–without 开头。

一般只需要简单安装,简单安装在下面,指定安装目录和https访问支持:在解压文件目录下

./configure --prefix=/opt/nginx --with-http_ssl_module --with-http_gzip_static_module --error-log-path=/var/log/nginx/nginx.log --pid-path=/var/log/nginx/pid

下面是简单配置的命令执行。命令中每一行的最后添加了反斜杠\表示当前命令并未结束,回车不会执行该命令。执行成功后,会给出配置报告。下面以安装对 https 访问协议支持的模块 http_ssl_module 为例。

  • –prefix:用于指定 nginx 的安装目录。注意,安装目录与解压目录不一样。
  • –http_ssl_module:https 访问协议需要安装 Http 安全连接协议模块 SSL(Secure SocketsLayer,安全套接层)。注意,在执行过 configure 命令后并不会立即生成/usr/local/nginx 目录,也不会马上开始安装指定的模块,而仅仅是将命令中指定的参数及默认配置写入到即将要生成的 Makefile文件中。

配置报告以两部分构成:第一部分给出了配置的系统库;第二部分给出了系统配置信息。

  • l path prefix:Nginx 安装目录
  • l binary file:Nginx 命令文件
  • l modules path:Nginx 模块存放路径
  • l configuration prefix:Nginx 配置文件存放路径
  • l configuration file:Nginx 配置文件名
  • l pid file:Nginx 的进程 id 文件
  • l error log file:错误日志文件
  • l http access log file:http 访问日志文件;
  • l http xxx:其它 http 请求相关的文件。

配置成功后,再次查看 Nginx 解压目录,发现其中多出了一个文件 Makefile。后面的编译就是依靠该文件进行的。

注意: /var/tmp/nginx/client目录需要手动创建

[root@nginx1 nginx-1.16.1]# mkdir –p /var/tmp/nginx/client
[root@nginx1 nginx-1.16.1]# pwd
/opt/apps/nginx-1.16.1
[root@nginx1 nginx-1.16.1]# ./configure \
 --prefix=/opt/nginx \
 --sbin-path=/usr/sbin/nginx\
 --conf-path=/etc/nginx/nginx.conf \
 --error-log-path=/var/log/nginx/error.log \
 --http-log-path=/var/log/nginx/access.log \
 --pid-path=/var/run/nginx/nginx.pid \
 --lock-path=/var/lock/nginx.lock \
 --user=nginx \
 --group=nginx \
 --with-http_ssl_module \
 --with-http_flv_module \
 --with-http_stub_status_module \
 --with-http_gzip_static_module \
 --http-client-body-temp-path=/var/tmp/nginx/client/ \
 --http-proxy-temp-path=/var/tmp/nginx/proxy/ \
 --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
 --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
 --http-scgi-temp-path=/var/tmp/nginx/scgi \
 --with-pcre  

6.编译安装

这是两个命令,make 为编译命令,make install 为安装命令,可以分别执行。这里使用&&将两个命令连接执行,会在前面命令执行成功的前提下才会执行第二个命令。(在解压目录下)

make && make install

7.nginx可以随处使用

在 Nginx 的安装目录/opt/nginx 中有一个 sbin 目录,其中存放着 nginx 的命令程序nginx。默认情况下,若要使用 nginx 命令,则必须要在/opt/nginx/sbin 目录中,或指定命令路径,使用起来很不方便。为了能够在任意目录下均可直接执行 nginx 命令,可通过以下两种方式完成。

  • 方式一:添加环境变量

/etc/profile 文件最后添加以下内容,将安装目录下的 sbin 目录添加到 PATH 系统环境变量中。然后再重新加载该文件即可。

#修改环境变量
export PATH=$PATH:/usr/sbin/nginx  #注意执行文件的位置
useradd nginx  #添加用户(默认添加nginx用户组)
nginx  #启动nginx

方式二:添加nginx到服务列表

将如下内容添加到/etc/init.d/nginx脚本中,并添加可执行权限。(/etc/init.g/nginx为人为创建,点击脚本内容

# vim /etc/init.d/nginx
# 修改nginx文件的执行权限
chmod +x nginx
# 添加该文件到系统服务中去
chkconfig --add nginx
# 查看是否添加成功
chkconfig --list nginx
# 启动,停止,重新装载
service nginx start|stop|reload 
# 设置开机启动
[root@nginx1 conf]# chkconfig nginx on
[root@nginx1 conf]# chkconfig
nginx          	0:off	1:off	2:on	3:on	4:on	5:on	6:off

工作原理

master-worker模式

1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。

2、Master接收来自外界的信号,向各worker进程发送信号,每个进程都有可能来处理这个连接。

3、Master进程能监控Worker进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RCX67GII-1677848529175)(…/img/image-20221125231508987.png)]

accept_mutex接受锁

​ 由于所有子进程都继承了父进程的sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。Nginx 提供了一个accept_mutex加在accept上的一把共享锁。即每个worker进程在执行accept之前都需要先获取锁,获取不到就放弃执行accept()。有了这把锁之后,同一时刻,就只会有一个进程去accpet(),这样就不会有惊群问题了。

​ 当一个worker进程在accept()这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,完成一个完整的请求。一个请求,完全由worker进程来处理,而且只能在一个worker进程中处理。

为什么使用进程不使用线程?

1、节省锁带来的开销。每个worker进程都是独立的进程,不共享资源,不需要加锁。同时在编程以及问题查上时,也会方便很多。

2、独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程。当然,worker进程的也能发生意外退出。

如何处理并发请求?

​ 每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么傻等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。此时,如果再有request 进来,他就可以很快再按这种方式处理。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。由于web server的工作性质决定了每个request的大部份生命都是在网络传输中,实际上花费在server机器上的时间片不多,这就是几个进程就能解决高并发的秘密所在。

nginx配置说明

nginx的重点是配置文件nginx.conf,是/opt/nginx/conf/nginx.conf文件,而非/opt/apps/nginx/conf/nginx.conf文件

nginx文件由三个部门组成,全局块,events模块已经

全局块

从配置文件开始到events之间的内容,主要会设置一些影响nginx服务器整体运行的配置命令。主要包括配置运行Nginx服务器的用户(组)、允许生成的worker process数,进程PID存放路径、日志存放路径和类型以及配置文件的引入等

#user  nobody;
worker_processes  1;	# 设置最多进程数

#error_log  logs/error.log;	# 默认地址
#error_log  logs/error.log  notice;	
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;	# 进程id储存地址

events块

events块涉及的指令主要影响Nginx服务器与用户的网络连接,常用的设置包括是否开启对多work process下的网络连接进行序列化,是否允许同时接受多个网络连接,选取哪种事件驱动模型来处理连接请求,每个work process可以同时支持的最大连接数等。

下面的例子表示每个work process支持的最大连接数为1024。这部分的配置对Nginx的性能影响比较大,在实际中应该灵活配置。

events {
	use epoll;
    worker_connections  1024;
}

工作模式与链接上线

一般用的是ues epoll,epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型。

参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; 如果跑在FreeBSD上面,就用kqueue模型。

uname -a :查看服务器系统相关的信息

nginx理论上能接受的最大并发数为 worker_connections * worker_proess;而进行设置这些参数时根据电脑物理内存进行设置。即最大并发数需少于系统可以一瞬间打开文件的最大句柄数,(通过$ cat /proc/sys/fs/file-max进行查看)。一般1G的内存可以同时打开10万个左右的文件,在设置时还需考虑保留一定的内存给其他软件

http模块!

这是Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。需要注意的是:http块也可以包括http全局块、server块。

全局块

http全局块配置的指令包括文件引入、MIME-TYPE定义、连接超时时间、单链接请求数上限等。

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;	# 是否开启零拷贝
    #tcp_nopush     on;	#

	# 每一个会话的缓存时间,即一个请求对应的进程退出后,其相关数据会在内存内保留的时间,每一个会话对应一个进程,当会话退出后,若在一定时间内重新请求的话,会继续有此进程负责,反之则可能分配给其他进程
	# 若要测试负载切换情况的话,可设置为0
    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;	# 传输过程中是否进行压缩,即先将文件压缩,在进行传输,有利于提高传输情况

    server {	# server 配置域名,地址啥的
}}

server模块

主机的监听配置和本虚拟主机的名称和IP配置,其中包含这location块,一个server可以包含多个location块。nginx主要是一个虚拟主机,根据传入请求的目的分配给对应的后端服务器,则主要的分配设置即在server中。

同一个服务器可以用多个域名进行访问,且特定域名的服务器访问到的结果不一样,见下文配置,www.sxthenhao.com和www.123.com都可以访问nginx(192.168.38.95),但是两者访问的页面和位置不一样,前者访问的是/mnt目录且以目录列表访问的形式,后者访问的是html文件下的index.html

    server {
        listen       80;
        server_name www.sxthenhao.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /mnt;	# 以root名义访问 /mnt
            autoindex on;	# 以目录列表的形式访问
        }
        }
    server {
        listen       80;
        server_name www.123.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm; 	 # index 普通模式
        }
    }
  • 在/opt/nginx/conf/nginx.conf中配置以上文件

  • 修改hosts文件(c:\Windows\System32\drivers\etc)

    192.168.20.11 nginx1 www.123.com  www.sxthenhao.com
    
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rrstzeyh-1677848529176)(…/img/image-20221126235416956.png)]

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-187DQ1Ix-1677848529177)(…/img/image-20221126235444413.png)]

日志文件配置

日志文件主要记录了访问此服务器的情况;日志文件配置在http模块中。

同一个虚拟主机可以由多个域名进行访问,各个域名可以有自己的日志文件。记录的内容也可因需而异,可以通过修改记录日志的**模板(log_format main ‘模板’)**来修改需要记录的内容。

  • 若无指定日志文件和模板,则默认保存在 logs/access.log 中,且以main为模板

  • 若有指定日志文件和模板,则以对应模板保留在对应的文件。见下文

    域名www.sxthenhao.com的日志文件为/sxthenhao.log中,且以main为模板

  • http全局模块下配置,是所有server模块公用的,某server模块下配置,则该模块使用

http {
    include       mime.types;
    default_type  application/octet-stream;
	
 ❤️默认模板情况main
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

 ❤️创建模板
 	log_format mymodel '$remote_addr - $remote_user [$time_local] "$request" ' # 创建mymodel模板,只记录客户端IP地址,客户端用户,访问时间,请求详细等
 	
 ❤️默认地址	
    #access_log  logs/access.log  main;
 	
	……

    server {
    listen 80
    server_name www.sxthenhao.com;		 
 ❤️ access_log logs/sxthenhao.log main;	"""此配置说明访问域名www.sxthenhao.com的情况将被记录在/sxthenhao.log中,且以main为模板"""
    
}
    server {	
    listen 80
    server_name www.123.com;
 ❤️ access_log logs/123.log  mymodel; 	# 访问www.123.com的情况将会以模板mymodel记录在123.log中 
    
}
}

😊配置结果检查 利用 tail -n k -f 日志文件来监控日志文件的后k行

# 默认的文件
[root@nginx1 logs]# tail -n 2 -F access.log 
192.168.38.1 - - [27/Nov/2022:13:59:22 +0800] "GET / HTTP/1.1" 200 124 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.37"
192.168.38.1 - - [27/Nov/2022:13:59:27 +0800] "GET /favicon.ico HTTP/1.1" 404 187 "http://www.sxthenhao.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.37"

# 自己创建的日志文件
[root@nginx1 logs]# tail -n 2 -f 123.log 
192.168.38.1 - - [27/Nov/2022:14:04:41 +0800] "GET / HTTP/1.1" sendfileon
192.168.38.1 - - [27/Nov/2022:14:04:52 +0800] "GET /write HTTP/1.1" sendfileon

模板参数说明

  • $remote_addr:客户端IP地址
  • $server_name:虚拟主机名称
  • $http_x_forward_for:http端请求的真实IP
  • $remote_user:表示客户端用户
  • $request:表示请求的详细,即客户端输入的信息
  • $upstream_status:表示upstream的状态,Nginx作为反向代理时使用。
  • $body_bytes_sent:表示Nginx发送给客户端的字节数,不包括HTTP头的大小
  • $bytes_sent:表示Nginx发送给客户端的字节数,包括HTTP头的大小
  • $bytes_sent:表示Nginx发送给客户端的字节数,包括HTTP头的大小.
  • $request_time:表示请求处理时间,单位为秒,精度为毫秒级别,表示Nginx接受用户请求的第一个字节到发送完响应数据的时间,包括接收请求数据时间
  • $upstream_response_time:表示应用程序响应时间,Nginx作为反向代理时使用,计算从Nginx向后端真实服务器建立链接开始到接受完完整数据然后关闭链接的总时间。

反向代理配置

反向代理配置是在http模块下进行配置的,反向代理原理:用户输入域名、URL和端口(“域名/url:端口”),反向代理服务器根据域名匹配对应的server块,匹配成功后根据url匹配location块,执行对应的业务

server匹配,域名解析匹配

server块中含有location块,而server主要是配置端口和域名,以及一些server块的日志文件等。

注意:

  • 域名和端口两者组合需唯一
  • server_name 可以使用正则匹配
http{
……
	server{
		listen 80;	# 端口设置
		server_name www.123.com  www.xxx.com;	#  域名设置,输入此域名将匹配到此server块

        #log_format mymodel  '$remote_addr - $remote_user [$time_local] "$request" $status'
    	#access_log  logs/access.log  main;
        ……
		location {……}
	}
    server{
        listen 32;	# 
       	server_name www.*.com;	# 上方不匹配则匹配此处
        location {……}
    }
}

location匹配

一个server中可以配置多个location;当虚拟主机匹配完成域名和端口号后,将根据url匹配对应的服务器,也就是location

匹配规则:

  • location [= | ~ | ~ | ^~ | ] URI {…}*:

    其中URL为表示域名后面的参数,即www.xxx.com/URI

  • location /URI {}:简单匹配

    若URL为空,则直接匹配此location,进入此location代理的服务器或页面

    若URL为当前location的指定目录的子目录时,也匹配成功,访问对应的子目录。

    server_name www.xxx.com;
    location / {
    	root   html;
    	index  index.html 123.txt;
    }
    
    """
    见上述配置,其为最简单的配置,只有一个 /,其对应的代理目录为 html,其有子目录 index.html,123.txt。因此若输入www.xxx.com将匹配到该location,且访问index.html(因为其在前面),输入www.xxx.com/123.txt则也会匹配该location,其访问123.txt
    """
    
  • location = /URI {}:精准匹配 (暂时没有搞明白)

    等号,表明只有输入的uri与URI完全匹配时,才会匹配到此location

  • location ~ | ~ URI {}*: 正则化匹配

    其中表示区分大小写,*表示不区分大小写

  • location ^~ URI {}:不适用正则匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jyGsnGD8-1677848529178)(…/img/image-20221129144139286.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKu7QVDW-1677848529178)(…/img/image-20221129144209378.png)]

反向代理配置

主要关键字为root和proxy_pass,主要用指定代理的服务器地址。两者只能存在一个

  • root:通常指代理到服务器域名服务器的内部文件,如root /mnt则反向代理到此目录下去

    经常携带的关键字:

    index:指定默认访问的文件。e:index index.html 11.txt 则优先访问index.html

  • proxy_pass:通常指代理到域名服务器以外的文件;如proxy_pass https://www.baidu.com

    proxy_pass指定的服务器,至少需要有httpd服务,因此需要代理的服务器需先下载httpd,并开启。则进行访问时将默认访问/var/www/html/文件夹下的内容。

    开头为https或http,需要根据服务器的协议来。首先选择https

  • 如果用的是关键词root,location配置为斜杠即可(即location /{}),且root一般放在最前面。

server {
    listen       80;
    server_name www.123.com;	

    #charset koi8-r;

    access_log logs/123.log mymodel;
    # access_log  logs/host.access.log  main;

    location = /bili {					# 为精确匹配
        proxy_pass https://www.bilibili.com/;
    }
    location ~* /s* {					# 正则化匹配
        proxy_pass https://www.baidu.com;
    }
}

当子服务器下载了httpd服务后,即可以在网页上链接,并进入对应的页面,比如node2下载的httpd,且在/var/www/html/文件夹中创建了index.html则可以利用nginx 进行反向代理。

server {
	listen       80;
	server_name www.sxthenhao.com;

	location /xo {
		proxy_pass http://192.168.38.92/;	# 子服务器,后面加上/默认表示访问首页
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wjXMT43g-1677848529179)(…/img/image-20221129151212682.png)]

负载均衡

这个均衡是指在大批量访问前提下的一种基本均衡,并非是绝对的平均。对于 Web 工程中的负载均衡,就是将相同的 Web 应用部署到多个不同的 Web 服务器上,形成多个 Web 应用服务器。当请求到来时,由负载均衡服务器负责将请求按照事先设定好的比例向 Web 应用服务器进行分发,从而增加系统的整体吞吐量。即将多个相同功能的服务器合理分类工作。

主要关键字

  • upstearm name{ server 域名1, server 域名2}

    指定进行负载均衡服务器的ip,定义为集群,其中name为集群的名字。

  • http://name/;集群进行指定

# 为www.123.com 设置两个服务器进行负载均衡

http{
	upstearm rss{
		server 192.168.38.92 weight=8;	# 第一个服务器,weight指定该服务器负载的权重,
		server 192.168.38.93 weight=2 down;	# 第二个服务器,down表示听停用此服务器
		server 192.168.38.94 weight=1 backup; 	# 第三个服务器,backup表示此服务器为备用,当前无可用服务器时,开启此
	}
	server{……}
}

session共享

含义

​ http协议是无状态的,即你连续访问某个网页100次和访问1次对服务器来说是没有区别对待的,因为它记不住你。那么,在一些场合,确实需要服务器记住当前用户怎么办?比如用户登录邮箱后,接下来要收邮件、写邮件,总不能每次操作都让用户输入用户名和密码吧,为了解决这个问题,session的方案就被提了出来,事实上它并不是什么新技术,而且也不能脱离http协议以及任何现有的web技术

​ session的常见实现形式是会话cookie(session cookie),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。实现机制是当用户发起一个请求的时候,服务器会检查该请求中是否包含sessionid,如果未包含,则系统会创造一个名为JSESSIONID的输出 cookie返回给浏览器(只放入内存,并不存在硬盘中),并将其以HashTable的形式写到服务器的内存里面;当已经包含sessionid是,服务端会检查找到与该session相匹配的信息,如果存在则直接使用该sessionid,若不存在则重新生成新的 session。这里需要注意的是session始终是有服务端创建的,并非浏览器自己生成的。 但是浏览器的cookie被禁止后session就需要用get方法的URL重写的机制或使用POST方法提交隐藏表单的形式来实现

​ 首先我们应该明白,为什么要实现共享,如果你的网站是存放在一个机器上,那么是不存在这个问题的,因为会话数据就在这台机器,但是如果你使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器,而它的session数据可能存在其中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。

配置

nginx1(192.168.38.95)为反向代理服务器,node2(92)node(93)为被代理服务器,目的是实现node2,node3的session共享。

其中,session共享通过 memcached 软件实现,即需要在nginx1上下载memcached软件。node2和node3以tomcat作为测试。

tomcat下载配置

  • 安装jdk和tomcat,都是解压安装

  • [root@node2 apps]# rpm -ivh jdk-7u80-linux-x64.rpm
    [root@node2 apps]# find / -name '*java*'
    #可以看出/usr/java/jdk1.7.0_80/
    配置环境变量
    [root@node2 jdk1.7.0_80]# vim /etc/profile
    加入以下两行代码:
    export JAVA_HOME=/usr/java/jdk1.7.0_80
    export PATH=$PATH:$JAVA_HOME/bin
    让文件生效:
    [root@node2 apps]# source /etc/profile
    [root@node2 apps]# jps
    13894 Jps  #说明jdk安装配置成功
    
  • 解压apache-tomcat-7.0.69.tar.gz

    tomcat和http的功能相似,但是http是80端口,tomcat是8080端口(默认);因此需要修改nginx.conf

    upstream rss {
    	server 192.168.20.102:8080;
    	server 192.168.20.103:8080;
    }
    

    访问tomcat默认访问的是 webapps/ROOT/index.jsp。因此进行修改,测试。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8XN35dTM-1677848529179)(…/img/image-20221201150552952.png)]

memcached下载配置

  • 安装 libevent

  • 安装 memcached

  • 启动memcached

    memcached -d -m 128m -p 11211 -l 192.168.38.95 -u root -P /opt/memip
    
    -d:后台启动服务
    -m:指定session的缓存大小
    -p:指定访问的端口
    -l:指定服务器的地址
    -P:存储服务器启动后的系统进程ID
    -u:以哪个用户名作为管理用户
    
    其中-l-p指定的服务器ip即端口,会将session缓存存放在到指定的服务器上去,不一定是本服务器,因为当业务很大时,可能会有一个专门储存session的服务器。
    
    
  • 利用memcached 进行session共享,需要在进行共享的服务器上传上jar包

    进行共享的服务器,读取缓存时,所指定的ip和端口需一致,见下文

session配置

  • 将memcached需要的jar包拷贝到 tomcat的lib下。

  • 配置tomcat,为其指定session缓存的地方。

    在tomcat的conf/context.xml中加入以下脚本

    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" 
    	memcachedNodes="n1:192.168.38.95:11211" 	# 需y代理服务器中的指定缓存ip个端口一致
        sticky="false" 
        lockingMode="auto"
        sessionBackupAsync="false"
    	requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        sessionBackupTimeout="1000" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" 
    />
    

    进行共享的服务器都需增加此脚本

    其中,ip端口需和代理服务器指定的一致

  • 最后进行重启tomcat

    在 /bin/下的shudown.sh 表示关闭,startup.sh表示启动。

配置脚本内容

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
nginx="/opt/nginx/sbin/nginx"
prog=$(basename $nginx)
 
NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"
 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
 
make_dirs() {
   # make required directories
   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
 
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
 
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
 
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
 
force_reload() {
    restart
}
 
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
 
rh_status() {
    status $prog
}
 
rh_status_q() {
    rh_status >/dev/null 2>&1
}
 
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

末尾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值