一、系统物理结构
本系统网络分为:内部局域网和互联网。服务器位于内部局域网,通过反向代理服务器对互联网公布系统,用户通过互联网访问系统。从网络层面安全进行隔离。用户访问系统基于http协议,系统内部之间服务器通信基于tcp/ip协议。根据部署应用的划分,将服务器分为负载均衡服务器、Web服务器、应用服务器、数据服务器四大类。
(1)负载均衡服务器
基于Linux之CentOS平台搭建Nginx服务,作Load Balance。
(2)Web服务器
基于window平台下IIS web服务器。部署基于asp.net mvc、web api技术实现的程序。
(3)应用服务器
部署基于.net平台通信框架之WCF技术实现的服务接口,提供与展现层调用,其中部分公用组件,如MQ则根据组件的要求部署。
(4)数据服务器
本系统数据存储选用:mssql数据库、MongoDB、Redis缓存和文件存储。根据项目情况数据库可做读写分离,同时结合redis做缓存策略提高系统性能。
二、nginx配置负载
Nginx没有httpnetwork的访问权限,需要设置
另外一种方式是ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
ip_hash设置
轮询方式还可以在server后指定权重
在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:
down,表示当前的server暂时不参与负载均衡。
backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
注,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
三、Keepalived+LVS+Nginx负载均衡之高可用
k
服务器 | IP地址 |
虚拟IP | 192.168.1.120:80 |
主机 | 192.168.1.104:80 |
备机 | 192.168.1.103:80 |
Web站点A | 192.168.1.101:8081 |
Web站点B | 192.168.1.101:8082 |
可能需要开启路由转发(一下是CenterOS6.5的 7的是否是这样有待考证)
3、进行Keepalived.conf配置,如果是MASTER机,将state BACKUP改为state MASTER。
# 定义对外提供服务的LVS的VIP以及port
从负载服务器与主负载服务器大致相同,只是在keepalived的配置文件中需要改以下两处:
(1)将state由MASTER改为BACKUP
(2)将priority由100改为99
我们看到将104服务器从 LVS移除掉。此时则将后续请求转发到103服务器。
关机后,BACKUP服务器 keepalived日志显示无法连接104,并移除掉
开机后,将自动检测到服务器正常,并加入LVS中。
新建一个MVC5工程,新建一个Controller,在Index方法实现将当前时间保存到Session["mysession"],并写Cookies["mycookies"]存储主机名和当前时间。
public
ActionResult Index()
{
if
(
this
.HttpContext.Session[
"mysession"
] ==
null
)
{
this
.HttpContext.Session[
"mysession"
] = DateTime.Now.ToString(
"yyyy-MM-dd hh:mm:ss"
);
}
this
.HttpContext.Response.Cookies.Add(
new
HttpCookie(
"mycookies"
)
{
Expires = DateTime.Now.AddDays(1),
Value = HttpContext.Server.MachineName +
"||"
+ DateTime.Now.ToString()
});
return
View();
}
public
ActionResult GetSession()
{
if
(
this
.HttpContext.Session[
"mysession"
] !=
null
)
{
ViewBag.DD =
this
.HttpContext.Session[
"mysession"
].ToString();
ViewBag.SCode =
this
.HttpContext.Session[
"mysession"
].GetHashCode().ToString();
ViewBag.SID =
this
.HttpContext.Session.SessionID;
}
ViewBag.CVAL = System.Web.HttpContext.Current.Request.Cookies[
"mycookies"
].Value;
ViewBag.CID = System.Web.HttpContext.Current.Request.Cookies[
"mycookies"
].Name;
ViewBag.CDO = System.Web.HttpContext.Current.Request.Cookies[
"mycookies"
].Domain;
return
View();
}
将session和cookies信息在页面显示,GetSession视图代码如下:
@{ ViewBag.Title = "GetSession";}
<h2>站点:A -- GetSession</h2>
<span>站点:A</span><br />
<span>Session Value: @ViewBag.DD</span><br/>
<span>Session SCode: @ViewBag.SCode</span><br />
<span>Session ID: @ViewBag.SID</span><br />
<span>Cookies ID: @ViewBag.CID</span><br />
<span>Cookies Values: @ViewBag.CVAL</span><br />
<span>Cookies Values: @ViewBag.CDO</span>
.Net平台对支持几种session存储模式:
(1)InProc 模式 session存储于当前站点在同一个进程内,修改web.config或者bin中文件更新,会导致session丢失。此模式为默认模式。
(2)aspnet state 模式
aspnet state是将session存储在状态服务中,需要启动ASP.NET State Service,能看到进程aspnet_state.exe。还需要在web.config配置此模式。
(3)SQLServer 模式 此模式需要SQL Server配置相关信息,启动代理服务、数据库账号及表,并将web.config指向数据库。
(4)第三方扩展 模式 本框架采用此模式,将session存储到其他存储,比如:Memcached、redis缓存中,达到共享session的目的。可以通过实现ASP.NET中的SessionStateStoreProviderBase这个抽象类扩展。本系统采用将session存储在redis缓存中,通过引入 RedisSessionStateProvider组件。
Install-Package Microsoft.Web.RedisSessionStateProvider
通过以上验证,获取到的session和cookies都是一致。