`
阿尔萨斯
  • 浏览: 4185344 次
社区版块
存档分类
最新评论

memcached与cookie结合使用实例

 
阅读更多

最近重点关注了memcached和cookie的相关技术,这些技术在web开发中使用的相当频繁,alibaba也不例外。

cookie的场景:由于http协议本身是无状态的,两次http请求毫无关联,总不能每次登录都让用户重新输入用户名和密码,重新验证一次,也许很多人说可以在服务端建立sesseion,的确这是一个不错的选择,session具有独享性,存储的是单个用户的信息,每个浏览器的多次请求都会维护服务端的一个session。但是服务端有如此多的session,怎样将其与请求匹配?这时cookie里面的jsessionid便发挥了作用,通过sessionid可以唯一的区分服务端的session信息。

当然cookie的作用可远不止这个,cookie更多的是在客户端存储用户的信息,每次会随着客户端请求发送到服务器端,使用场景如“自动登录”等

memcached的场景:缓存的作用位置是在内存,虽然大多数数据是存储在数据库、文件系统等,单次读取的速率差异并不是特别明显(让用户无法接受),但是如果面对多用户访问,如此多的并发请求,基数一大,差异便会特别明显。解决这种问题的最好方式便是借助缓存,将大量的跨表甚至跨库的记录整合封装,临时存于内存中,下次使用时可直接读取,大大提高了数据的交互速率。

结合这两种技术,写了一个demo应用,领域下缓存的神奇。

结构类图:

表单提交时

读取服务端创建的session的sessionid

 // 组建sessionId
 String sid = request.getSession().getId() + "_" + Constants.serverName + "_" + person.getUserId();

存储cookie信息,其中的value是组建的sessionid

RequestUtils.setCookie(request, response, Constants.session_key_flag_of_cookie, sid, 30 * 60);
/**
	 * 设置COOKIE
	 * @param request
	 * @param response
	 * @param name
	 * @param value
	 * @param maxAge
	 */
	public static void setCookie(HttpServletRequest request, HttpServletResponse response, String name,
			String value, int maxAge) 
	{
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(maxAge);
		if(cookieDomain!=null && cookieDomain.indexOf('.')!=-1)
		{
			cookie.setDomain('.' + cookieDomain);
		}
		cookie.setPath(cookiePath);
		response.addCookie(cookie);
	}

缓存中放入的是一个map对象,该对象封装当前的session会话的key-value键值对

session的服务类,里面会初始化memcached的客户端

private SessionService() 
	{
		ClassLoader cl = Thread.currentThread().getContextClassLoader();
		InputStream input = cl.getResourceAsStream("memcached.properties");
		Properties props = new Properties();
		String serverlist = "127.0.0.1:11211";
		try 
		{
			props.load(input);
			serverlist = props.getProperty("serverlist", "127.0.0.1:11211");
			poolName = props.getProperty("poolname", "sidsock");

		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}

		String[] servers = serverlist.split(",");
		pool = SockIOPool.getInstance(poolName);
		pool.setServers(servers);
		pool.setFailover(true);
		pool.setInitConn(10);
		pool.setMinConn(5);
		pool.setMaxConn(250);
		pool.setMaintSleep(30);
		pool.setNagle(false);
		pool.setSocketTO(3000);
		pool.setAliveCheck(true);
		pool.initialize();
	}

缓存信息的存操作

public void saveSession(String id, Map session) 
	{
		MemCachedClient mc = this.getMemCachedClient();
		if(mc.keyExists(id))
		{
			mc.replace(id, session,getExpiryDate());
		}
		else
		{
			mc.add(id, session,getExpiryDate());
		}
	}

memcached的取数据操作

public Map getSession(String id,boolean create) 
	{
		MemCachedClient mc = this.getMemCachedClient();
		
		Map session = (Map) mc.get(id);
		if(session == null)
		{
			if(create)
			{
				session = new HashMap(5);
				mc.add(id, session,getExpiryDate());
			}
		}
		return session;
	}

返回值是一个map对象,会封装到MemSession对象的map 全局变量中,供后面的操作使用

public class MemSession
{
	//session会话 ID
	private String sid = "";

	//存放本会话的所有信息
	private Map map = null;
		
	public static MemSession getSession(String sid)
	{
		MemSession session = null;
		
		session = new MemSession(sid,true);
		
		return session;
	} 

补充:关于一个web工程的创建 及启动,http://hi.baidu.com/paper369/blog/item/afae7939886d7d38b9998f46.html

代码地址:https://mymemcached-cookie.googlecode.com/svn/trunk/


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics