- 主题:服务器动态模块热插拔管理
一个服务器系统,承担着大量的客户业务,当服务模块业务变更时,通常需要停止服务升级系统。
如何建立动态热插拔的模块更换,使得服务器在不影响业务运行时升级功能,这里提供一种方法。
例子是在linux环境,用.so实现。WINDOS用DLL实现也是一样的。
建立两个库目录,一个运行库目录库,一个就绪库目录。
在客户端请求调用某个模块时,服务器在运行库目录中寻找模块并加载到内存。使用完毕驻留。
每个客户端进来使用这个模块,引用计数+1,使用完毕引用计数-1.
当需要更换模块时,先把新模块放到就绪库目录。
然后管理者向服务器发一个更换某模块的指令。这个指令导致运行时目录里的该模块被移动到备份库,以便降级回滚。新模块拷贝到运行库目录。
然后等待引用计数归零。
归零后,从内存中删除该模块。
原理很简单,麻烦的是各种环节的各种锁。
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
【 在 ylh1969 的大作中提到: 】
: 一个服务器系统,承担着大量的客户业务,当服务模块业务变更时,通常需要停止服务升级系统。
: 如何建立动态热插拔的模块更换,使得服务器在不影响业务运行时升级功能,这里提供一种方法。
: 例子是在linux环境,用.so实现。WINDOS用DLL实现也是一样的。
: ...................
/******************************************************
* 动态模块的应用服务入口,app层
* json="{model:"modelname",param:{....}}"
* model是调用的so名字
* param是提交给模块的数据
******************************************************/
。。。。。。。。。。
nodep=(cmd_node *)trp->Content;
pthread_mutex_lock(&nodep->mut);
nodep->lock++; //引用计数
pthread_mutex_unlock(&nodep->mut);
}
pthread_rwlock_unlock(&dmlock);
if(nodep->cmd) {
result=nodep->cmd(srvp,json_object_object_get(json,"param"),err_json);//执行,支持多线程协程,没有线程锁。
pthread_mutex_lock(&nodep->mut);
nodep->lock--;// 引用计数
pthread_mutex_unlock(&nodep->mut);
if(nodep->lock==0) pthread_cond_signal(&nodep->cond);//通知管理模块可以更换了。
}
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
【 在 ylh1969 的大作中提到: 】
: /******************************************************
: * 动态模块的应用服务入口,app层
: * json="{model:"modelname",param:{....}}"
: ...................
管理模块:
pthread_mutex_lock(&nodep->mut);
while(nodep->lock>0) {
pthread_cond_wait(&nodep->cond,&nodep->mut);
}
pthread_mutex_unlock(&nodep->mut);
if(nodep->destruct) nodep->destruct(srvp);
do {
ret=dlclose(nodep->handle);
} while(ret>0);
cmd_tree=BB_Tree_Del(cmd_tree,nodep,sizeof(node),cmd_cmp,NULL,&flg);//从内存中删除该模块
pthread_rwlock_unlock(&dmlock);
--
FROM 221.218.60.*