记一次登录请求始终10秒中断的生产问题
记一次 登录 10 秒请求中断的排查过程:从现象到根因1. 问题描述在一个基于 Spring Cloud 的微服务架构系统中,遇到了一个诡异的登录问题: 现象:用户在前端登录页面点击登录,请求始终在 10 秒 后中断,导致登录失败。 前端配置:前端设置的超时时间是 60 秒,理论上不应该在 10 秒报错。 后端状态:后端的登录接口被其他服务通过 Feign 调用时,一切正常,没有报错。 异常信息:在 Gateway 网关层发现了异常日志:1reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response 2. 初步排查:排除业务代码与 Feign 调用2.1 为什么不是 Feign 的问题?首先,我们确认了 Feign 接口本身是正常的。因为其他服务调用该接口时能够成功返回,说明后端的业务逻辑、数据库查询以及 Feign 客户端的配置(如超时时间、熔断策略)在服务间通信链路上是没有问题的。 2.2 为什么不是业务处理慢?虽然登录逻辑可能涉及鉴权、...
OAuth 2.0 与 OIDC (OpenID Connect) 学习笔记
一、OAuth 2.0 授权码模式 vs. 实际登录场景1、标准的 OAuth 2.0 授权码模式 定义:OAuth 2.0 是一个授权框架,解决的是“委托授权”问题(即:应用 A 能否访问用户在应用 B 的数据)。 核心产物:Access Token(访问令牌)。 Token 生成者:必须由授权服务器(如微信、Google)生成。 原因:资源服务器只信任授权服务器。如果由第三方(客户端)自己生成,资源服务器无法验证其真伪,安全体系将崩溃。 Token 持有者:第三方应用(客户端)。 Token 用途:第三方应用拿着 Token 去访问资源服务器的接口。 2、实际企业登录场景(混合模式) 场景描述:公司新买的网站 P 接入公司统一登录平台。 网站 P 通过 OAuth 2.0 获取 code。 用 code 换取用户信息。 网站 P 自己生成 Token,建立本地会话。 定性:这属于“基于 OAuth 2.0 的身份认证 + 本地会话管理”。 前半段是标准的 OAuth 2.0(解决“你是谁”)。 后半段是业务逻辑(解决“在自家网站如何保持登录状态”)。 为什么第三...
Nacos-服务启动无法获取配置问题排查与解决
一、问题背景在微服务架构中,Nacos 作为配置中心和服务注册中心被广泛使用。但在生产环境中,我们遇到了应用启动时无法从 Nacos 获取配置的问题,导致应用启动失败。本文将详细分析该问题的排查过程、根本原因及解决方案。 二、问题描述1、问题现象Java 应用在启动时连接 Nacos 超时,导致配置读取失败、应用启动异常。具体表现为: 应用启动过程卡顿约 15 秒 随后报错读取配置失败,提示”【XXX】配置文件is empty” 日志中显示连接 Nacos 超时 2、环境信息 JDK 版本:JDK 8 Spring Cloud Alibaba 版本:2.2.0.RELEASE Nacos 版本:2.4.1 操作系统:CentOS 7 三、问题排查过程1、初步排查首先,我们检查了 Nacos 服务端的运行状态和网络连通性: 12345678# 检查 Nacos 服务是否正常运行ps -ef | grep nacos# 检查 Nacos 服务端口是否正常监听netstat -anp | grep 8848# 检查应用服务器到 Nacos 服务器的网络连通性telnet <...
部署web到Tomcat的三种方式
这里简单的记录tomcat的部署方式: 一、 直接将 web 项目文件(一般是复制生成的war包)复制到tomcat的webapps目录中 ; 二、在tomcat中的conf目录下的server.xml文件中,在节点中添加一个context,具体为: 1<Context Path="" Docbase="目标目录位置" Debug="0" Privileged="True" Reloadable="True"></Context> 这里的 Reloadable= “true” 这个属性是指tomcat在运行状态下会自动检测应用程序的WEB-INF/classes和WEB-INF/lib目录下的class文件,如果监测到有class文件有改动,服务器自动加载新的web应用程序,可以在不重起tomcat的情况下改变应用程序,也就是热部署; 一般我们会在开发阶段将Reloadable属性设为true,有助于调试servlet和其它的class文件,但是由于这样会...
并发编程(三)
三、JUC:java.util.concurrent3.1 集合3.1.1 BlockingQueue什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时, 获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。 阻塞队列提供了四种处理方法: 方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put(e) offer(e,time,unit) 移除方法 remove() poll() take() poll(time,unit) 检查方法 element() peek() 不可用 不可用 异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException(“Queue full”)异常。当队列为空时,从队列里获取元素时会抛出NoSu...
并发编程(二)
二、并发编程基础2.1 临界资源临界资源是一次仅允许一个进程使用的共享资源。各进程采取互斥的方式,实现共享的资源称作临界资 源。属于临界资源的硬件有,打印机,磁带机等;软件有消息队列,变量,数组,缓冲区等。诸进程间 采取互斥方式,实现对这种资源的共享。 123456public class Counter { protected long count = 0; public void add(long value){ this.count = this.count + value; }} 2.2 线程安全2.2.1 基本概念竞态条件:当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。导致竞态条件发生的代码区称作临界区。在临界区中使用适当的同步就可以避免竞态条件,如使用synchronized或者加锁机制。 线程安全:允许被多个线程同时执行的代码称作线程安全的代码。线程安全的代码不包含竞态条件。 2.2.2 对象的安全局部基本类型变量局部变量存储在线程自己...
并发编程(一)
一、并发编程入门1.1 线程1.1.1进程和线程进程进程: 进程指正在运行的程序,进程拥有一个完整的、私有的基本运行资源集合。通常,每个进程都有 自己的内存空间。 进程往往被看作是程序或应用的代名词,然而,用户看到的一个单独的应用程序实际上可能是一组相互 协作的进程集合。 为了便于进程之间的通信,大多数操作系统都支持进程间通信(IPC),如pipes 和sockets。IPC不仅支持同一系统上的通信,也支持不同的系统。IPC通信方式包括管道(包括无名管道和命名管道)、 消息队列、信号量、共享存储、Socket、Streams等方式,其中 Socket和Streams支持不同主机上的两个进程IPC。 线程: 线程有时也被称为轻量级的进程。进程和线程都提供了一个执行环境,但创建一个新的线程比创建一个新的进程需要的资源要少。 线程是在进程中存在的 — 每个进程最少有一个线程。线程共享进程的资源,包括内存和打开的文件。这样提高了效率,但潜在的问题就是线程间的通信。 多线程的执行是Java平台的一个基本特征。每个应用都至少有一个线程 – 或几个,如果算上“系 统”线程的话,比如内存管理和...
容器小记
容器中的设计模式: 迭代器模式;[例子:容器循环所使用的 Iterator 迭代器] 设配器模式:简单的说就是将原本两个不相干的类联系起来(类似于充电器,连接插座和用电器,将电压变成电器匹配的量级);[例子:Arrays.asList() 将数组转换成List] 默认长度 & 扩容大小: List 默认大小 默认扩容 备注 ArrayList 10 原来的1.5倍 由数组实现,因此支持快速随机访问;扩容操作需要将原数组整个复制到新数组中,代价很高;删除元素是将删除index后的元素复制到index的位置,代价很高; Vector 原来的2倍 与ArrayList相似,但是使用了synchronized进行同步,是线程安全的 得到一个线程 安全的ArrayList替代方案: ① Collections.synchronizedList() ② concurrent 并发包下的 CopyOnWriteArrayList 类 CopyOnWriteArrayList : 写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分...
事务传播行为与事务隔离级别
事务事务读传播行为· 保证同一个事务中PROPAGATION_REQUIRED支持当前事务,如果不存在,就新建一个(默认)PROPAGATION_SUPPORTS支持当前事务,如果不存在,就不适用事务PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常 · 保证没有在同一个事务中PROPAGATION_REQUIRES_NEW如果有事务存在,挂起当前事务,创建一个新的事务PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行 事务隔离级别DEFAULT这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别; 未提交读(read uncommitted): 事务的修改,即使当前事务没有被提交,对其他事务而言也是可见的。事务可以读取未提交的数据,也称为脏读。这个级别会导致很多问题,性能上也不比其他级别好多少,一般...
servlet学习笔记
1.Tomcat主要在程序中做了些什么?1.1 创建socket监听在对应的端口 1.2 维护一个线程池 1.3 当有TCP连接时分配一个线程来处理 1.4 从TCP连接中读取数据 1.5 按照HTTP协议解析数据 1.6 将解析后的数据包封装到request对象中 1.7 按照web.xml的映射关系找到对应的Servlet类 1.8 将最后的执行结果response组装成HTTP协议格式的数据包 1.9 重新通过TCP返回给客户端 2.访问servlet 的过程2.1 connector 负责监听端⼝,当有链接进来时分配线程并实例化HttpllProcessor对数据进⾏ HTTP协议解析,然后将请求交给其所在的engine即Catalina来处理,处理的是域名对应的ip和 端⼝8080 ,注意localhost任然没被使⽤ 2.2 engine将从HTTP请求头中获取host参数⽤于选择⼀个匹配的Host 处理的是主机名 localhost(Host可以配置多个,即你可以在⼀台电脑上部署两个完全不相关的web项⽬例如jd 和百度),此时处理的是域...
