-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshi-yong-redisrang-shiroshi-xian-ji-qun.html
165 lines (150 loc) · 9.7 KB
/
shi-yong-redisrang-shiroshi-xian-ji-qun.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="./shi-yong-redisrang-shiroshi-xian-ji-qun.html" />
<title> 愚钝的故事 — 使用Redis让Shiro实现集群
</title>
<link rel="stylesheet" href="./theme/css/style.css">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<meta name="author" content="Jet Geng">
<meta name="description" content="在使用shiro是一个很不错的权限验证框架。我们要在一个多机同时活的结构中使用他来做权限管理。这里就牵涉到一个认证Session共享的问题。我们决定使用redis作为这个Session存储的介质。 所以在github上发现了https://github.com/alexxiyang/shiro-redis 这个项目。这个项目基本上解决了我的问题。 不过在使用的过程中也遇到了一下问题。下面一一说明。 配置中的坑 按照项目中的配置起初没有跑起来,没有跑起来的原因是session老是找不到。原因是Shiro的session id老是和系统的session id冲掉,在直接使用内存缓存的时候ok,换成了redis的时候就不行了。 所以我就根据 http://www.cnblogs.com/xguo/p/3209529.html 的提示将 shiro-redis 中的配置改成如下内容: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...">
<meta name="tags" contents="Gorm, Grails, ">
</head>
<body>
<header class="header">
<div class="container">
<div class="header-inner">
<h1 class="header-name">
<a class="nodec" href="/">愚钝的故事</a>
</h1>
<h3 class="header-text">Jet Geng的工作和生活</h3>
<ul class="header-menu list-inline">
<li><a class="nodec icon-github" href="https://github.com/jetgeng"></a></li>
</ul>
</div>
</div>
</header> <!-- /.header --> <div class="container">
<div class="post full-post">
<h1 class="post-title">
<a href="/shi-yong-redisrang-shiroshi-xian-ji-qun.html" title="Permalink to 使用Redis让Shiro实现集群">使用Redis让Shiro实现集群</a>
</h1>
<ul class="list-inline">
<li class="post-date">
<a class="text-muted" href="/shi-yong-redisrang-shiroshi-xian-ji-qun.html" title="2014-09-07T17:39:00+08:00">Sun 07 September 2014</a>
</li>
<li class="muted">·</li>
<li class="post-category">
<a href="./category/grails.html">Grails</a>
</li>
<li class="muted">·</li>
<li>
<a href="/tag/Gorm.html">Gorm</a>, <a href="/tag/Grails.html">Grails</a> </li>
<li class="muted">·</li>
<li>
<address class="post-author">
By <a href="./author/jet-geng.html">Jet Geng</a>
</address>
</li>
</ul>
<div class="post-content">
<p>在使用shiro是一个很不错的权限验证框架。我们要在一个多机同时活的结构中使用他来做权限管理。这里就牵涉到一个认证Session共享的问题。我们决定使用redis作为这个Session存储的介质。
所以在github上发现了https://github.com/alexxiyang/shiro-redis 这个项目。这个项目基本上解决了我的问题。
不过在使用的过程中也遇到了一下问题。下面一一说明。</p>
<div class="section" id="id1">
<h2>配置中的坑</h2>
<p>按照项目中的配置起初没有跑起来,没有跑起来的原因是session老是找不到。原因是Shiro的session id老是和系统的session id冲掉,在直接使用内存缓存的时候ok,换成了redis的时候就不行了。
所以我就根据 <a class="reference external" href="http://www.cnblogs.com/xguo/p/3209529.html">http://www.cnblogs.com/xguo/p/3209529.html</a> 的提示将 <a class="reference external" href="https://github.com/alexxiyang/shiro-redis">shiro-redis</a> 中的配置改成如下内容:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="nt"><bean</span> <span class="na">id=</span><span class="s">"wapsession"</span> <span class="na">class=</span><span class="s">"org.apache.shiro.web.servlet.SimpleCookie"</span><span class="nt">></span>
<span class="nt"><constructor-arg</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">value=</span><span class="s">"WAPSESSIONID"</span><span class="nt">/></span>
<span class="nt"></bean></span>
<span class="c"><!-- redisSessionDAO --></span>
<span class="nt"><bean</span> <span class="na">id=</span><span class="s">"redisSessionDAO"</span> <span class="na">class=</span><span class="s">"org.crazycake.shiro.RedisSessionDAO"</span><span class="nt">></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"redisManager"</span> <span class="na">ref=</span><span class="s">"redisManager"</span> <span class="nt">/></span>
<span class="nt"></bean></span>
<span class="c"><!-- sessionManager --></span>
<span class="nt"><bean</span> <span class="na">id=</span><span class="s">"sessionManager"</span> <span class="na">class=</span><span class="s">"org.apache.shiro.web.session.mgt.DefaultWebSessionManager"</span><span class="nt">></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"sessionDAO"</span> <span class="na">ref=</span><span class="s">"redisSessionDAO"</span> <span class="nt">/></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"sessionIdCookie"</span> <span class="na">ref=</span><span class="s">"wapsession"</span><span class="nt">/></span>
<span class="nt"></bean></span>
<span class="c"><!-- cacheManager --></span>
<span class="nt"><bean</span> <span class="na">id=</span><span class="s">"cacheManager"</span> <span class="na">class=</span><span class="s">"org.crazycake.shiro.RedisCacheManager"</span><span class="nt">></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"redisManager"</span> <span class="na">ref=</span><span class="s">"redisManager"</span> <span class="nt">/></span>
<span class="nt"></bean></span>
</pre></div>
</td></tr></table><p>这样所有问题就解决了,可以正常的在多机器的情况下登陆,登出了。</p>
</div>
<div class="section" id="id2">
<h2>性能的坑</h2>
<p>正当我高兴的时候发现前台的页面变得非常非常的慢。一次请求搞到了1~2秒,天哪这个要用户怎么可能接受,最起码我自己这儿就无法接受了。找原因去,最后发现是在一次的shiro的认证过程中 他要十几次的访问RedisSessionDAO的doReadSession方法,在doReadSession方法中直接访问redis。 也就是说在一次认证过程中,需要访问redis 十几次,在我的屌丝网络中一次访问redis是需要100ms的,十来次就是1000个ms啊。
所以我决定给这个在内存中加一个简单的缓冲,确保一次认证的过程中只是去redis取一次,最多2次就ok。所以我选用了guava中的Cache,他使用简单,无需配置,适用我这个场合。
所以就有了 pull request <a class="reference external" href="https://github.com/alexxiyang/shiro-redis/pull/3">https://github.com/alexxiyang/shiro-redis/pull/3</a> 。
这样一来,我们页面的访问速度就一下子回到了200 ~ 300 ms了。这个时间范围用户应该还是可以接受的。</p>
<p>在这里非常感谢alex 贡献了他的项目,感谢aliencode的 《Apache-Shiro+Zookeeper系统集群安全解决方案之会话管理》 一文,帮助我找到了cookie冲突的问题。
另外alex在写这篇博客的时候已经同意将我的代码合并到 <a class="reference external" href="https://github.com/alexxiyang/shiro-redis">shiro-redis</a> 分支中去。欢迎大家使用这个项目!</p>
</div>
</div>
</div>
<hr class="separator">
<div class="col-md-8 col-md-offset-2">
<div id="disqus_thread">
<script>
var disqus_shortname = 'techfoolishstory';
(function() {
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>
Please enable JavaScript to view the
<a href="https://disqus.com/?ref_noscript=techfoolishstory">
comments powered by Disqus.
</a>
</noscript>
<a href="https://disqus.com" class="dsq-brlink">
blog comments powered by <span class="logo-disqus">Disqus</span>
</a>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="text-center">
Jet Geng, <a href="" target="_blank">版权归Jet Geng所有,转载请注明!</a> unless otherwise noted.
</p>
<div class="text-center">
Generated by <a href="http://getpelican.com" target="_blank">Pelican</a> with the <a href="http://github.com/nairobilug/pelican-alchemy">alchemy</a> theme.
</div>
</div>
</footer> <!-- /.footer -->
<script src="./theme/js/jquery.min.js"></script>
<script src="./theme/js/bootstrap.min.js"></script>
</body> <!-- 42 -->
</html>