在">Azure Web Role中,开发者经常会面临一些场景,需要对IIS服务器做一定的配置和优化,以实现Web Role中的一些功能,如关闭静态文件加密(site compression)、强制SSL访问等,此类场景的出现具有一个共同的特点:web本身(包括code和web.config)不能实现开发者的需求,开发者必须通过配置web服务器(IIS)来实现其期望的web特性。
在PaaS中,用户通过远程连接(RDP)在web role虚机上的修改只能暂时生效,web role虚机在经历云平台的系统更新(每月一到两次)后,虚机环境会被恢复到刚刚发布的状态,即用户通过远程连接而做的设定(如IIS设定)会全部丢失!
因此,在Azure Web Role中,开发者如果需要自定义配置IIS服务器,必须通过代码来实现,以下就是一个例子:
1. 示例web role中,开启了http和https端口,网站中有一个文件夹test,测试目标是test目录下的所有页面仅能通过https访问。如示例项目:
2. 添加代码到webrole.cs文件中实现IIS中的SSL设置。此处需要指定目标目录名。
public override bool OnStart()
{
// By default, the website name is "[ Current Role Instance id]_Web"
string sitename = RoleEnvironment.CurrentRoleInstance.Id + "_Web";
// The folder you want to expose it only via https
string foldername = "test";
string cmd = string.Format(" set config \"{0}/{1}/\" /section:access /sslFlags:Ssl /commit:APPHOST", sitename, foldername);
string appcmdpath = @"d:\Windows\System32\inetsrv\appcmd.exe";
try
{
Process.Start(new ProcessStartInfo(appcmdpath, cmd));
Trace.TraceInformation("Initialize IIS ssl succeed.");
System.IO.File.AppendAllText("log.txt", DateTime.Now.ToString() + " | Initialize IIS ssl succeed.");
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
System.IO.File.AppendAllText("log.txt", DateTime.Now.ToString() + " | " + ex.Message + " | " + cmd);
//throw;
}
return base.OnStart();
}
3. 在servicedefinition文件中,找到对应的web role,添加以下设置。
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WindowsAzure4" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2013-03.2.0">
<WebRole name="WebRole1" vmsize="Small">
<Runtime executionContext="elevated"/>
<Sites>
<Site name="Web">
<Bindings>
……
4. 部署到云端,生效。
https://***.cloudapp.net/test/test1.aspx (work)
http://***.cloudapp.net/test/test1.aspx (does not work)
https://***.cloudapp.net/ (work)
http://***.cloudapp.net/ (work)
在Azure Web Role中,其他的IIS设定也可以通过类似的方法实现。其主要思路是:通过代码调用IIS自带的appcmd工具,用命令行的方式去设置IIS服务器。
关于appcmd工具:http://technet.microsoft.com/zh-cn/library/cc772200(v=ws.10).aspx
appcmd工具示例1--设定SSL访问:http://technet.microsoft.com/en-us/library/cc753983(v=ws.10).aspx
appcmd工具示例2--设定site compression:http://support.microsoft.com/kb/930909
下面的代码是使用上述类似的方式关闭site compression,IIS服务器中,默认情况下site compression是开启状态。
1. Add code part to your webrole.cs
public override bool OnStart()
{
string cmd = string.Format(" set config /section:urlCompression /doStaticCompression:False");
string appcmdpath = @"d:\Windows\System32\inetsrv\appcmd.exe";
try
{
Process.Start(new ProcessStartInfo(appcmdpath, cmd));
Trace.TraceInformation("Success: turn off compression for static content in IIS.");
System.IO.File.AppendAllText("log.txt", DateTime.Now.ToString() + " | Success: turn off compression for static content in IIS.");
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
System.IO.File.AppendAllText("log.txt", DateTime.Now.ToString() + " | " + ex.Message + " | " + cmd);
//throw;
}
return base.OnStart();
}
2. Do some change in service definition file:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WindowsAzure7" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2014-01.2.3">
<WebRole name="WebRole1" vmsize="Small">
<Runtime executionContext="elevated" />
<Sites>
<Site name="Web">
……
小结:Azure Web Role中,如果需要设定IIS服务器,需要通过代码方式来调用appcmd,以实现特别需求的服务器功能。任何通过远程连接的手动修改都是不可取的,其随时可能失效。