【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 ...
随机推荐
- dispaly结合背景图片会提升加载性能
1.display的常见现象 我们很多人都知道,display可以让元素实现隐藏或者显示. 或者让行级元素变成块级元素. 对它的认识也是比较准确的. 如果一个元素使用了display:none; 那么 ...
- 让你彻底理解Typescript中静态成员和抽象方法
1.Typescript中static详解 静态成员:在类中通过 static 修饰的属性或者方法 那么就是静态的属性静态方法 也称之为:静态成员(静态成员包含静态属性和静态方法) 静态成员在使用的时 ...
- Python 潮流周刊#22:Python 3.12.0 发布了!!
你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中一则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...
- Gin 框架之jwt 介绍与基本使用
目录 一.JWT 介绍 二.JWT认证与session认证的区别 2.1 基于session认证流程图 2.2 基于jwt认证流程图 三. JWT 的构成 3.1 header : 头部 3.2 pa ...
- go中的sync.RWMutex源码解读
读写锁 前言 什么是读写锁 看下实现 读锁 RLock RUnlock 写锁 Lock Unlock 问题要论 写操作是如何阻止写操作的 写操作是如何阻止读操作的 读操作是如何阻止写操作的 为什么写锁 ...
- 4.0 Python 变量与作用域
在python中,变量的作用域决定了变量在哪些位置可以被访问.一个程序中的变量并不是所有的地方都可以访问的,其访问权限决定于变量的赋值位置.python中有两种最基本的变量作用域:局部作用域和全局作用 ...
- Axure谷歌浏览器扩展程序下载及安装方法(免FQ)
在用Axure在chrome查看原型时,没有安装Axure谷歌浏览器插件时无法显示会有提示信息,如果未FQ按照提示是无法直接安装扩展程序的,这里提供插件下载地址并教大家如何安装插件. 平时在使用谷歌浏 ...
- 26岁的超经典音乐播放器Winamp归来!UI彻底重构:支持iOS/安卓
快科技4月18日讯,还记得Winamp吗? 这款1997年首发的媒体播放器,已经走过了26年的历史.它凭借高度简洁.大量的皮肤.丰富的定制性.多元的格式支持等成为有史以来最好的音乐播放器之一. 当年的 ...
- CF452F Permutation 与 P2757 [国家集训队] 等差子序列 题解
两道基本一样的题: 题目链接: P2757 [国家集训队] 等差子序列 Permutation 链接:CF 或者 洛谷 等差子序列那题其实就是长度不小于 \(3\) 的等差数列是否存在,我们考虑等于 ...
- 关于SUPPLEMENTAL_LOG_DATA_MIN的设置问题
Oracle数据库开启附加日志,用于Logminer或基于Logminer的一些操作. 客户咨询关于开启附加日志,SUPPLEMENTAL_LOG_DATA_MIN显示为啥是implicit,如何改成 ...