Apache负载均衡与Spring Session

Apache web服务器配置

安装Apache并启动Apache服务

Apache是一个web应用容器,和tomcat,iis等是一类软件,除了普通web容器的功能,Apache还可以配置反向代理,实现web服务器的负载均衡。这里先示范如何通过Apache创建一个普通的web应用。通过apache官网下载apache,我下载的是Apache2.4解压版,所以还要手动配置一下。

  1. 配置安装目录
    这里写图片描述
    在apache的安装目录中找到conf文件夹,其中有一个httpd.conf文件,打开这个文件,在大约38行的位置配置一下apache的安装目录。

  2. 安装并启动服务
    进入命令行界面,执行指令httpd -k install -n Apache2.4。注意,如果上一步安装目录配置不正确,这里会提示找不到目录。
    这里写图片描述
    安装成功后,右键“计算机”->”管理”->”服务和应用程序”->”服务”,查看服务是否安装成功,安装成功后还要手动启动服务。
    这里写图片描述

  3. 配置web应用的相关属性
    首先是ServerName,也就是访问web应用时用的域名,这里用localhost:80:
    这里写图片描述
    然后是配置web应用所在目录:
    这里写图片描述
    这里使用了默认的目录htdocs,可以将自己的web应用放到这个目录下,这个目录自身已经包含一个html文件:
    这里写图片描述

4.访问web应用,如果修改过配置文件,需要在命令行中使用httpd -k restart重启一下服务器。
这里写图片描述

Apache反向代理配置与负载均衡

反向代理与正向代理相对,所谓正向代理,就是多个用户给自己的浏览器设置一个代理服务器,这样代理服务器就和多个客户端浏览器绑定,所有这些用户发送的请求都会先经过浏览器包装成目标地址为代理服务器的请求,这样就可以绕过一些访问限制。反向代理是指通过配置代理服务器,使代理服务器与多个web服务器绑定,然后仅对用户提供代理服务器的域名,代理服务器根据配置的映射关系将用户的访问转发到不同的web服务器中,这些web应用往往属于同一个系统,用来负载均衡,分流用户的请求。配置反向代理只需要两部,第一步为配置加载模块,第二部为配置映射。

加载模块

打开httpd.conf,分别找到如下两行,并将#注释去掉,这样Apache就会加载相关模块

#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
ProxyPass                  /proxy2 http://target2:port/url
ProxyPass                  /proxy3 http://target3:port/url
......

负载均衡

上面反向代理的作用是可以将一个地址/proxyX映射到另一个址http://targetX:port/url,这种映射关系是一对一的,实际应用中可能更多的是出于隐藏地址和网络安全方面的作用。负载均衡在反向代理的基础上,可以实现一对多的地址映射,这里“一”是统一的共用户访问的地址,“多”是多个完全相同的web应用,用户通过统一的地址访问应用,Apache根据负载均衡算法决定将用户的请求分配给哪一个web应用服务器,实现负载均衡的效果。

下面是一个配置实例:

LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so

<Proxy "balancer://mycluster">  
BalancerMember http://localhost:8080/firstapp
BalancerMember http://localhost:8080/secondapp
</Proxy>   
ProxyPass "/proxy" "balancer://mycluster" 
ProxyPassReverse "/proxy" "/firstapp"
ProxyPassReverse "/proxy" "/secondapp"
ProxyPassReverseCookiePath "/firstapp" "/proxy"
ProxyPassReverseCookiePath "/secondapp" "/proxy" 

可以看到,与反向代理不同的是,这里将地址映射到了”balancer://mycluster”,BalancerMember即为后台的web应用。Apache根据配置的负载均衡算法(注意第2行我们加载了byrequest类型的算法,它将按照BalancerMember声明的顺序转发用户的http请求),将请求转发给BalancerMember,这里firstapp和secondapp都是完全相同的web应用,这样就减轻了单台web服务器的压力,而对用户来说这一切都是透明的。

session共享问题

当使用负载均衡时会有session共享的问题。我们知道,web容器的session是通过向cookie中添加sessionid达到有状态的效果的。
使用反向代理时,假设:
用户第一次访问的地址是http://localhost/proxy/a.html ,该请求被Apache转发到http://target:port/url/a.html ,web服务器target1查询sessionid发现没有,则新建一个session,并把sessionid随响应报文一并传送回去。
当用户再次访问localhost时,如http://localhost/proxy/a.html ,浏览器会在请求报文中添加相同的sessionid,但此时报文被转发到了另一台web应用服务器target2,target2中查询后发现不存在这个sessionid,这就出现了错误。

Spring Session配置

Spring Session是解决多web服务器session共享的一个开源方案,通过Spring Session可以解决上面提到的问题。Spring Session的介绍这里不再重复,网上可以查到。这里主要利用官网的下载的sample结合Apache验证一下效果。

运行一个sample

官方的源码中有写好的sample,我们可以直接拿来体验一下,注意,这个sample并没有整合Apache反向代理。

  1. 下载samples,url为https://github.com/spring-projects/spring-session/
    这里写图片描述

  2. 搭建项目,选择httpsession-xml这个demo,
    这里写图片描述
    在eclipse中创建一个项目,服务器使用tomcat,并将demo中的内容复制过去,注意需要引用的第三方包
    这里写图片描述

  3. 安装redis数据库,我安装的是ms提供的window64位版,安装完服务会自动启用,不必手动配置。

  4. 运行项目
    这里写图片描述
    这个程序的作用就是设置并查看session的值,这个session是经过Spring Session定义的,不是tomcat自己的session 。下面,我们还是用这个sample,但是会整合Apache反向代理。

整合Apache反向代理与Spring Session

  1. 在tomcat的发布目录下建立两个项目,firstapp和secondapp,这两个项目的内容是一模一样的,都是上面httpsession-xml这个sample的内容。建立完后启动tomcat。
    这里写图片描述

  2. 在Apache的httpd.config中设置映射
    这里写图片描述
    注意ProxyPassReverseCookiePath这条设置,由于tomcat可以在同一域名下建立多个web应用,所以浏览器在传递sessionid时并不能仅靠域名选择要上传的cookie,还需要域名后的一级路径。当用户第一次访问站点时,站点返回的信息包含cookie(包含sessionid),域名,一级路径,浏览器将cookie(包含sessionid)和域名/一级路径对应起来,当用户再次访问相同的域名/一级路径时会上传这个cookie。使用反向代理时,web服务器返回的一级路径和域名都是web服务器而非Apache中映射的那个,比如用户第一次访问http://localhost/proxy/index.jsp ,web服务器返回的一级路径为/firstapp
    这里写图片描述,这样当用户再次访问http://localhost/proxy/index.jsp 时浏览器不会上传cookie ,因为浏览器将cookie绑定到了localhost/firstapp上了,所以我们要设置ProxyPassReverseCookiePath,将web服务器返回的一级路径进行转换。
    这里写图片描述

3.访问http://localhost/proxy/index.jsp , 设置一个session值
这里写图片描述
可以看到Apache将请求转发到了firstapp(这里我把sample里的jsp文件改了一下<title>标签,用来区分返回的是哪一个页面,实际应用中多个web应用的内容是完全相同的) ,我设置了一条session,key:proxy value:1
接下来点击“Set Attribute”按钮,请求会被提交到http://localhost/proxy/session(这是一个servlet)
这里写图片描述
可以看到虽然这次请求的是另一个web应用secondapp,但是它却获得了刚才firstapp设置的session值,这是因为Spring Session将session存储在独立的Redis数据库中而不是web容器内,这就实现了session共享。

最后是一幅图总结内容:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012334071/article/details/50586073