| JohnBull 回复于:2003-04-03 14:08:10
|
[quote:4e7066cac8="chdonald"]COOKIE机制不是太好,因为客户端情况变化太大。我以前所实现的是用URL带BASE64编码的SESSIONID信息来表明用户的SESSION ID,并且在主机里专门实现一个小型SESSION POOL。用于匹配用户的SESSION ID的其他关键信息,当..........[/quote:4e7066cac8]
没问题,我的cookie存根是放在数据库里的,与用户名和客户的IP相关联,均衡也不怕。用户注销后删除。
|
| JohnBull 回复于:2003-04-02 20:48:44
|
用户一旦登陆成功,cgi就生成一个随机字符串,本地留一个存根后以cookie的形式发给浏览器。在需要session操作的时候,检查浏览器发回的cookie本地是否有存根,就知道他有没有登陆了。
发送cookie的方法是在Content-type声明之前:
printf("Send-cookie: var=随机串; expires=xxxxxxxx; server=xxxxxx; path=xxxxxxx; secure\n");
(expires,server,path分别是有效期、域名、url,secure是说明是否要在https连接时向服务器返回cookie。)
接受cookie很简单,读取环境变量即可:
strcpy(xxx,getenv("HTTPD_COOKIE"));
(好像是这个变量名,不行的话自己去网上查查)
然后自己写个字符串处理函数,分解出需要的变量值即可。
|
| ccrazy 回复于:2003-04-03 09:47:40
|
十分感谢!我试试看!!!
|
| ccrazy 回复于:2003-04-03 09:59:48
|
对了,请问这个随机串是什么?是否就是登陆名?能否举例说明一下?由于从来没用c写过cgi,还请多指教,谢谢!!!
|
| chdonald 回复于:2003-04-03 13:47:49
|
COOKIE机制不是太好,因为客户端情况变化太大。我以前所实现的是用URL带BASE64编码的SESSIONID信息来表明用户的SESSION ID,并且在主机里专门实现一个小型SESSION POOL。用于匹配用户的SESSION ID的其他关键信息,当然这种存放要考虑安全性,我用的是DBM库加密方式。
实现SESSION还要考虑一种情况:是单机还是多机的负载均衡,如过用了负载均衡设备,还要考虑得更周到一些
|
| JohnBull 回复于:2003-04-03 14:01:43
|
[quote:cdb43a64b5="ccrazy"]对了,请问这个随机串是什么?是否就是登陆名?能否举例说明一下?由于从来没用c写过cgi,还请多指教,谢谢!!![/quote:cdb43a64b5]
必须是看上去毫无意义的字串,否则不安全。可以通过/dev/urandom生成,也可以通过crypt()计算出用户名+客户IP+连接时间戳的md5散列来生成。
|
| gadfly 回复于:2003-04-03 14:27:35
|
用C实现Session机制确实比较麻烦, 必须在本地,或数据库中缓存SESSION数据. 还是Servlet方便,直接放在内存中
|
| JohnBull 回复于:2003-04-04 13:27:45
|
[quote:a2921959e4="gadfly"]用C实现Session机制确实比较麻烦, 必须在本地,或数据库中缓存SESSION数据. 还是Servlet方便,直接放在内存中[/quote:a2921959e4]
C语言也可以利用共享内存的方法把存根放在内存里,之所以不这样做是为了解决上面chdonald提到的负载均衡问题。
你用servlet是怎么解决负载均衡的?
|
| gadfly 回复于:2003-04-04 15:08:33
|
我的意思是,如果用servlet并不用直接管理session数据,而是由servlet container自动完成管理。你如果用c 实现CGI,将session数据存入共享内存,用户总得在服务端实现这些数据的内存管理。
至于动态均衡,有种算法,是将最近访问过的ip,还是分配到以前的服务器。这可以解决这个问题,不过这是依赖于load balance,与实现无关了。
还有一些方法:
1 記憶體處理
當某台 J2EE Server 中的某個 HttpSession 有新增某個 Object 進去的時候,或是當這個 HttpSession 的某個 Object 被修改之後,這台 J2EE Server 可以利用 IP Broadcast 的方式,或是 TCP/Socket 的方式,將 Object 傳遞到其它備份的 J2EE Server 上,讓其他 J2EE Server 上相關的 HttpSession 也跟著變化。
2 由一台資料庫或是檔案系統記錄
這種方式是讓 HttpSession 內的資料,固定寫入到一台資料庫去,或是這幾台要作 Cluster 的 J2EE Server 共用一塊硬碟區,將資料固定寫入該硬碟區塊,如此一來,某台 J2EE Server 發生問題時, Session 的資料一樣還在。
3 集中式處理
所謂集中式的處理,與記憶體處理方式非常類似,但是 HttpSession 的資 料並不是送到多台機器上,而是被送到某台特定的機器上,當然,當另外一台機器要取得 Session 的資料的時候,也可以透過這台機器來存取!
以上1依赖于j2ee server, 2实际上存数据库的方法。3感觉上不可行,有单点
故障问题。
|
| JohnBull 回复于:2003-04-07 21:09:20
|
[quote:cb78634292="gadfly"]我的意思是,如果用servlet并不用直接管理session数据,而是由servlet container自动完成管理。你如果用c 实现CGI,将session数据存入共享内存,用户总得在服务端实现这些数据的内存管理。
至于动态均衡,有种算?.........[/quote:cb78634292]
1、 对于C程序员来说,在程序中做这么一点点内存管理并不难。急了眼的话,大不了我写一个session服务器,通过udp端口提供服务。
2、 关于load balance,你说到的均衡算法叫做“源地址散列”,是浩如烟海的均衡算法中的一种。较常用的(加权)RR、(加权)最小连接、负载检测等算法并不能保证你提出的要求。他们只能是保证每[b:cb78634292]一[/b:cb78634292]个连接所发生的数据包流向相同的服务器。且不说就算使用源地址散列,尚存在为了增加随机性而需要定期(数十秒)更换散列算法的问题了。
3、 你找来的3种方法可以解决问题,但是1太麻烦,至少比“在服务端实现这些数据的内存管理”麻烦得多;2其实就是我说的方法——利用数据库(数据库本身也可以集群,解决单点故障)。
|
| gadfly 回复于:2003-04-08 00:42:49
|
1. 我的意思不就是麻烦,servlet的开发效率高么,没说难度亚。无论如何,增加了程序员的开发复杂度这句话总没错。且不说你session server本身的单点故障的解决和服务效率问题。
2.我不知道浩如烟海是什么意思。你的知识很渊博,我很佩服,不过恕我直言,也许是我孤陋寡闻,我知道的实际产品中使用的也就这么几种。而且,一般来说,load balance的均衡算法可以根据用户的需求配置,并不是说随机的,机器自动想用哪种就用哪种。实际中我们也做过这种项目,就是按我说的这种算法均衡负载的。呵呵,上面我也说的很明确,用这种算法来解决问题。
3.呵呵,由底层平台来解决问题,对开发人员来说,能比程序来完成更复杂?我觉得有些时候,更可依赖的是平台。我承认程序确实无所不能,但是有的时候用你得综合考虑,考虑开发时间,可维护性,开发的效率,代码和系统的复杂度等等,而不是编码的可行性。
上面方式2是数据库方式,我也承认了,呵呵,确实和你说的方案一样。
我觉得有的时候得考虑实际的项目方案可行性,开发进度和效率,而不是理论上的可行性。就像你说的算法浩如烟海,可是实际产品采用的就那么几种。
当然研究另当除外。
|
| chdonald 回复于:2003-04-08 07:53:23
|
两位都提到了LOAD BALANCE,我觉得看具体的实现.如果是分布式的机器不共享SESS POOL,如只用本地文件实现SESS POOL的话,最简单地就是利用CLIENT直接发送原来在一个SESSION中访问过的那台主机,保持一个完整的会话.如果是利用了共享的方式,如NFS,DB,或者其他网络的实现,这时候CLI就可以向VIP直接发送请求了,不过至于什么最少连接数算法,RR循环算法,等,其实都是有这种产品在前面实现负载均衡的,如硬件负载均衡交换机,软件我没用过.这就不是我应用实现的范围里了.
|