曾想自己做个远程方法调用,今晚心血来潮,从9点左右开始,大概做了2.5小时。 一个小小的远程方法调用框架出来了。调试顺利通过, 欣喜ing:) 关键点 1)客户端动态代理,截取方法代理远程调用。 2)服务端有线程服务就OK 考虑性能问题 1)使用对象池,作无状态使用。(测试中使用对象池反而比较慢,可能并发数不够,至少有一点可以保证--节省服务器内存开销) 2)服务端已知道需要调用的方法,故无需再动态代理,也直接可以实现AOP。 3)createRemoteInstance时,不连接服务器(本框架也不需要),只创建本地stub代理对象。 测试代码: ISingle is=(ISingle)StubFactory.createRemoteInstance(ISingle.class); String name=is.getName(tag); System.out.println(name); 输出结果: 【客户端】 #6A75 Hello, my darling. #5A37 Hello, my darling. #1A90 Hello, my darling. #7A28 Hello, my darling. #2A11 Hello, my darling. #4A93 Hello, my darling. #8A3 Hello, my darling. #3A44 Hello, my darling. #9A37 Hello, my darling. 【服务端】 Running tcp services at 999 ... accetpSocket[addr=/127.0.0.1,port=1942,localport=999] accetpSocket[addr=/127.0.0.1,port=1943,localport=999] accetpSocket[addr=/127.0.0.1,port=1941,localport=999] accetpSocket[addr=/127.0.0.1,port=1937,localport=999] accetpSocket[addr=/127.0.0.1,port=1938,localport=999] accetpSocket[addr=/127.0.0.1,port=1940,localport=999] accetpSocket[addr=/127.0.0.1,port=1939,localport=999] accetpSocket[addr=/127.0.0.1,port=1935,localport=999] accetpSocket[addr=/127.0.0.1,port=1936,localport=999] 比较粗糙,使用中逐步去完善,比如加入日志,权限。--本着轻量“短平快”的宗旨。
继续: 增加上下文传递,用ThreadLocal保存上下文变量。 这里不想增加session层,因为用作c/s结构的远程方法调用,需要构建的系统不是特别复杂,无需使用有状态的会话。另外一个原因,扩展为有状态会话也不难,就是服务对象增加客户的(连接)标识并处理请求(锁碎的事),服务对象也就是一个普通bean,放入对象池里。 无状态bean有个很大的好处, 1)无需考虑session 2)每个bean class只有一个实例,不论有多少请求,开相应的Thread即可。上下文应该是有session的概念,这里的上下文概念不同,是客户端传过来的(服务端无---无状态,也不保留登连接用户任何信息),这些数据必要,但是又不方便给方法里添加这个参数,比如用户ID。使用ThreadLocal管理是个绝妙的方法。