##架构:
通信核心层:使用 socket 和 netty 框架进行网络通信,制定通信协议,使用反射传递服务方调用方数据
代理层:封装 构建发送消息,发现服务,负载均衡,故障容错,拦截器的创建,简化调用服务方操作
注册中心:使用 zookeeper 作为注册中心,对服务提供方的服务进行管理
路由层:使用轮询算法对多个服务提供方进行选择
容错层:对调用提供方服务出现异常,进行故障转移或者忽略错误
拦截器层:提供安全校验服务
SPI层:服务发现机制,实现微内核+插件形式设计,使用用户spi和系统spi,用户能够通过插件的形式自己实现组件,更改组件
设计模式 代理模式:抽取复杂重复的发送消息逻辑,交给代理类处理,屏蔽底层逻辑,简化调用方操作
工厂模式+单例模式:将系统 spi 和用户 spi 需要加载的类放入一个缓存 map 中,各个工厂按需获取对应的类,统一管理对象
责任链模式:对 client 和 server 的工厂进行按序初始化
观察者模式:引入zk,通过观察者模式,当服务方在 zk 中注册服务时,调用方会被通知
黏包,半包问题 黏包问题:很多个请求用同一个连接发送,服务端收到的数据会包含多个请求
半包问题:使用 TCP 进行网络传输,一次发送的数据大于TCP的发送缓冲区(16KB),需要分成多次进行传输,导致服务端单次接收的数据不完整
解决: 调用方和服务提供方制定协议,将数据大致信息写入请求头中,将具体的数据写入请求体中进行读取,固定请求头长度,使用解码器判断是否接收完完整消息
协议 magic:保证安全性,防止伪造协议
version:协议版本信息
msgType:消息类型,请求or响应,再做不同处理
status:状态
requestId:请求id,唯一
serializationLen:序列化数组长度
serialization:序列化方式
msgLen:请求体消息长度
data:请求体消息 image#S #R #100% #100%
请求头必须固定,不然多出的部分会被当作请求体被读出,所以请求头中不能放置不定长的数组 image#S #R #100% #100%
负载均衡算法 轮询:按照请求顺序分发到服务器组
随机:随机发送请求到服务器
权重:根据不同的服务器权重占比分发请求
IP哈希:根据客户端 ip 计算哈希值取模访问服务器
URL哈希:根据 URL 地址计算哈希取模
一致性哈希:使用一致性 hash 算法,相同的IP或URL请求总是发送到统一服务器
最少连接:将新请求发送到当前客户端连接数最少的服务器
最短时间:请求发送到最快响应时间和最少活动连接数的服务器
序列化方式 JDK:java内置序列化,相比其他序列化性能更低,序列化后的字节数组体积大,传输成本加大,有安全漏洞
Kryo:高性能,有变长存储特性以及使用了字节码生成机制,运行速度较快,生成的字节码体积较小
Hessian:高效的二进制序列化方式
fastjson:速度快,使用简单,功能完备
容错机制 故障转移:如果当前服务出错,遍历剩余服务,如果无服务能使用,忽略
重试策略:设定最大重试次数和重试时间,对该服务进行重试