滥用cURL与Redis进行通信

tzcvj98z  于 2023-02-28  发布在  Redis
关注(0)|答案(9)|浏览(159)

我想发送一个PING到Redis来检查连接是否正常,现在我可以直接安装redis-cli,但是我不想这样做,而且curl已经存在了。那么我怎么能滥用curl来做到这一点呢?基本上我需要关闭这里发送的内容:

> GET / HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost:6379
> Accept: */*
> 
-ERR wrong number of arguments for 'get' command
-ERR unknown command 'User-Agent:'
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'

我可以通过添加-A ""来完全去掉User-Agent,但是我找不到其他的东西来代替剩下的,你知道我怎么做吗?

nnt7mjpx

nnt7mjpx1#

当你想使用curl时,你需要REST而不是RESP,比如webdis、tinywebdis或者turbowebdis。https://github.com/markuman/tinywebdis#turbowebdis-tinywebdis--cherrywebdis

$ curl -w '\n' http://127.0.0.1:8888/ping
{"ping":"PONG"}

如果没有用于redis的REST接口,您可以使用netcat。

$ (printf "PING\r\n";) | nc <redis-host> 6379 
+PONG

对于密码保护的redis,你可以像这样使用netcat:

$ (printf "AUTH <password>\r\n";) | nc <redis-host> 6379
+PONG

使用netcat时,您必须自己构建RESP协议。

更新日期:2018年1月9日

我构建了一个强大的bash函数,它可以通过tcp以任何代价ping redis示例

function redis-ping() {
            # ping a redis server at any cost
            redis-cli -h $1 ping 2>/dev/null || \
                    echo $((printf "PING\r\n";) | nc $1 6379 2>/dev/null || \
                    exec 3<>/dev/tcp/$1/6379 && echo -e "PING\r\n" >&3 && head -c 7 <&3)
    }

使用redis-ping localhost

ldioqlga

ldioqlga2#

不是curl,但不需要HTTP接口或nc(对于没有安装nc的容器来说非常好)
exec 3<>/dev/tcp/127.0.0.1/6379 && echo -e "PING\r\n" >&3 && head -c 7 <&3
应该给予你
+PONG
您可以从this fantastic article阅读更多关于正在发生的事情的信息。

yvgpqqbh

yvgpqqbh3#

我需要在@Markus提供的nc中添加一个sleep,才能让它在远程系统中工作:

(printf "PING\r\n"; sleep 1) | nc remote.redis.hostname 6379

有关详细信息,请参见Request/Response protocols and RTT: Redis Pipelining

kcwpcxri

kcwpcxri4#

您也可以使用telnet localhost 6379,如果连接成功,请键入ping
外出使用quit

daupos2t

daupos2t5#

我在mac( Catalina )上运行了docker,并使用

docker run --name redis-mac -p 6379:6379 -d redis

然后我用电脑的IP测试了连接

echo PING | nc 192.168.1.100 6379

收到

+PONG

使用来自docker inspect redis-mac的IP不起作用。
实际上,我正在测试使用redis作为缓存提供程序的Sping Boot 应用程序,所以我需要测试连接。如果你是第一次使用docker,下面是第一个命令的一些解释:将redis作为容器运行,主机端口6379,docker端口6379,并将容器命名为redis-mac .现在如果镜像已经可用,docker守护进程将创建一个容器,否则它将从docker hub中提取镜像,然后运行容器.您可以执行docker ps来检查容器是否正在运行.

6ie5vjzr

6ie5vjzr6#

为了只检查主机是否已响应,我使用了以下命令:

echo "quit" | curl -v telnet://HOST:PORT

结果

*   Trying..
* TCP_NODELAY set
* Connected to ..
+OK
* Closing connection 0

扩展netcat解决方案,如果您需要关闭连接,这对我很有效:

(printf "AUTH <password>\r\nPING\r\nQUIT\r\n";) | nc HOST PORT

产出

+OK
+PONG
+OK
whlutmcx

whlutmcx7#

详细说明@Joel B的伟大答案。我需要在docker容器中的shell脚本中使用这个,没有curl,没有redis-cli,没有nc...我正在测试的REDIS是kubernetes的公开redis-ha Helm图表,从这里开始:https://github.com/helm/charts/tree/master/stable/redis-ha
要设置的变量有:

  • REDIS_HOST =包含Redis主机和Sentinel的主机名(DNS地址或IP)(如果主机是独立的,请将其拆分为独立的主机,如果需要,请更改端口-但在helm图表中,主机/从机和Sentinel位于同一个pod中,并使用标准端口)
  • REDIS_STARTUP_TIMEOUT =放弃前等待的最大秒数-默认为10分钟
  • REDIS_STARTUP_RETRY =测试之间等待的秒数-默认为15秒
  • DEBUG =将其设置为true以回显失败的响应

技术的错综复杂在评论中有描述(我建议你把评论留在原地,以保存你的同事--以及未来的自己--在试图破译尖括号时免于某种疯狂)

# wait for 10 mins and check again every 15 seconds
let n=${REDIS_STARTUP_TIMEOUT:-600}
let m=${REDIS_STARTUP_RETRY:-15}
ready=false
while ((n > 0)); do
    # These scripts are the best way to check if redis is running without having access to nc, curl or redis-cli
    # They write a "PING" to the redis and sentinel ports on the hostname "dc-ecm-redis-ha"
    # and look for a "PONG+" in return.
    #
    # Detailed explanation:
    # -  3<>/dev/tcp... opens a file handle identified as #3 for input and output on the tcp host and port
    #    The host $REDIS_HOST is defined in DNS by the Kubernetes _service_, and the port is for redis or sentinel
    #    (Uses linux's low-level network-as-filesystem support. Think of it as a sort of poor-man's telnet)
    # -  "PING" followed by carriage-return is sent to the port by redirecting to the handle with >&3
    # -  The response from the port is sent to the head command with <&3
    # -  The first 5 bytes of the response are captured with -c 5. This removes the linebreak (\r) from the response
    # -  Standard shell $() around the whole thing stores the result in a variable (master or sentinel)
    # -  When Redis is NOT ready, the result is generally a failure in the exec or some other error, which goes
    #    to stderr, so we wrap it in  { } > 2>&1 to capture that error in the variable too.
    # -  Success is measured by "+PONG" being in the variable
    # -  If you set the variable DEBUG to "true" (or "TRUE" -> the {,,} lower-cases it) the failed responses are echoed
    # -  (There are easier ways to do this if you have redis-cli installed or nc, but typically you don't on a docker container)
    # -  The whole thing waits n seconds for Redis to be ready, checking every m seconds
    #
    master=$( { exec 3<>/dev/tcp/${REDIS_HOST}/6379 && echo -e "PING\r\n" >&3 && head -c 5 <&3; } 2>&1 )
    sentinel=$( { exec 3<>/dev/tcp/${REDIS_HOST}/26379 && echo -e "PING\r\n" >&3 && head -c 5 <&3; } 2>&1 )
    if [ "$sentinel" = "+PONG" -a "$master" = "+PONG" ]; then ready=true;
       break;
   else echo "$(date) : Waiting $n more seconds for Redis master and sentinel to respond to PING"
        [[ "${DEBUG,,}" = "true" ]] && echo "master response was [$master]";
        [[ "${DEBUG,,}" = "true" ]] && echo "sentinel response was [$sentinel]";
        sleep $m
        ((n-=m))
    fi
done

if [ "$ready" = true ]
    then echo "$(date) : REDIS is ready"
    # do something when Redis is ready
else
    echo "$(date) : ERROR: REDIS is still not ready. Giving up waiting"
    # do something when Redis fails
fi
olqngx59

olqngx598#

如果Redis示例需要pass,这可能会有帮助:

$ exec 3<>/dev/tcp/127.0.0.1/6379 && echo -e "AUTH {requirepass-string-from-redis-config} \r\n PING\r\n" >&3 && head -c 12 <&3
+OK
+PONG

将{requirepass-string-from-redis-config}替换为“requirepass”redis.conf中的字符串

eivnm1vs

eivnm1vs9#

运行以下代码,即使你的Redis在Docker上,对我来说也是有效的:

echo PING | nc 127.0.0.1 6379

正常时得到以下响应:

+PONG

相关问题