当程序员使用Visual Studio 2010为SharePoint 2010创建应用程序时,可以创建两种类型的解决方案,服务器场解决方案和沙盒解决方案。比如,打开Visual Studio 2010,新建一个空白SharePoint项目,你看到的第一个界面就是如下这个对话框。
服务器场解决方案(或简称为场解决方案)和SharePoint 2007一样,是一种被完全信任的解决方案。场解决方案可以包含能放到解决方案包里面的所有SharePoint组件和元素,比如应用程序页、可视化Web部件等等。在SharePoint 2010系统上安装场解决方案包,需要系统管理员在SharePoint服务器上,打开命令提示符窗口或PowerShell窗口,输入相应的命令行指令或Cmdlet,将这个场解决方案包安装到SharePoint服务器场里面。
如果你的客户对SharePoint系统有严格的管控流程,那你就惨了。你辛辛苦苦的把代码里面的Bug全部修正之后,把项目打包成更新的解决方案包,然后,身为开发人员的你必须填写N张表格,接着就只能眼巴巴的等着管理服务器场的IT人员帮你把这个更新的解决方案包部署到服务器场里面,因为只有他们才有权限能在服务器上直接操作。如果客户每次还需要你去解释,到底每次更新都做了些什么,对服务器有何影响,那你就更加会头大了。
于是SharePoint 2010引入了沙盒解决方案的概念。说到“沙盒”,嗯,这可是好东东啊。这些年整个开发平台都在围着“沙盒”转,JVM就是一个“沙盒”,CLR也是一个“沙盒”。有了“沙盒”,就能将自定义代码限制在其中,即使它一不小心crash掉,也能最小化带来的影响。
SharePoint沙盒解决方案的作用也差不多。如果开发人员将自己的SharePoint 2010项目创建为沙盒解决方案,那么SharePoint 2010会在一个特定的“沙盒”中运行沙盒解决方案,并随时监控“沙盒”里面代码的运行情况。
对于场解决方案里面所包含的代码,除了少数组件外,其他大部分组件,例如Web部件、页面、事件处理程序之类的,都是被载入到w3wp.exe进程中运行。这个是理所当然的,因为SharePoint就是一个ASP.NET Web应用嘛,所以各种自定义代码自然会被ASP.NET Runtime给载入到w3wp.exe进程中。
但是如果是沙盒解决方案,其中所包含的代码将运行在一个单独的进程中(准确的说,有好几个进程都被用于运行沙盒解决方案里面的代码),而并非w3wp.exe进程。
例如,开发人员将一个自定义Web部件打包到一个沙盒解决方案包,部署到一个网站集并激活,然后将这个Web部件给放置到某个页面上。当有用户访问这个页面时,w3wp.exe就会发现,需要运行那个Web部件中所包含的自定义代码,这时,w3wp.exe进程会联系(本地或远程服务器上的)SPUCHostService.exe进程,告诉它需要以“沙盒”模型执行一些代码。SPUCHostService.exe进程会通知SPUCWorkerProcess.exe进程载入需要运行的代码,SPUCWorkerProcess.exe进程会通过SPUCWorkerProcessProxy.exe来完成对SharePoint对象模型的调用,并执行那个Web部件中的自定义代码。这些代码执行完成之后,会将执行结果最终返回到w3wp.exe进程,w3wp.exe拿到这个自定义Web部件的执行结果,就可以继续将页面执行下去了。
要想SharePoint 2010服务器场能执行沙盒解决方案,就需要在至少一台服务器上启动“Microsoft SharePoint Foundation沙盒代码服务”。从SharePoint 2010管理中心打开“服务器上的服务”页面,就可以将这个服务在指定的物理服务器上启动或停止。
如果你的服务器场包含了n台服务器,那么你既可以在所有物理服务器上启动“Microsoft SharePoint Foundation沙盒代码服务”,也可以只选择在某几台应用服务器上启动“Microsoft SharePoint Foundation沙盒代码服务”。甚至最极端的,你可以准备一台CPU和内存都很强大的服务器,加入到服务器场中,然后专门在这台服务器上运行“Microsoft SharePoint Foundation沙盒代码服务”。这样,无论服务器场中的哪一台前端服务器需要运行沙盒解决方案中的自定义代码,这些请求都会被发送到这台强大的物理服务器。万一沙盒解决方案里面的自定义代码很烂,会严重影响运行代码的服务器的CPU或内存资源,那么也只会影响到这一台特定的服务器。
当w3wp.exe进程需要找到一个地方运行沙盒代码时,它会基于某种预先制定的策略。SharePoint 2010有两种策略可用:1、总是在得到请求的同一台服务器上运行沙盒代码;2、使用一种内置的优化规则来传递执行请求。第1种策略非常简单,w3wp.exe总是会将执行沙盒代码的请求传递给自己这台服务器上的SPUCWorkerProcess.exe进程,也就是由当前服务器负责运行沙盒代码。第2种策略类似于一种“负载平衡”机制,SharePoint会检查服务器场中哪些服务器可以用来运行沙盒代码,然后按照一个优化规则,让w3wp.exe将执行代码的请求传递到某台服务器。这个优化规则简单来说就是,如果上次是服务器A执行了某个沙盒解决方案里面的一个Web部件代码,那下次会优先考虑继续让服务器A执行同一个Web部件里面的代码。
具体选择哪个策略,可以在SharePoint 2010管理中心打开“系统设置 - 管理用户解决方案”页面,然后就能选择2个策略中的某一个了。
沙盒解决方案中包含的代码除了会在单独的进程中运行之外,它还有很多的限制。首先,SharePoint 2010使用了CAS(Code Access Security)来限制了沙盒代码能做的事情。在“Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG\wss_usercode.config”文件中定义了沙盒代码的CAS策略,沙盒代码的权限被这个CAS策略限制为:
●SecurityPermission.Execution:可以执行托管代码;
●AspNetHostingPermission = Minimal:可以在ASP.NET中运行,但不能访问服务器上的任何资源;
●SharePointPermission.ObjectModel:可以使用SharePoint对象模型。
由于CAS的限制,沙盒代码能够做的事情是很有限的,比如