4

我们有一个在Glassfish应用服务器集群上运行的基于 Java EE 的 Web 应用程序。传入的流量主要是对我们应用程序资源的基于 XML 的表示的 RESTful 请求,但可能有 5% 的流量可能是基于 JSON 或 XHTML/CSS 的表示。

我们现在正在研究负载平衡解决方案,以在集群中的 Glassfish 实例之间分配传入流量。我们还在研究如何使用 memcached 卸载集群,memcached 是一种内存分布式哈希映射,其键是 REST 资源名称(例如,“/user/bob”、“/group/jazzlovers”),其值为相应的 XML 表示。

一种听起来很有希望的方法是用一块石头杀死两只鸟,并使用轻量级、快速的nginx HTTP 服务器/反向代理。Nginx 将通过首先在 memcached 中查找其 URI 来处理每个传入请求,以查看是否已经存在未过期的 XML 表示。如果没有,nginx 会将请求发送到 Glassfish 实例之一。这篇简短的文章中描述了 nginx memcached 模块。

你对 nginx 和 memcached 这样使用的总体印象如何,你对它们有多满意?您发现哪些资源对了解它们最有帮助?如果您尝试了它们并且它们不适合您的目的,为什么不呢?您改用了什么?

注意:这是一个相关的问题

更新:我后来在 ServerFault.com 上问了同样的问题。那里的答案主要是建议替代 nginx (有帮助,但间接)。

4

1 回答 1

9

假设您有一组应用程序服务器向用户上游传递数据。

upstream webservices {
    server 10.0.0.1:80;
    server 10.0.0.2:80;
    server 10.0.0.3:80;
}
server {
    ... default nginx stuff ...
    location /dynamic_content {
          memcached_pass localhost:11211;
          default_type   text/html;
          error_page     404 502 = @dynamic_content_cache_miss;
          set $memcached_key $uri;
    }
    location @dynamic_content_cache_miss {
          proxy_pass http://webservices;
    }

上面的 nginx.conf 片段所做的是将所有流量从http://example.com/dynamic/ * 直接定向到 memcached 服务器。如果 memcache 有内容,您的上游服务器将看不到任何流量。

如果缓存命中失败并出现 404 或 502 错误(不在缓存中或无法访问内存缓存),则 nginx 会将请求传递给上游服务器。由于上游定义中有三台服务器,因此您还可以获得透明的负载平衡代理。

现在唯一需要注意的是,您必须确保后端应用程序服务器保持 memcache 中的数据新鲜。我使用 nginx + memcached + web.py 创建简单的小系统,在相对适中的硬件上每分钟处理数千个请求。

应用服务器的一般伪代码是这样的 web.py

class some_page:
     def GET(self):
         output = 'Do normal page generation stuff'
         web_url = web.url().encode('ASCII')
         cache.set(web_url, str(output), seconds_to_cache_content)
         return output

在上面的 web.py / 伪代码中要记住的重要一点是,通过 nginx 来自 memcached 的内容根本无法更改。nginx 使用简单的字符串而不是 unicode。如果您将 unicode 输出存储在 memcached 中,您至少会在缓存内容的开头和结尾处获得奇怪的字符。

我将 nginx 和 memcached 用于与体育相关的网站,在那里我们获得了仅持续几个小时的巨大流量脉冲。如果没有 nginx 和 memcached,我就过不下去了。实施上述更改后,我们上一次 7 月 4 日大型体育赛事期间的服务器负载从 70% 下降到 0.6%。我不能推荐它。

于 2009-07-07T15:34:36.280 回答