微服务 0 篇文章

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

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

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

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

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

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

微服务的优雅上下线

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

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

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

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

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

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

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

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

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

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

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

基于 Hunter 的 Thrift RPC 调用链跟踪

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

调用链跨线程传递 ThreadLocal 对象

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

采样算法之蓄水池算法

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