系统大概的流程如下:从数据中心接收到数据包(1万~3万(个)/秒,使用WCF)可以被不同的应用场景使 用,每个应用场景的业务逻辑各不相同,而每个场景的接收数据包部分的代码是相同的,于是使用一个容 器将所有的"应用场景的dll"通过反射加载,同时容器接收所有的数据包并把他们分发给"应用场景的dll" ,接收数据的功能,自然被抽象成了Interface。透彻一点讲就是一个插件系统,只不过这个插件有点儿 大而已,大到整个系统都是个插件。这个容器我们暂时叫他“引擎”,而这个"场景的dll"我们暂且叫他 “规则”。
我的理想做法是:每一个规则(一个或多个dll)都单独放在一个文件夹下面,并且有自己的配置文件 。当引擎启动的时候,根据引擎的配置为每个规则创建一个新的AppDomain,并且还为该AppDomain设置配 置文件,同时让这个新的AppDomain加载相对应的dll。引擎的CurrentDomain里面保存着每个规则的 MarshalByRefObject,当引擎接收到数据的时候,就把这些数据根据一些条件分发到相对应的规则当中。 俄,引擎看起来有点像一个IIS啊!!!
等等,这么美妙的想法,这么容易就可以实现?! 我是不是忘记了什么??哦 我忘记了那些规则的 MarshalByRefObject每秒钟是否能承受1万~3万次的调用(这里的调用就是传递数据包)。
[下午系统测试得时候,性能技术器显示每秒钟仅仅2千个左右的包被处理,剩下的都丢了。。。。。 。疯狂的郁闷中]
自从上次net技术大会回来,每天都挺忙,好多讲课还没来得及回味,看到老赵和eaglet都CodeTimer 了,惭愧啊,不过刚好拿过来用吧。测试代码如下:
1。FunA() FunB() FunC() FunD() 为测试代码,class RemoterProxy是为了创建远程对象更容易一些 ,不是Proxy模式哦。
1namespace AppDomainPerformanceDemo
2{
3 class Program
4 {
5 const int COUNT = 500000;
6
7 static void Main( string[] args )
8 {
9 FunA();
10 FunB();
11 FunC();
12 FunD();
13
14 Console.ReadLine();
15 }
16
17
18 static void FunC()
19 {
20 RemoterProxy remoterProxy = new RemoterProxy();
21 CodeTimer.Time( "RemoterProxy: Same AppDomain", COUNT, remoterProxy.FunTest );
22 }
23
24 static void FunD()
25 {
26 AppDomain domain = AppDomain.CreateDomain( "NewAppDomain" );
27 RemoterProxy remoterProxy = (RemoterProxy) domain.CreateInstanceAndUnwrap( Assembly.GetExecutingAssembly().FullName, "AppDomainPerformanceDemo.RemoterProxy" ); ;
28 CodeTimer.Time( "RemoterProxy: Across AppDomain", COUNT, remoterProxy.FunTest );
29 AppDomain.Unload( domain );
30 }
31
32 static void FunB()
33 {
34 IInterface inter = new ImplementA();
35 CodeTimer.Time( "ImplementA: Same AppDomain", COUNT, inter.FunA );
36 }
37
38 static void FunA()
39 {
40 AppDomain domain = AppDomain.CreateDomain( "NewAppDomain" );
41 RemoterProxy remoterProxy = (RemoterProxy) domain.CreateInstanceAndUnwrap( Assembly.GetExecutingAssembly().FullName, "AppDomainPerformanceDemo.RemoterProxy" );;
42 IInterface inter = remoterProxy.CreateInstance( "AppDomainPerformanceDemo.ImplementA", "MyImplement", BindingFlags.CreateInstance, null );
43 CodeTimer.Time( "ImplementA: Across AppDomain", COUNT, inter.FunA );
44 AppDomain.Unload( domain );
45
46 }
47 }
48
49 public class RemoterProxy : MarshalByRefObject
50 {
51 public IInterface CreateInstance( string typeName, string assemblyName, BindingFlags bindingFlags, object[] constructorParams )
52 {
53 Assembly owningAssembly = Assembly.Load( assemblyName );
54
55 IInterface instanceHandler = owningAssembly.CreateInstance( typeName) as IInterface;//, false, bindingFlags, null, constructorParams, null, null ) as IInterface;
56
57 return instanceHandler;
58 }
59
60 public void FunTest()
61 {
62 }
63 }
64
65
66}
67