实现思路:
服务之间的通信,无非就是实现数据的传输,中间件之所以快,一些通用手段必不可少.如:
在加大单位时间内传输响应速度,减小数据量,加快序列化速度,持久到磁盘的速度等:
1.大单位时间内传输响应速度:
相对于BIO同步等待,NIO单线程发送,异步回调以及批量发送,都很好的提高的发送端的并发能力
2.减小数据量:
实现自己的通讯协议,比如redis的resp协议,mq的amqp协议,比http协议传输数据量要小很多;
我们在传输数据的的时候,首先要解决的就是断句问题。比如 HTTP1 协议,它的分隔符是换行(\r\n)。但是,这个办法有一个问题比较难处理,在自然语言中,标点符号是专用的,它没有别的含义,和文字是有天然区分的。
在数据传输的过程中,无论你定义什么字符作为分隔符,理论上,它都有可能会在传输的数据中出现。为了区分“数据内的分隔符”和真正的分隔符,你必须得在发送数据阶段,加上分隔符之前,把数据内的分隔符做转义,收到数据之后再转义回来。这是个比较麻烦的过程,还要损失一些性能。
更加实用的方法是,我们给每句话前面加一个表示这句话长度的数字,收到数据的时候,我们按照长度来读取就可以了。这种预置长度的方法就很好解决了断句的问题,并且它实现起来要比分隔符的方法简单很多,性能也更好,是目前普遍采用的一种分隔数据的方法。
3.加快序列化速度:
面对这么多种序列化实现,我们该如何选择呢?你需要权衡这样几个因素:
- 序列化后的数据最好是易于人类阅读的;
- 实现的复杂度是否足够低;
- 序列化和反序列化的速度越快越好;
- 序列化后的信息密度越大越好,也就是说,同样的一个结构化数据,序列化之后占用的存储空间越小越好
在专用的序列化方法中,不必考虑通用性。比如,我们可以固定字段的顺序,这样在序列化后的字节里面就不必包含字段名,只要字段值就可以了,不同类型的数据也可以做针对性的优化,但这样需要为每种对象类型定义专门的序列化和反序列化方法,实现起来太复杂了,大部分情况下是不划算的。
4.持久到磁盘的速度:
数据写入硬盘之前,都会先储存在服务器告诉缓存中,何时刷盘是由操作系统控制的,但是我们可以手段刷盘,mysql中是每次写数据都主动刷盘.效率较慢...........
5.双工通讯
HTTP1 协议,是一种单工协议,客户端与服务端建立一个连接后,客户端发送一个请求,直到服务端返回响应或者请求超时.
要实现可以实现双工通信,发送请求的时候,给每个请求加一个序号,这个序号在本次会话内保证唯一,然后在响应中带上请求的序号,这样就可以把请求和响应对应上了。