Nginx memcached 回退到远程服务
Nginx memcached with fallback to remote service
我无法让 Nginx 与 memcached 模块一起工作,要求是查询远程服务,在 memcached 中缓存数据,并且在后端使缓存无效之前永远不会获取远程端点。我有 2 个容器 memcached v1.4.35 and one with Nginx v1.11.10.
配置如下:
upstream http_memcached {
server 172.17.0.6:11211;
server 172.17.0.7:11211;
}
upstream remote {
server api.example.com:443;
keepalive 16;
}
server {
listen 80;
location / {
set $memcached_key "$uri?$args";
memcached_pass http_memcached;
error_page 404 502 504 = @remote;
}
location @remote {
internal;
proxy_pass https://remote;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
我试图错误地设置 memcached 上游,但我得到的是 HTTP 499 和警告:
*3 upstream server temporarily disabled while connecting to upstream
似乎使用描述的配置 Nginx 可以成功到达 memcached 但无法写入或读取。我可以使用 telnet 成功写入和读取 memcached。
你能帮帮我吗?
我对你的配置的猜测
1。 499个代码
HTTP 499 是 nginx 的自定义代码,表示客户端在收到响应之前终止了连接 (http://lxr.nginx.org/source/src/http/ngx_http_request.h#0120)
我们可以轻松复现,只需
nc -k -l 172.17.0.6 172.17.0.6:11211
和 curl 您的资源 - curl 将挂起一段时间,然后按 Ctrl+C — 您的访问日志中会出现此消息
2。连接到上游时暂时禁用上游服务器
这意味着 nginx 无法访问您的 memcached,只是将其从上游池中删除。关闭两个 memcached 服务器就足够了,您会经常在错误日志中看到它(我每次都看到它 error_log ... info
)。
当您看到这些消息时,您认为 nginx 可以与 memcached 服务器自由通信的假设似乎并不正确。
考虑明确设置 http://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_bind
并将 -b 选项与 telnet 一起使用,以确保您正确地通过 telnet 客户端
测试 memcached 服务器的可用性
3。 nginx 可以成功访问 memcached 但无法写入或读取它
Nginx 只能通过其内置模块从 memcached 读取
(http://nginx.org/en/docs/http/ngx_http_memcached_module.html):
The ngx_http_memcached_module module is used to obtain responses from
a memcached server. The key is set in the $memcached_key variable. A
response should be put in memcached in advance by means external to
nginx.
4。整体架构
从你的问题来看,整体架构应该如何运作并不完全清楚。
nginx 的上游默认使用weighted round-robin。
这意味着您的 memcached 服务器将被随机查询一次。
您可以通过设置 memcached_next_upstream not_found
来更改它,这样丢失的密钥将被视为错误并且您的所有服务器都将被轮询。对于 2 台服务器的农场来说可能没问题,但不太可能是你想要的 20 台服务器
memcached 客户端库通常也是如此——他们会根据某种哈希方案从池中选择一个服务器 => 所以你的密钥最终只会出现在池中的一台服务器上游泳池
5。做什么
我已经设法在 10 分钟内在我的本地机器上设置了类似的配置 - 它按预期工作。为了减少调试,我会摆脱 docker 容器以避免网络过于复杂,运行 2 个内存缓存服务器在单线程模式下的不同端口上,带有 -vv 选项以查看请求何时到达它们(memcached -p 11211 -U o -vv
) 然后玩 tail -f 和 curl 看看你的情况到底发生了什么。
6.工作解决方案
nginx 配置:
https 和 http/1.1 这里没有用但是没关系
upstream http_memcached {
server 127.0.0.1:11211;
server 127.0.0.1:11212;
}
upstream remote {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name server.lan;
access_log /var/log/nginx/server.access.log;
error_log /var/log/nginx/server.error.log info;
location / {
set $memcached_key "$uri?$args";
memcached_next_upstream not_found;
memcached_pass http_memcached;
error_page 404 = @remote;
}
location @remote {
internal;
access_log /var/log/nginx/server.fallback.access.log;
proxy_pass http://remote;
proxy_set_header Connection "";
}
}
server.py:
这是我的虚拟服务器 (python):
from random import randint
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello: {}\n'.format(randint(1, 100000))
这是运行的方法(只需要先安装flask)
FLASK_APP=server.py [flask][2] run -p 8080
填写我的第一个 memcached 服务器:
$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set /? 0 900 5
cache
STORED
quit
Connection closed by foreign host.
正在检查:
请注意,尽管我们存储了数据,但我们每次都会得到一个结果
仅在第一个服务器
$ curl http://server.lan && echo
cache
$ curl http://server.lan && echo
cache
$ curl http://server.lan && echo
cache
这个不在缓存中,所以我们将从 server.py
得到回复
$ curl http://server.lan/?q=1 && echo
Hello: 32337
全图:
右边的2个windows是
memcached -p 11211 -U o -vv
和
memcached -p 11212 -U o -vv
我无法让 Nginx 与 memcached 模块一起工作,要求是查询远程服务,在 memcached 中缓存数据,并且在后端使缓存无效之前永远不会获取远程端点。我有 2 个容器 memcached v1.4.35 and one with Nginx v1.11.10.
配置如下:
upstream http_memcached {
server 172.17.0.6:11211;
server 172.17.0.7:11211;
}
upstream remote {
server api.example.com:443;
keepalive 16;
}
server {
listen 80;
location / {
set $memcached_key "$uri?$args";
memcached_pass http_memcached;
error_page 404 502 504 = @remote;
}
location @remote {
internal;
proxy_pass https://remote;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
我试图错误地设置 memcached 上游,但我得到的是 HTTP 499 和警告:
*3 upstream server temporarily disabled while connecting to upstream
似乎使用描述的配置 Nginx 可以成功到达 memcached 但无法写入或读取。我可以使用 telnet 成功写入和读取 memcached。
你能帮帮我吗?
我对你的配置的猜测
1。 499个代码
HTTP 499 是 nginx 的自定义代码,表示客户端在收到响应之前终止了连接 (http://lxr.nginx.org/source/src/http/ngx_http_request.h#0120)
我们可以轻松复现,只需
nc -k -l 172.17.0.6 172.17.0.6:11211
和 curl 您的资源 - curl 将挂起一段时间,然后按 Ctrl+C — 您的访问日志中会出现此消息
2。连接到上游时暂时禁用上游服务器
这意味着 nginx 无法访问您的 memcached,只是将其从上游池中删除。关闭两个 memcached 服务器就足够了,您会经常在错误日志中看到它(我每次都看到它 error_log ... info
)。
当您看到这些消息时,您认为 nginx 可以与 memcached 服务器自由通信的假设似乎并不正确。
考虑明确设置 http://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_bind 并将 -b 选项与 telnet 一起使用,以确保您正确地通过 telnet 客户端
测试 memcached 服务器的可用性3。 nginx 可以成功访问 memcached 但无法写入或读取它
Nginx 只能通过其内置模块从 memcached 读取 (http://nginx.org/en/docs/http/ngx_http_memcached_module.html):
The ngx_http_memcached_module module is used to obtain responses from a memcached server. The key is set in the $memcached_key variable. A response should be put in memcached in advance by means external to nginx.
4。整体架构
从你的问题来看,整体架构应该如何运作并不完全清楚。
nginx 的上游默认使用weighted round-robin。 这意味着您的 memcached 服务器将被随机查询一次。 您可以通过设置
memcached_next_upstream not_found
来更改它,这样丢失的密钥将被视为错误并且您的所有服务器都将被轮询。对于 2 台服务器的农场来说可能没问题,但不太可能是你想要的 20 台服务器memcached 客户端库通常也是如此——他们会根据某种哈希方案从池中选择一个服务器 => 所以你的密钥最终只会出现在池中的一台服务器上游泳池
5。做什么
我已经设法在 10 分钟内在我的本地机器上设置了类似的配置 - 它按预期工作。为了减少调试,我会摆脱 docker 容器以避免网络过于复杂,运行 2 个内存缓存服务器在单线程模式下的不同端口上,带有 -vv 选项以查看请求何时到达它们(memcached -p 11211 -U o -vv
) 然后玩 tail -f 和 curl 看看你的情况到底发生了什么。
6.工作解决方案
nginx 配置:
https 和 http/1.1 这里没有用但是没关系
upstream http_memcached {
server 127.0.0.1:11211;
server 127.0.0.1:11212;
}
upstream remote {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name server.lan;
access_log /var/log/nginx/server.access.log;
error_log /var/log/nginx/server.error.log info;
location / {
set $memcached_key "$uri?$args";
memcached_next_upstream not_found;
memcached_pass http_memcached;
error_page 404 = @remote;
}
location @remote {
internal;
access_log /var/log/nginx/server.fallback.access.log;
proxy_pass http://remote;
proxy_set_header Connection "";
}
}
server.py:
这是我的虚拟服务器 (python):
from random import randint
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello: {}\n'.format(randint(1, 100000))
这是运行的方法(只需要先安装flask)
FLASK_APP=server.py [flask][2] run -p 8080
填写我的第一个 memcached 服务器:
$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set /? 0 900 5
cache
STORED
quit
Connection closed by foreign host.
正在检查:
请注意,尽管我们存储了数据,但我们每次都会得到一个结果 仅在第一个服务器
$ curl http://server.lan && echo
cache
$ curl http://server.lan && echo
cache
$ curl http://server.lan && echo
cache
这个不在缓存中,所以我们将从 server.py
得到回复$ curl http://server.lan/?q=1 && echo
Hello: 32337
全图:
右边的2个windows是
memcached -p 11211 -U o -vv
和
memcached -p 11212 -U o -vv