一时无两


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

聊聊RPC的超时时间

发表于 2017-07-31 | 分类于 解决方案
聊聊RPC的超时时间开篇这个故事的起因是我在和中间件的同事们聊天的时候聊到的。关于超时时间,目前大部分的做法是按照最大正常相应时间设置,而并非一个TP995得出来的平均响应时间之类的。举个例子: 这是我在我们这边的监控系统上随机抓了个请求的响应时间分布,大体上是这样的,某个时间段内:4561次请求,4489次的响应时间在30ms之内,69次在200ms之内,3次在1000ms之内。 我们现在通常的做法是设置一个1000ms的超时时间。为什么,因为毕竟那三次都是正常的请求,只是因为一些特殊原因导致响应时间比较久(比如:获取某个用户的歌单的时候,某几个用户关注了几万个歌单,那么查询时间也好,数据 ...
阅读全文 »

记一次Disruptor排坑

发表于 2017-07-26 | 分类于 线上问题排查
记一次Disruptor排坑 Abstract我们在项目中使用了Disruptor作为事件总线,实现的业务是:用户消费完成成就,完成八个成就之后自动获得第九个成就——获得前面八个成就。 这个项目不是我参与的,当时我自己封装的高性能事件总线(Electrons)已经完全能胜任上述功能,但是由于小伙伴当时对我的这个组件没有特别研究,仍然感觉我的这个就是顺序执行前面几个监听器,就没有用。 这个项目在测试环境中一直没有问题,原因我分析一下有下: 并发量太小,RingBuffer的队列的size太小都完全足够。 测试环境中代码不稳定,经常重启服务器,导致有些问题被我们的重启掩盖掉了。 问题出现这个项 ...
阅读全文 »

记一次并发场景下的问题排查

发表于 2017-04-24 | 分类于 线上问题排查
记一次并发场景下的问题排查 上周周四,项目上线,我负责的部分主要是账单重构,说来也巧,本来是没有这个需求的,由于当时划分给我的项目其实已经被别的线接走了,后来经过讨论,这次的业务需要其他线支持,一下任务少了一大截,比较轻松,看了看下单流程,代码不符合我的审美就给重构了(现在想想真是自信过头,没经过架构评审,模型纯自己写的,就给重构了。。果不其然。。)。废话不说,直接进入正题。 问题出现四点钟上线完成,盯着日志,发现一单下单异常,仔细看了一下发现入参少了一个参数,问题很神奇,没有这个参数的情况下按理来说就不应该走到相应的流程去,但是却走进去了,这时候还没当回事,毕竟上线过程中,机器重启啥问题都可 ...
阅读全文 »

Java阻塞队列的原理分析

发表于 2017-04-11 | 分类于 java源码
Java阻塞队列的原理分析 先看看BlockingQueue接口的文档说明: add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出IllegalStateException异常; offer:添加元素到队列里,添加成功返回true,添加失败返回false; put:添加元素到队列里,如果容量满了会阻塞直到容量不满; poll:删除队列头部元素,如果队列为空,返回null。否则返回元素; remove:基于对象找到对应的元素,并删除。删除成功返回true,否则返回false; take:删除队列头部元素,如果队列为空,一直阻塞到队列有元素并删除。 先看一个简单的Arra ...
阅读全文 »

Electrons使用指南

发表于 2017-03-21 | 分类于 java插件
Electrons使用指南前言Electrons是一个异步事件分发器,也是一个通道,结合了生产者消费者模型和SUB/PUB模式。传统的SUB/PUB模型,在publish事件的时候是直接同步执行所有的监听器,是同步阻塞的。现在结合RINGBUFFER的无锁的急速体验,设计了Electrons,意味电路,事件就相当于跑在电路中的电子,电子在电路中的传递速度非常之快,这也是这个插件的寓意。publish的事件会放到容器中等待消费者消费,消费者就是SUB方的listener,这里有个设计上的小缺陷,由于种种愿意,listener的注册是通过注解 + 接口的方式实现,后面会提到。下面进入主题 使用废话 ...
阅读全文 »

Go语言中的Dispatcher

发表于 2017-03-09 | 分类于 go语言底层
Go语言中的DispatcherGo使用goroutines来处理connection的读写事件,不会阻塞: 12345c, err := srv.newConn(rw) if err != nil { continue } go c.serve() c即为创建的connection,保存了该次请求的信息,然后再传递到对应的handler,handler就可以读取到请求的header信息,保证了请求之间独立。 Go中的ServeMux上面代码中提到了c(这个c就是connection).serve()方法。其实内部是调用了http包默认的路由器,通 ...
阅读全文 »

wait和notify实现分析

发表于 2017-03-06 | 分类于 java源码
深入分析Object.wait和notify实现机制同一个obj对象调用wait、notify方法。 当线程A执行wait方法时,该线程被挂起。 当线程B执行notify方法时,唤醒一个被挂起的线程A。 lock对象、线程A和线程B三者是一种什么关系?根据上面的结论,可以想象一个场景: lock对象维护了一个等待队列list; 线程A中执行lock的wait方法,把线程A保存到list中; 线程B中执行lock的notify方法,从等待队列中取出线程A继续执行。 使用过程中有这么几个疑问: 进入wait/notify之前为什么要获取synchronized? 线程A获取了synchr ...
阅读全文 »

Go语言中的Continuous Stack(连续栈)

发表于 2017-02-25 | 分类于 go语言底层
Go语言中的Continuous Stack(连续栈)前言Go语言支持goroutine,每个goroutine需要能够运行,所以它们都有自己的栈。假如每个goroutine分配固定栈大小并且不能增长,太小则会导致溢出,太大又会浪费空间,无法存在许多的goroutine。为了解决这个问题,goroutine可以初始时只给栈分配很小的空间,然后随着使用过程中的需要自动地增长。这就是为什么Go可以开千千万万个goroutine而不会耗尽内存。Go1.3版本之后则使用的是continuous stack。 基本原理每次执行函数调用时Go的runtime都会进行检测,若当前栈的大小不够用,则会触发“中 ...
阅读全文 »

Go语言中的闭包

发表于 2017-02-25 | 分类于 go语言底层
Go语言中的闭包 先看一个demo: 123456func f(i int) func() int { return func() int { i++ return i }} 函数f返回了一个函数,返回的这个函数就是一个闭包。这个函数中本身是没有定义变量i的,而是引用了它所在的环境(函数f)中的变量i。 我们再看一下效果: 1234c1 := f(0)c2 := f(0)c1() // reference to i, i = 0, return 1c2() // reference to another ...
阅读全文 »

深克隆插件 -- FKC

发表于 2017-02-25 | 分类于 深克隆
年前没机会分享我写的插件了,这里也做个总结吧:1.深克隆有几种实现方法: (1)最low的,大家都会的,get set get set get set巴拉巴拉。(缺点:显而易见,不通用,而且代码非常的丑陋!)(2)对象流读入,対向流读出,这其实就是一个序列化反序列化。(缺点:流是非常占用资源的,不停地new close会消耗CPU,一个请求过来要进行几次new操作,会导致GC非常频繁,还有就是原生速度比较慢) 2.针对以上第二种实现方法,设计了一个深克隆的插件,特点和实现如下: (1)针对原生序列化反序列化慢,使用kryo做序列化反序列化处理,kryo底层其实还是用了原生的流,只不过进行了一 ...
阅读全文 »
1…789
时无两

时无两

88 日志
24 分类
84 标签
GitHub E-Mail
© 2020 时无两
主题 — NexT.Pisces v5.1.3