- 浏览: 160925 次
- 来自: ...
文章分类
- 全部博客 (151)
- Liferay.in.Action (3)
- 集群 (12)
- web (5)
- jna (2)
- 数据库 (7)
- Terracotta (11)
- xml (1)
- Hibernate (3)
- Jdbc (2)
- DDD (10)
- nosql (7)
- 云存储 (3)
- 云产品 (7)
- 云计算 (26)
- Hadoop (11)
- 虚拟化 (5)
- REST (3)
- 程序人生 (11)
- google (2)
- 安全应用 (5)
- LDAP (0)
- 安全技术 (5)
- android (4)
- 网络妙语 (1)
- HTML5 (1)
- 搜索引擎 (1)
- 架构设计 (5)
- redis (3)
- Cassandra (2)
最新评论
-
liwanfeng:
情况是这样的,你的文件我觉得还是比较小,我现在需要处理的XML ...
dom4j处理大文件
原文 http://www.jdon.com/jivejdon/thread/39106
Clustering Cloud-friendly Tomcat Sessions with RabbitMQ: Part I | TomcatExpert
云架构的流行,使得水平伸缩成为王者( horizontal scalability is king),而传统的Tomcat集群是通过广播集群
,也就是让一台机器上的Session广播到其他机器上,这样的坏处就是大量Session中数据在服务器之间不停被复制拷贝,增加服务器负担,服务器越多,复制越厉害,Tomcat的服务器也就不能无限任意增加,水平伸缩很差。
该文作者通过引入RabbitMQ消息系统,用来控制tomcat的Session无限复制,也就是设计一种Session管理器:使得任何一个用户请求都可以被随机分配到任何一台tomcat服务器上。
作者对Session管理器要求是:
1.轻量,Terracotta虽然号称可以帮助session复制,可惜重量。作者没有选择。
2.Reliable 可靠
3.Scalable 可伸缩
4.No single point of failure 无单点风险
5.Asynchronous (for speed and efficiency) 异步
6.Easy to configure易于配置
7.Zero (or nearly so) maintenance 零维护。
Session管理器的工作原理如下:当一个tomcat服务器被要求加载用户的session, 它首先将session的ID传到云存储中CloudStore(使用 Redis 或其他 NoSQL
数据库), 检查内部的session ID列表. 如果发现存在这个ID,
就知道这是一个已经激活的session,然后检查内部Map看看其是否已经存在当前服务器本地了,如果没有,发出"load"消息给相应队列
queue. 当前用户请求的线程就堵塞等待Session在本地加载复制。
[该贴被banq于2010-06-22 10:55修改过]
Clustering Cloud-friendly Tomcat Sessions with RabbitMQ: Part I
posted by jbrisbin on June 21, 2010 07:11 AM
The existing solutions for Tomcat session clustering are viable for moderate clusters and straightforward failover in traditional deployments. Several are well developed with a mature code-base, such as Apache's own multicast clustering . But there's no getting around the fact that today's cloud architectures place new and different expectations on Tomcat that didn't exist several years ago when those solutions were being written. In cloud architectures, where horizontal scalability is king, a dozen or more Tomcat instances is not unusual.
In my hybrid, private cloud, first described in my earlier post on keeping track of the availability and states of services across the cloud , I wanted to fully leverage all my running Tomcat instances on every user request. I didn't want to use sticky sessions as I wanted each request (including AJAX requests on a page) to be routed to a different application server. This is how virtual machines work at a fundamental level. Increased throughput is obtained by parallelizing as much of the work as possible and utilizing more of the available resources. I wanted the same thing for my dynamic pages. Not finding a solution in the wild, I resolved to roll my own session manager. The result is the "vcloud" (or virtual cloud) session manager. I've Apache-licensed the source code and put it on GitHub--mostly to try and elicit free help to make it better. You can find the source code here: http://github.com/jbrisbin/vcloud/tree/master/session-manager/
The Dilemma
I dug into the code of the available session managers and found they simply would not do what I was asking them to do. My expectations were (and are) quite high. I was looking for something that was, simultaneously:
- Lightweight (sorry Terracotta)
- Reliable
- Scalable
- No single point of failure
- Asynchronous (for speed and efficiency)
- Easy to configure
- Zero (or nearly so) maintenance
I don't have to give the standard session managers a second thought when deploying a web application onto Tomcat. I wanted the same out of any other session manager. I also didn't want user sessions "copied" throughout the network all the time. I use lots of little Tomcat instances that have small heap sizes. If there was any way around it, I didn't want to keep entire copies of every active session in every server. But if I wanted the session loaded on demand, I'd need something screamingly fast. I use a cluster of RabbitMQ servers internally, so it only made sense to leverage that great asynchronous message broker to solve this problem.
Ideally, a user session would always be available in-memory. This is the fastest possible way to serve the user request. But it's inherently limiting. What if a new server comes online? Or, why keep precious resources locked up caching user sessions if that application server never sees that user?
The Trade-Off
Ain't that just life? Always having to trade one good thing for something else that you hope will really be better. Having user sessions available on-demand in any server that needs them is definitely trading off the speed of having a user session in-memory with the flexibility of not knowing (or caring) where that session object comes from. But realistically, it's only trading off the time it takes to handle the bytes that make up the object going from one server to the next. Since all my servers are connected by either a VMware virtual switch (because they're running on the same host) or are directly connected to our core Cisco gigabit switch; and because the only object stored in those user sessions is a Spring Security user object, I felt okay taking that hit on page load time if it meant I could load-balance all my servers, all the time.
The Method Behind the Madness
As a Java programmer, I found myself doing what nearly every Java programmer alive does: I tried to complicate things by adding to the code all kinds of stuff I didn't need. It took me a while to filter that out but I eventually settled on only the components that are actually required: a fast, thread-safe list of session IDs that are currently active in the cloud, and a convention of subscribing and publishing standard messages to queues with names that include the session ID.
The Process (at 30,000 feet)
When a Tomcat server is asked to load a user session, it passes that ID into the CloudStore, which checks the internal list of session IDs. If it finds that ID listed there, it knows it has an active session and checks the internal Map to see if that session is actually local to the application server. If it's not, it publishes a "load" message to the appropriate queue. The thread is then blocked for a configurable amount of time until it's either got the loaded session or it times out and assumes the session is no longer valid (maybe because the server that had it in-memory crashed).
As a somewhat-related aside: the Tomcat server doesn't know what's on the other end of that queue. It could be another Tomcat server that has that session in its internal Map. It could also be a dedicated session replicator written in Ruby and backed by a Redis (or other NoSQL) store. Going the other direction: code running in standalone mode, like a system utility, could load the session object that was created when a user logged into your initial web application, exposing a single user object to any Java code running anywhere in your cloud. Pretty cool, huh? ;)
When the server responsible for that session gets this load message, it serializes the session it has in-memory and sends those bytes back to the sender. The sender's listener gets this "update" message and checks to see if any loaders are waiting on this session. If it finds one, it gives the deserialized session to the loader, who, in turn, passes the session back to Tomcat, who continues to serve the page.
The Code (at 1,000 feet)
We won't have time in just one article to cover the important parts of the CloudStore. In my next article, I'll discuss the "load" and "update" event handlers in detail as well as issue the obligatory caveats and acknowledge the known shortcomings. But to start with, let's take a quick peek at the event dispatcher, which is the backbone of the CloudStore session manager.
There are several different programming models when writing asynchronous applications. There's no one way to tackle the problem, so it often comes down to simply personal taste. I can get my mind around the dispatching model more easily than some of the alternatives, so that's the route I chose. Fundamentally, the dispatcher has a custom EventListener class that runs in a separate thread which is responsible for pulling messages off the queue, interrogating them, and dispatching them to the appropriate handler based on their type. There is a message type for every action the CloudStore performs.
- A touch message adds that session ID to the master list, which marks it as a valid session throughout the cloud. One of these is emitted whenever a new session is first saved by the session manager.
- A destroy message not only deletes the session object from the internal Map, it unbinds the queue for that ID. These are emitted by the store when the session has expired or is otherwise invalidated.
- A setattr message contains incoming changes made to the session while it was on the remote server. These changes have to be replicated to the real session object in the internal Map. One of these is emitted by the session whenever the "setAttribute" method is called with a different object than what the attribute is currently set to.
- A delattr message is emitted whenever the session's "removeAttribute" method is called. Its handler removes the attribute from the real session object.
Almost without exception, I dispatch EventHandlers into separate threads to do the actual work requested by the incoming message. I do this because I have only one QueueingConsumer per queue. I want as much throughput as possible, so the thread that pulls messages off the queue can very quickly get back to doing what it's supposed to concentrate on: processing messages as quickly as possible. Because I'm using the official RabbitMQ Java client , I have to do this in a separate thread so I can publish messages, bind and unbind queues, and perform other operations that require communicating back to a RabbitMQ server; otherwise, those operations would cause a deadlock if I tried to do them in the EventListener's thread.
The Teaser
The other event message types ("load" and "update") get emitted whenever the session manager attempts to load a session or when the server that has the actual object in memory responds to that load message, respectively. I'll cover those in my next article.
Jon Brisbin is an Architect/Analyst/Java Guru at NPC International, the world's largest Pizza Hut franchisee. He's been deploying web applications on Tomcat for over 10 years and currently focuses on cloud computing (virtual, hybrid, and private). He built a private cloud from scratch using VMware ESX, Ubuntu Linux, packing tape, and rusty baling wire. He's done consulting work with industry leaders and Mom-and-Pops alike. Prior to NPC, Jon developed new application frameworks, integrated the AS/400 with UNIX and Windows systems, developed Lotus Domino applications, hacked websites together with Perl CGI and a text editor, and served with US Air Force Intelligence in a very hot and sandy, but undisclosed, location. He lives in the rural Midwest.
He blogs on Web 2.0 (and sundry topics) on his website: http://jbrisbin.com/web2
发表评论
-
Cassandra 分布式数据库详解,第 1 部分:配置、启动与集群
2012-08-01 11:13 935原文 http://www.ibm.com/devel ... -
Cassandra 分布式数据库详解,第 2 部分:数据结构与数据读写
2012-08-01 11:11 936原文 http://www.ibm.com/develope ... -
让 WordPress 使用 Redis 缓存来进行加速
2012-08-01 11:00 976原文 http://www.oschina.net/quest ... -
Linux 下 Redis 安装详解
2012-08-01 10:54 862原文 http://www.oschina.net/qu ... -
Redis作者:深度剖析Redis持久化
2012-08-01 10:37 871原文 http://www.iteye.com ... -
华为称IT业五年内面临变革 云计算列入核心战略
2012-07-31 10:32 0原文 http://www.hadoopor.com/ ... -
Hadoop分布式文件系统:架构和设计要点
2012-07-31 10:07 794摘自 http://www.blogjava.net/ ... -
淘宝数据魔方技术架构解析
2012-07-31 10:09 778原文 http://www.programmer.com.c ... -
Apache Hadoop 2.0 Alpha 版发布
2012-07-30 16:10 1886原文 http://www.iteye.com/news/25 ... -
MongoDB Hadoop Connector 1.0 正式版发布
2012-07-30 16:01 916原文 http://www.iteye.com/news/24 ... -
VMware发布开源项目Serengeti,支持云中部署Apache Hadoop
2012-07-30 15:55 806原文 http://www.iteye.com/news/25 ... -
安全第一!VMware云安全八项新举措
2012-07-30 16:03 929云与安全,就这 ... -
EMC与VMware和Intel联手云安全
2012-07-28 14:05 698原文 http://security.zdnet.com.cn ... -
剖析开源云
2012-07-28 13:11 686原文 http://www.oschina.net/q ... -
怎样部署基于Spring与数据库的应用到CloudFoundry
2012-07-26 15:16 803原文 http://www.oschina.net/q ... -
深度剖析CloudFoundry的架构设计
2012-07-26 15:17 779原文 http://qing.weibo.com/22 ... -
Cloud Foundry——Azure杀手?
2012-07-25 09:54 1049原文 http://cloud.csdn.net/a/ ... -
业界首个开放式云服务平台Cloud Foundry
2012-07-25 09:52 998原文 http://sd.csdn.net/a/201 ... -
Jdon关于云的文章
2012-07-23 11:48 867云计算 著名的 ... -
盘点Chrome 8的八大新功能 硬件加速与新技术
2010-11-09 21:59 1227原文 http://os.51cto.com/art/ ...
相关推荐
Nginx Redis Rabbitmq Tomcat全套安装包.zip(Linux),内含pcre-8.36.tar.gz、openssl-1.0.1c.tar.gz、nginx-1.8.1.tar.gz、redis-3.2.0.tar.gz、rabbitmq-server-3.5.7-1.noarch.rpm、apache-tomcat-7.0.57.tar.gz...
【标题】:“TP6使用RabbitMQ” 在PHP框架ThinkPHP6(简称TP6)中集成RabbitMQ是一项常见的任务,用于实现异步处理、消息队列和分布式系统的通信。RabbitMQ是一个开源的消息代理和队列服务器,它遵循AMQP(Advanced...
MySQL、Redis、MongoDB、RabbitMQ、Tomcat、NGNIX和Docker工具的Docker安装
在IT行业中,软件开发与运维过程中常常涉及到多个关键组件的部署和配置,这些组件包括Java开发环境(JDK)、Web服务器(Tomcat)、数据库(MySQL)以及消息队列(RabbitMQ)。本教程集合了这些核心组件的安装、启动...
本文将详细介绍如何在C++和QT环境下集成并使用RabbitMQ,以便于开发者构建实时通信和高并发的应用。 首先,安装RabbitMQ需要在系统上设置Erlang环境,因为RabbitMQ是用Erlang语言编写的。确保已下载并安装了Erlang ...
本示例将详细介绍如何使用RabbitMQ来避免超卖问题。 首先,RabbitMQ是一个开源的消息代理和队列服务器,它遵循AMQP(Advanced Message Queuing Protocol)协议,能够提供可靠且灵活的消息传递服务。在处理超卖问题...
它支持分支、合并操作,使得多人协作变得简单,是现代软件开发的标准工具。 **Postman** 是一款强大的API开发和测试工具,支持创建、组织和分享API请求,进行接口测试,生成文档,以及团队协作。它是开发者调试API...
本篇文章将深入探讨如何在Beego框架下封装并使用RabbitMQ,以实现高效、可靠的通信。 首先,我们要了解RabbitMQ。RabbitMQ是一款开源的消息代理和队列服务器,它基于AMQP(Advanced Message Queuing Protocol)协议...
初始化安装RabbitMQ的步骤包括使用命令行重启服务、添加用户、设置用户权限,以及将用户设置为管理员等。用户通过浏览器访问RabbitMQ管理界面,可以登录、修改密码、管理用户权限等。 文档还提供了有关RabbitMQ的几...
【Java使用RabbitMQ服务】 RabbitMQ是一款开源的消息队列系统,广泛应用于分布式系统中的消息传递。本文将简要介绍如何在Java环境中使用RabbitMQ,包括安装、基本结构、消息发送模式以及高级特性。 ### 1. 安装 在...
`rabbitmq-c`是RabbitMQ的一个C语言客户端库,它使得在C程序中与RabbitMQ服务器进行交互变得更加简单。本文将详细介绍如何使用CMake编译`rabbitmq-c-master`源码,并讨论相关知识点。 首先,我们需要了解CMake,这...
RabbitMQ是一种广泛使用的开源消息代理软件,它实现了Advanced Message Queuing Protocol (AMQP)标准,允许应用程序之间进行异步通信和数据交换。 描述中提到,这个项目无需用户自己编译源码,而是可以直接在VS2019...
.net core 使用RabbitMQ的demo。 二、功能介绍 RabbitMQ从信息接收者角度可以看做三种模式,一对一,一对多(此一对多并不是发布订阅,而是每条信息只有一个接收者)和发布订阅。其中一对一是简单队列模式,一对多是...
RabbitMq 使用手册 本文档为 RabbitMq 使用手册,介绍了 RabbitMq 的应用场景和开发指导。RabbitMq 是一个由 Erlang 开发的 AMQP(Advanced Message Queue)流行的开源消息队列系统。RabbitMq 的结构图如下: ...
在Android平台上,使用RabbitMQ进行网络通信是一个高效且可靠的选择。RabbitMQ是一个开源的消息代理和队列服务器,它允许应用程序之间通过消息传递进行异步通信。在本例中,我们将探讨如何在Android上设置和使用...
RabbitMQ是当前广泛使用的开源消息队列系统,它基于AMQP(Advanced Message Queuing Protocol)协议,适用于多种编程语言,包括Java。本篇文章将深入探讨如何在Java环境下使用RabbitMQ实现一个简单的示例。 首先,...
.net core 使用RabbitMQ的demo。 二、功能介绍 RabbitMQ从信息接收者角度可以看做三种模式,一对一,一对多(此一对多并不是发布订阅,而是每条信息只有一个接收者)和发布订阅。其中一对一是简单队列模式,一对多是...
RabbitMQ 详细讲解 RabbitMQ 是一个基于 Advanced Message Queue Protocol(AMQP)的开源消息队列系统,...RabbitMQ 的出现是为了解决异构系统中的分布式调用与通信问题,使得系统之间的信息传递变得更加可靠、高效。
.NET Core使用RabbitMQ是一个广泛应用于微服务架构中的消息队列技术,用于实现应用程序之间的异步通信和解耦。RabbitMQ是一个开源的消息代理,它遵循Advanced Message Queuing Protocol(AMQP)标准,允许不同语言的...
在设计系统时,考虑使用死信队列处理错误消息,或者通过交换机和路由键实现消息路由,可以帮助构建更加健壮和灵活的消息传递架构。同时,监控 RabbitMQ 的运行状态和性能指标也是运维过程中不可或缺的一部分。 总之...