JAVA 线上故障排查全套路

JAVA 线上故障排查全套路
线上故障主要会包括 CPU、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如 jstack、jmap 等工具也是不囿于一个方面的问题的,基本上出问题就是 df、free、top 三连,然后依次 jstack、jmap 伺候,具体问题具体分析即可。CPU 一般来讲我们首先会排查 CPU 方面的问题。CPU 异常往往还是比较好定位的。原因包括业务逻辑问题(死

2019 云栖大会—互联网中间件

2019 云栖大会—互联网中间件
9 月 26 日,在杭州云栖大会上各位专家分享了关于互联网中间件的一些内容。互联网中间件的演进首先是阿里云智能中间件首席架构师李小平带来的关于互联网中间件演进的分享。互联网中间件的发展得益于中国互联网用户的规模,规模变化使得同时服务几亿用户成为挑战。而飞速发展的业务需要飞速发展的技术来支持,技术一旦上升一个数量级,复杂度往往更大。阿里本身中间件经过一段时间的沉淀发展,提出了 Aliware 互联网 PaaS 产品

使用基于 SpringMVC 的透明 RPC 开发微服务

使用基于 SpringMVC 的透明 RPC 开发微服务
我司目前 RPC 框架是基于 JavaRest 的方式开发的,形式上可以参考 SpringCloudFeign 的实现。Rest 风格随着微服务的架构兴起,SpringMVC 几乎成为了 Rest 开发的规范,同时对于 Spring 的使用者门槛也比较低。REST 与 RPC 风格的开发方式 RPC 框架采用类 Feign 方式的一个简单的实现例子如下:@RpcClient(schemaId="hello")publicinterfac

对 RPC 框架的内存优化—改变服务引用方式

对 RPC 框架的内存优化—改变服务引用方式
近来总是会有服务遇到 OOM 的情况,简单定位后发现 rpc 框架内存占用较多,看来是时候需要优化一波了。占用内存膨胀首先我们需要简单了解一下目前 rpc 框架的层次结构。先从服务注册中心 zookeeper 的数据结构看,一个命名空间对应数个服务,而每个服务对应数个实例信息,我们的 API 信息则是与实例配置一同放在实例信息的 body 里面的。当我们根据用户配置的订阅列表拉取服务信息的时候,会将所有的 API 信息一同拉下

在 Kubernetes 中优雅下线微服务应用

在 Kubernetes 中优雅下线微服务应用
在去年写过一篇关于微服务优雅上下线的文章,比较笼统的将了一下微服务保证优雅上下线的一些方式。但随着应用的逐渐 k8s 化,原有的微服务下线会存在一些问题。下线信号钩子之前针对优雅下线使用的还是通过信号响应的方式。一个是 Docker 以及 k8s 中下线信号 SIGTERM,由于这个信号会被 JVM 处理,所以我们写了一份下线逻辑在其 shutdownHook 里。另一个是我们自定义的信号 SIGUSR2,这个本身就是保留

当我们谈微服务,我们在谈什么(3)— 微服务的稳定性

当我们谈微服务,我们在谈什么(3)— 微服务的稳定性
当一个单体应用改造成多个微服务之后,在请求调用过程中往往会出现更多的问题,通信过程中的每一个环节都可能出现问题。而在出现问题之后,如果不加处理,还会出现链式反应导致服务雪崩。服务治理功能就是用来处理此类问题的。我们将从微服务的三个角色:注册中心、服务消费者以及服务提供者一一说起。注册中心如何保障稳定性注册中心主要是负责节点状态的维护,以及相应的变更探测与通知操作。一方面,注册中心自身的稳定性是十分重

当我们谈微服务,我们在谈什么(2)— 具体的微服务请求背后

当我们谈微服务,我们在谈什么(2)— 具体的微服务请求背后
在我们对微服务架构有了整体的认识,并且具备了服务化的前提后,一个完整的微服务请求需要涉及到哪些内容呢?这其中包括了微服务框架所具备的三个基本功能:服务的发布与引用服务的注册与发现服务的远程通信服务的发布与引用首先我们面临的第一个问题是,如何发布服务和引用服务。具体一点就是,这个服务的接口名是啥,有哪些参数,返回值是什么类型等等,通常也就是接口描述信息。常见的发布和引用的方式包括:RESTFulAPI

当我们谈微服务,我们在谈什么(1)— 了解微服务

当我们谈微服务,我们在谈什么(1)— 了解微服务
微服务是什么抛去教条性质的解释,从巨石应用到微服务应用,耦合度是其中最大的变化。或是将多个模块中重复的部分进行拆分,或是纯粹为了拆分膨胀的单体应用,这些拆分出来的部分独立成一个服务单独部署与维护,便是微服务了。拆分后自然而然会催生出一些必要的需求:从本地方法调用的关系衍变成远程过程调用的关系,那么可靠的通信功能是首要的。随着拆分工作的推进,资源调度关系会变得错综复杂,这时候需要完善的服务治理。调用关

SOFA-MOSN 源码解析—配置详解

SOFA-MOSN 源码解析—配置详解
SOFAMosn 是基于 Go 开发的 sidecar,用于 servicemesh 中的数据面代理。官方文档见 SOFAMosn,基本架构如下:一个简单的结合 sofa-rpc 的例子可参考 SOFAMosn 代理 SOFARPC。观察到启动 mosn 形似./mainstart-cconfig.json,那么我们可以先从分析配置入手,看看 mosn 作为数据代理的整个流转过程。配置初探 config.json 的配置如下:{"se

SLF4J MDC 在全链路跟踪中的应用

经常做线上问题排查的可能会有感受,由于日志打印一般是无序的,多线程下想要串行拿到一次请求中的相关日志简直是大海捞针。那么 MDC 是一种很好的解决办法。SLF4J 的 MDCSLF4J 提供了 MDC(MappedDiagnosticContexts)功能,它的实现也是利用了 ThreadLocal 机制。在代码中,只需要将指定的值 put 到线程上下文的 Map 中,然后在对应的地方使用 get 方法获取对应的值,从而达到自

优雅地记录 http 请求和响应的数据

经常会遇到需要处理 http 请求以及响应 body 的场景。而这里比较大的一个问题是 servlet 的 requestBody 或 responseBody 流一旦被读取了。就无法二次读取了。针对这个问题,Spring 本身提供了解决方案,即 ContentCachingRequestWrapper/ContentCachingResponseWrapper。我们编写一个过滤器:publicabstractclassH

遇到 400、500 错误不要慌

很多人都会在平时开发过程中遇到 400 或 500 异常,并且也没有走到服务端 controller 中,就变得有些不知所措。我们知道 SpringMVC 从 DispatchServlet 开始接收与分发请求,从入口开始 debug,还能找不到问题所在么?从 DispatchServlet 的 doDispatch()方法开始处理请求:protectedvoiddoDispatch(HttpServletRequestreq

自适应采样算法在全链路跟踪中的应用

自适应采样算法在全链路跟踪中的应用
在实际生产环境中,全链路跟踪框架如果对每个请求都开启跟踪,必然会对系统的性能带来一定的压力。与此同时,庞大的数据量也会占用大量的存储资源,使用全量采样的场景很有限,大部分应用接入链路跟踪的初衷是错误异常分析或者样本查看。为了消除全量采样给系统带来的影响,设置采样率是一个很好的办法。采样率通常是一个概率值,取值在 0 到 1 之间,例如设置采样率为 0.5 的话表示只对 50% 的请求进行采样。在之前的采样算法之蓄水

自适应限流神器 netflix-concurrency-limits

自适应限流神器 netflix-concurrency-limits
作为应对高并发的手段之一,限流并不是一个新鲜的话题了。从 Guava 的 Ratelimiter 到 Hystrix,以及 Sentinel 都可作为限流的工具。自适应限流一般的限流常常需要指定一个固定值(qps)作为限流开关的阈值,这个值一是靠经验判断,二是靠通过大量的测试数据得出。但这个阈值,在流量激增、系统自动伸缩或者某某 commit 了一段有毒代码后就有可能变得不那么合适了。并且一般业务方也不太能够正确评估

调用链跨线程传递 ThreadLocal 对象

调用链跨线程传递 ThreadLocal 对象
在全链路跟踪框架中,Trace 信息的传递功能是基于 ThreadLocal 的。但实际业务中可能会使用异步调用,这样就会丢失 Trace 信息,破坏了链路的完整性。在同一线程中 trace 信息的传递流程使用代码模拟如下:ThreadLocal<String>traceContext=newThreadLocal<>();StringtraceId=Tracer.startServer();traceConte

结合 Ribbon 实现微服务故障自动剔除

结合 Ribbon 实现微服务故障自动剔除
Ribbon 是 Netflix 出品的一套负载均衡组件,提供了许多 Rule 规则从负载列表中选取合适的 server 实例。当实例出现问题时候,需要将这部分异常的服务提供者从负载列表中剔除,从而避免雪崩效应。而 Riibbon 本身具有自动移除问题实例的功能,于是我们可以结合 Ribbon 对现有的负载均衡策略做一些改进,实现自动故障剔除功能。工作流程 Ribbon 中实现自动移除问题实例的 Rule 是 Availabili

采样算法之蓄水池算法

全链路跟踪框架 Hunter 中原先的采样算法在高并发的情况下会出现问题,原有代码如下:protectedbooleandoSampled(finalfloatsampleRate){finalSpanCollectorMetricHandlermetricHandler=getMetricHandler();finallongcollectedCount=metricHandler.getCollec

基于 Hunter 的 Thrift RPC 调用链跟踪

基于 Hunter 的 Thrift RPC 调用链跟踪
Hunter 是我司自研的全链路跟踪框架,最近有集成 Thrift 的改造需求,先来看看通信链路传递信息的大致架构。##通信链路信息传递首先对于远程通信的链路埋点来说,有两个关键信息需要传递,即 traceId 与 spanId(parentspanId)。通信方式目前 Hunter 只支持 Http 一种。而 Http 利用 header 来传递 trace 信息也十分方便(traceId,spanId)。Client 端采用封装

微服务的优雅上下线

微服务的优雅上下线
对于微服务来说,服务的优雅上下线是必要的。就上线来说,如果组件或者容器没有启动成功,就不应该对外暴露服务,对于下线来说,如果机器已经停机了,就应该保证服务已下线,如此可避免上游流量进入不健康的机器。优雅下线基础下线(Spring/SpringBoot/内置容器)首先 JVM 本身是支持通过 shutdownHook 的方式优雅停机的。Runtime.getRuntime().addShutdownHook(

关于 Undertow 和 RxNetty 的一次错误排查

undertow 是一个快速高性能的容器。但在 SpringBoot 中集成 undertow 作为内置容器后,测试我司 RPC 框架序列化扩展的时候却发生了错误。客户端报的异常,仅仅是判断出报了一个 400BadRequest,没有其他任何有效信息。首先需要确定是客户端出现的问题还是服务端出现的问题,先从客户端角度入手,比较单测调用和 postMan 调用,结果单测是有问题的,而 postMan 是好的,那么问题肯定出现