一个学习式的mogoLink框架介绍
https://github.com/penkee/mogoLink
mogoLink是我于2016年开始设计的一个rpc框架,当时只是接触了Netty技术,觉得它非常适合做rpc框架的底层通讯。对于编解码产品,选用的是谷歌的protoBuf,不过苦于它的schema和每个类都得静态编译问题无法解决,然后耽搁下来。而那时候各大公司尚未服务化改造,故开发此框架经验不足,考虑不周。
今年公司开展服务化工作,此时又接触了dubbo,spring cloud相关书籍,系统介绍了设计rpc的理论基础。故而有重新维护此项目。
那么设计一个rpc框架,需要注意哪些地方呢?
- socket通讯框架:一般这个框架目前也只有netty开源的,上手快,性能也杠杠的
- 编解码技术:java序列化、谷歌的protobuf、facebook thift、jboss marshaling、kryo、json、hession、aryo
- 粘包处理:消息定长、消息尾加分隔符、消息头加表示长度的字段、其他复杂的应用层协议
- 服务注册中心:分布式系统用的,管理可用的服务地址
- 负载均衡算法:客户端用的,分散请求不同的服务器
- 限流熔断处理:服务端用,防止请求过多,造成服务中断的
- 监控系统:监控服务调用次数,耗时,客户端连接数等信息
- 日志跟踪系统:由于会级联调用多层rpc,所以要生成唯一标识来跟踪调用链的日志收集系统
上图是本系统的设计流程图,虽然糙了点,但能看明白就行。
- FutureObject类,用于获取未来的对象的。因为netty接收消息是异步的,所以只能用此对象作为沟通工具,当服务端接收到消息时放入此对象里,则监听端就立刻获取到对象,否则超时处理
/*** @brief 获取未来对象* @details (必填)* @author 彭堃* @date 2016年8月26日下午5:56:29*/
public class FutureObject<T> {private T value;public T get(long outTime) {if (value == null) {synchronized (this) {try {this.wait(outTime);} catch (InterruptedException e) {e.printStackTrace();}}}return value;}public void set(T value) {this.value = value;synchronized (this) {this.notify();}}
}
客户端的代理方法:这样所有加@Autowird的接口,spring自动注入成工厂类产生的代理对象,当调用服务方法时,则代码执行代理的请求远程的服务
<bean id="userInfoRemoteService" class="com.eastorm.mogolink.client.proxy.ProxyFactory"><constructor-arg name="className" value="com.eastorm.mogolink.demo.client.service.api.IUserInfoService" /></bean>
/*** 创建动态代理对象* 动态代理不需要实现接口,但是需要指定接口类型* @author 慕容恪*/
public class ProxyFactory implements FactoryBean {private static final Logger logger = LoggerFactory.getLogger(ProxyFactory.class);private String className;public ProxyFactory(String className){this.className=className;}public Object getProxyInstance() throws ClassNotFoundException {Class target=Class.forName(className);return Proxy.newProxyInstance(target.getClassLoader(), new Class[]{target},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//无需代理的父类方法if("toString".equals(method.getName())){return method.invoke(proxy,args);}BaseMessage req=new BaseMessage();UUID uuid = UUID.randomUUID();req.setRequestId(uuid.toString());List<MethodParam> paramTypes=new ArrayList<>();if(args!=null&&args.length>0){for (Object arg : args) {paramTypes.add(new MethodParam(arg.getClass().getName(),arg));}}req.setParamTypes(paramTypes);req.setServiceName(className);req.setMethod(method.getName());long s=System.currentTimeMillis();ClientMsgHandler handler= ClientStarter.getHandler();if(handler==null){logger.info("请求失败req={},耗时:{}ms",req.getRequestId(),System.currentTimeMillis()-s);return null;}// Request and get the response.BaseMessage resMsg = handler.getData(req);if(resMsg!=null&&resMsg.getCode().equals(ServiceCodeEnum.SUCCCESS.getId())){logger.info("req={},耗时:{}ms",resMsg.getRequestId(),System.currentTimeMillis()-s);return resMsg.getReturnData();}else{logger.info("失败req={},耗时:{}ms",req.getRequestId(),System.currentTimeMillis()-s);}return null;}});}@Overridepublic Object getObject() throws Exception {return getProxyInstance();}@Overridepublic Class<?> getObjectType() {Class target= null;try {target = Class.forName(className);} catch (ClassNotFoundException e) {e.printStackTrace();}return target;}@Overridepublic boolean isSingleton() {return true;}
}
- channel连接池
一个客户端如果只连接一个channel,那岂不是暴殄天物。一个channel是同步阻塞的,所有这里每个客户端要有一个channel连接池。本系统采用是apache的common-pool工具类,来维护channel连接。
- 粘包问题
本框架采用消息头加消息长度字段的方式实现,具体的类是netty自带的LengthFieldBasedFrameDecoder。我们在kryo编码器里加了一行头长度字段。
@Overrideprotected void encode(ChannelHandlerContext channelHandlerContext, BaseMessage baseMessage, ByteBuf byteBuf) throws Exception {byte[] data= messageCodec.serialize(baseMessage);byteBuf.writeShort(data.length);byteBuf.writeBytes(data);}
如果能确定编码后不包含分割符,也是可以用分隔符处理的,更节约。
- 消息体的定义:方法支持重载,故需要方法参数的class名
ublic class BaseMessage {private String requestId;private String code;private String msg;/*** 返回的信息*/private Object returnData;/*** 服务名*/private String serviceName;/*** 方法*/private String method;/*** 方法的参数类型* 用来转型*/private List<MethodParam> paramTypes;
}
一个学习式的mogoLink框架介绍相关推荐
- 深度学习平台——Paddle核心框架介绍
摘要 本博文将最后的讲解和学习有关于的Paddle的核心框架的分享.并且有关于的Paddle的学习就暂时告一段落.后期本人将更多的在与深度学习的原理和利用Paddle开发自己的深度学习模型作为分享.飞 ...
- 深度学习主流框架介绍(PyTorch、TensorFlow、Keras、Caffe、Theano、MXNET)
深度学习主流框架介绍(PyTorch.TensorFlow.Keras.Caffe.Theano.MXNET) 1.Theano Theano是最早的深度学习框架之一,由 Yoshua Bengio ...
- Python黑马头条推荐系统第四天 TensorFlow框架介绍和深度学习
深度学习与推荐系统 6.1 推荐系统与深度学习关联 学习目标 目标 无 应用 无 6.1.1 深度学习到推荐系统 深度学习发展成功与局限 最近几年深度学习的流行,大家一般认为是从2012年 AlexN ...
- 每天学习一个Android中的常用框架——0.目录
文章目录 1.前言 2.环境 3.目录 3.1 持久化 3.1.1 Litepal 3.1.2 GreenDao 3.1.3 Realm 3.1.4 DBFlow 3.2 网络传输 3.2.1 OkH ...
- keras 自定义层input_从4个方面介绍Keras和Pytorch,并给你选择其中一个学习库的理由...
全文共3376字,预计学习时长7分钟 对许多科学家.工程师和开发人员而言,TensorFlow是他们的第一个深度学习框架. TensorFlow 1.0于2017年2月发布:但客观来说,它对用户不是非 ...
- 八.激光SLAM框架学习之LeGO-LOAM框架---框架介绍和运行演示
专栏系列文章如下: 一:Tixiao Shan最新力作LVI-SAM(Lio-SAM+Vins-Mono),基于视觉-激光-惯导里程计的SLAM框架,环境搭建和跑通过程_goldqiu的博客-CSDN ...
- 二.激光SLAM框架学习之A-LOAM框架---介绍及其演示
专栏系列文章如下: 一:Tixiao Shan最新力作LVI-SAM(Lio-SAM+Vins-Mono),基于视觉-激光-惯导里程计的SLAM框架,环境搭建和跑通过程_goldqiu的博客-CSDN ...
- 百度官方文档Plus版,PaddlePaddle深度学习框架介绍
作者:木羊同学 来源:华章计算机(hzbook_jsj) 现在深度学习框架不但内卷严重,而且头部效应明显.一提起深度学习框架,首先想到的肯定是Google家的TensorFlow,和Facebook家 ...
- 国产首款——飞桨PaddlePaddle深度学习框架介绍
现在深度学习框架不但内卷严重,而且头部效应明显.一提起深度学习框架,首先想到的肯定是Google家的TensorFlow,和Facebook家的PyTorch.究竟排名谁先谁后,还要看你是工业界还是学 ...
最新文章
- [摘录]第8章 与非美国人谈判的技巧
- ios 旋转加载gif_加载GIF动画方法 iOS
- linux中sudo如何读取标准输入作为密码,避免每次都输入密码?
- boost::hana::remove_at用法的测试程序
- 用类,求三个数的最大数
- Hbase1.2数据导入2.0
- 计算机类自主招生推荐信,自主招生推荐信范文:中国人民大学自主招生推荐信...
- react学习预备知识_在10分钟内学习React基础知识
- webpack 的使用1
- RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势...
- chapter10--进程和计划任务管理
- 腾讯云一站式物联PaaS平台IOT Suite助力行业加速“物联网+”
- LeetCode--Reverse Integer(整数反转)Python
- python map函数filter函数 day16
- 若依集成yuicompressor实现(CSS/JS压缩)
- Android 悬浮窗的实现(类似于360加速球)
- 全球及中国毛巾产品市场盈利前景与供需调查分析报告2022版
- c51数字钟c语言程序,51单片机电子时钟C语言程序
- python圣诞树代码成品图片动态_基于JS2Image实现圣诞树代码
- 7、KSQL刨根问底和实战操作教程
热门文章
- 硬盘插上后提示“设备未就绪”の解决方案
- layui define 的使用
- cisco(思科)交换机操作(基本查询命令)【一】
- linux键盘背光指令,在Linux下开启背光Led键盘的背光
- 这一季绿色智能制造“英雄联盟”已集结, 有哪些新鲜点?
- 简单的实现app界面劫持和后台监控
- Appium自动化测试(五)——PO模式(一):短信案例
- SpringMVC在web.xml中配置DispatcherServlet拦截了静态资源访问
- 软件公司防止代码外泄的几种方法介绍
- 上传图片为线上图片,可以在线访问