使用Nginx解决IIS绑定域名导致应用程序重启的问题
在将多个站点迁移到一个站点(Tenant Feature)的时候碰到了一个棘手的问题,用户需要绑定自定义域名,但IIS绑定域名的时候会导致这个站点重启,那么只要一个用户绑定了一个域名则会导致这个应用上的其它租户都会受到影响,下面写出我们的解决方案,但不一定是最优的。
问题在IIS上绑定域名导致应用程序重启
一个简单的测试
1.新建一个空MVC项目,在MvcApplication类中定义一个全局的静态变量
2.创建一个控制器和视图
3.在视图页对MvcApplication中的Count进行++并输出
4.访问几次页面
5.绑定一个域名
6.刷新页面
至此验证完成,可以看到应用被重启了。
为什么绑定域名会导致应用程序重启
其实原理和更改Web.config文件会导致应用重启启动是一样的,因为绑定域名时实际在C:\Windows\System32\inetsrv\config\applicationHost.config文件中增加一了一段配置,如下:
只有IIS会重启?
答案是否定的,在早期我接触Java的时候Tomcat等也是需要重启的,不过是需要手动重启服务,现在我就不清楚老。
使用Nginx解决问题
为了解决这个问题可谓是找了很多资料,最终无奈使用一个代理服务器来解决这个问题,虽然我觉得在这里Nginx受了委屈,因为它更大的作用是负载均衡,但能解决问题就行,以后在大访问量的时候也可以派上用场,下面就简述下使用Nginx解决这个问题的过程。
原理其实非常简单,在用户访问一个Url时由Nginx去分配,这样域名就可以不用直接绑定在IIS上,而由Nginx来分配域名指向哪里。
提前在IIS上绑定无数个泛解析域名
比如:site1.cs.xxx.com~site9999999.cs.xxx.com,这样就免去了在新增Tenant时需要绑定域名的尴尬。
将绑定自定义域名的动作交给Nginx
Nginx没有提供什么API,只有一个配置文件和几个命令,所以我们要做的就是将在Nginx上配置域名的动作自动化,我们为此写了一个Daemon Service来完成这个动作,下面会介绍并放出这个守护程序的使用说明及源码。
这样IIS绑定域名的问题就解决了,但其实在这个方案之前我们还有过其他的方案。
被Pass掉的方案
1.一台服务器只挂一个站点,而这个站点不绑定任何域名,所有指向这个服务器IP的80端口的请求全部由这个站来响应。
Pass原因:浪费资源,80端口被极大的浪费。
2.每天定点绑定域名
Pass原因:用户绑完域名后生效时间不确定,可能需要等到晚上12点之后才能生效。
Nginx自动化配置
Server
守护服务的主要原理是这样的,守护服务提供一个WCF服务,这个WCF服务中有两个操作,绑定域名和删除域名,服务约束如下:
具体实现代码就不演示了。
使用说明
1.配置守护服务(App.config)
主要有两个配置:
NginxPath:Nginx的存放路径,因为我要找到配置文件和nginx.exe,你懂的。
RunModel:因为Nginx只提供了命令行的模式去执行,所以我需要借助PowerShell或CMD,注意如果使用PowerShell,则PowerShell的版本必须为3.0及以上。
2.配置Nginx
因为Nginx默认的配置文件中有很多配置,所以我们单独把域名的配置独立出来,这就需要对Nginx原有的配置进行一些修改。
打开nginx-1.7.2\conf\nginx.conf文件,在http节点下添加配置 include custom.conf;
到这里我们的配置就完成了,接下来启动服务。
Client
1.添加服务引用
2.添加如下测试代码
运行之后会发现nginx-1.7.2\conf\下多出了一个custom.conf文件。
内容为:
到这里我们就测试通过啦,如果想看效果请自行hosts映射test1.com和test2.com到本地IP。
为了防止绑定失败我们同时在服务的根目录下保存了domains.xml文件,域名的绑定信息也会在此保留,这样大家就可以自己还原啦。
Daemon Service Source Code
https://files.cnblogs.com/ants/ChunSun.NginxServer.DaemonService.zip
说明:该源码是我精简过后的,原来的源码是基于Rabbit Kernel的,所以精简后的源码没有提供日志等功能的支持,大家可以自行添加。