1. 程式人生 > 其它 >【Azure Redis 快取】定位Java Spring Boot 使用 Jedis 或 Lettuce 無法連線到 Redis的網路連通性步驟

【Azure Redis 快取】定位Java Spring Boot 使用 Jedis 或 Lettuce 無法連線到 Redis的網路連通性步驟

問題描述

Java Spring Boot的程式碼在IDE裡面跑可以連上 Azure 的 Redis服務,打包成Image放在容器裡面跑,就連不上azure的redis服務,錯誤訊息為:

Unable to connect to Redis; nested exception is org.springframework.data.redis.connection.PoolException: 
Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to xxxxxxxxxxxxx.redis.cache.chinacloudapi.cn:6380

問題分析

第一步: 因為容器是Linux的機器上執行,所以第一步是確認客戶端與Azure Redis服務之間的網路連通性。可以通過PsPing或者PaPing 測試。

#PsPing
psping xxxxxxxxxxxxx.redis.cache.chinacloudapi.cn:6380


#PaPing
./paping -p 6380 -c 500 xxxxxxxxxxxxx.redis.cache.chinacloudapi.cn

PsPing:https://docs.microsoft.com/zh-cn/sysinternals/downloads/psping

PaPinghttps://code.google.com/archive/p/paping/downloads

PS:在windows的機器上,可以使用 tcpingxxxxxxxxxxxxx.redis.cache.chinacloudapi.cn:6380

第二步: 抓取網路包

sudo tcpdump -i en0 -w xxxx.pcap

從網路包中驗證是否是與TLS協議,版本錯誤相關。如果能夠檢視TCP及TLSv1.2的Application Data傳遞,則表明網路連通性,TLS協議都沒有問題。

經過以上分析後,就可以定位問題一定發生在應用程式碼中,然後就是通過Demo來複現及定位問題。比如:排除專案中各種元件間的相互干擾,使用Azure官網中的簡單Demo來測試聯通問題。如上Jedis連線Redis的程式碼片段:

App.java

package example.demo;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;

/**
 * Redis test
 *
 */
public class App 
{
    public static void main( String[] args )
    {

        boolean useSsl = true;
        String cacheHostname = "redis host";
        String cachekey = "key";

        // Connect to the Azure Cache for Redis over the TLS/SSL port using the key.
        JedisShardInfo shardInfo = new JedisShardInfo(cacheHostname, 6380, useSsl);
        shardInfo.setPassword(cachekey); /* Use your access key. */
        Jedis jedis = new Jedis(shardInfo);      

        // Perform cache operations using the cache connection object...

        // Simple PING command        
        System.out.println( "\nCache Command  : Ping" );
        System.out.println( "Cache Response : " + jedis.ping());

        // Simple get and put of integral data types into the cache
        System.out.println( "\nCache Command  : GET Message" );
        System.out.println( "Cache Response : " + jedis.get("Message"));

        System.out.println( "\nCache Command  : SET Message" );
        System.out.println( "Cache Response : " + jedis.set("Message", "Hello! The cache is working from Java!"));

        // Demonstrate "SET Message" executed as expected...
        System.out.println( "\nCache Command  : GET Message" );
        System.out.println( "Cache Response : " + jedis.get("Message"));

        // Get the client list, useful to see if connection list is growing...
        System.out.println( "\nCache Command  : CLIENT LIST" );
        System.out.println( "Cache Response : " + jedis.clientList());

        jedis.close();
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>example.demo</groupId>
  <artifactId>redistest</artifactId>
  <version>1.0</version>

  <name>redistest</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.2.0</version>
      <type>jar</type>
      <scope>compile</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

參考資料

使用 PsPing & PaPing 進行 TCP 埠連通性測試:https://docs.azure.cn/zh-cn/articles/azure-operations-guide/virtual-network/aog-virtual-network-tcp-psping-paping-connectivity#paping

當在複雜的環境中面臨問題,格物之道需:濁而靜之徐清,安以動之徐生。 雲中,恰是如此!