最近因为网站要支持nginx的动态负载均衡,因此要去掉cppcms内置的session机制。就顺便研究了一下cppcms的application。
准确的讲,研究的是application类的子类的生命周期. 按照cppcms的规则,我们必须自己从application继承出自己的类,比如MyApp, 逻辑上,这个类的对象会被缓存到application pool中,代表了一个应用程序。
cppcms的设计支持多个application运行在一起,也就是通过http://domain:port/(具有相同的domain和端口)能够访问到多个web apps。
想法很大,不过我用不着多个应用在一个进程里面运行,真要是有多个应用,我肯定会放在不同的进程里面使用,进程隔离,会比较安全。防止一个web app写得不好,crash导致其他app也完蛋。 虽然多个application运行在不同的进程,意味着监听了各自的端口,访问的时候可能URI不一致,不过前面加上Nginx就可以将之统一起来。
既然MyApp代表一个web application,因此它的对象就只能有一个,构造函数也只能被调用一次,默认情况下,经过测试,是在第一次web请求到达的时候被创建出来的。
MyApp可以改写继承來自application的虚函数init,这个函数当每次web请求到来都会被调用。
注意
1.如果有全局的数据,现在可以放在MyApp里面作为成员变量. 不过如果涉及到既读又写的话,还是应该使用线程同步操作保证多线程安全。
因为通过日志打印线程ID,可以证明的确是多线程调用MyApp的方法。试验代码写在init函数中:
void MyApp::init() { thread::id current_thread_id = boost::this_thread::get_id(); BOOSTER_NOTICE("MyApp) << "enter init" << " thread id:" << current_thread_id; }
2.为了打造一个stateless的restful web app, 不要将session等数据保存在MyApp的成员变量中。可以写到真正的session server中,或者简化起见,直接写到mongodb中。以后每次再通过key读出来。key存放在客户端的cookie中,当用户登录验证通过后,可以通过调用继承自application::response().set_cookie 函数来将自己生成的key保存在cookie中,然后返回到浏览器端,浏览器可以将cookie保存起来。
请看例子代码:
cookie c("my_session", user->oid, 36000, "/"); response().set_cookie(c);多线程模型还未深究,目前只知道cppcms内部使用了线程池。