【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
PaPing:https://code.google.com/archive/p/paping/downloads
PS:在windows的机器上,可以使用 tcping xxxxxxxxxxxxx.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
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤的更多相关文章
- 【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑
编写Java Spring Boot应用,通过配置logging.path路径把日志输出在指定的文件夹中. 第一步:通过VS Code创建一个空的Spring Boot项目 第二步:在applicat ...
- Java Spring Boot VS .NetCore (一)来一个简单的 Hello World
系列文章 Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filte ...
- Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (三)Ioc容器处理
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (七) 配置文件
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
随机推荐
- 小Min_25筛小记🐤
这里的小Min_25筛,可以筛出 $10^11$ 以内所有质数的完全积性函数之和 注意事项: 1. cmd 的题解里面下标写得不清楚,应该是 $S'(p_k-1,k-1)$ 而不是 $S'(p_{k- ...
- JS遍历树形数据
树形数据结构遍历某个key值 深度优先遍历(DFS) let tree = [{ id: '1', name: '节点1', children: [{ id: '1-1', name: '节点1-1' ...
- vue3动态路由的addRoute和removeRoute使用
为什么需要有动态路由 有些时候,我们不同的身份角色,我们希望可以展示不同的菜单. 比如说:普通用户只有展示A菜单,管理员有A,B,C菜单 这个时候,我们就需要动态路由了! Vue2和vue3的区别 V ...
- 大数据面试题集锦-Hadoop面试题(一)
目录 1.集群的最主要瓶颈 2.Hadoop运行模式 3.Hadoop生态圈的组件并做简要描述 4.解释"hadoop"和"hadoop 生态系统"两个概念 5 ...
- kettle(docker版)系列文章02---hello world
目标:将mysql库中表的数据定时转到另外一个表中 1.在mysql中新建目标表test_kettle,有字段id,productName,createtime 2.连接mysql数据库 DB连接-- ...
- NetCore高级系列文章01---创建项目及配置文件
.NET Core是适用于 Windows.Linux 和 macOS 的免费.开源托管的计算机软件框架,作为.NET开发人员,全面拥抱.NetCore将成为趋势. 本系列文章将分为两大部分讲解.Ne ...
- paddle之visualDL工具使用,可视化利器。
相关链接: [一]AI Studio 项目详解[(一)VisualDL工具.环境使用说明.脚本任务.图形化任务.在线部署及预测]PARL_汀.的博客-CSDN博客 isualDL 是一个面向深度学习任 ...
- C/C++ 反汇编:数据类型与常量
反汇编即把目标二进制机器码转为汇编代码的过程,该技术常用于软件破解.外挂技术.病毒分析.逆向工程.软件汉化等领域,学习和理解反汇编对软件调试.系统漏洞挖掘.内核原理及理解高级语言代码都有相当大的帮助, ...
- C/C++ Qt 基本文件读写方法
Qt文件操作有两种方式,第一种使用QFile类的IODevice读写功能直接读写,第二种是利用 QFile和QTextStream结合起来,用流的方式进行文件读写. 第一种,利用QFile中的相关函数 ...
- 物色到的 c# 模拟 http post get 请求 做下笔记
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...