当前位置: 首页 > news >正文

简易的RPC调用框架(大神写的)

 

RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样。

RPC 可基于 HTTP 或 TCP 协议,Web Service 就是基于 HTTP 协议的 RPC,它具有良好的跨平台性,但其性能却不如基于 TCP 协议的 RPC。会两方面会直接影响 RPC 的性能,一是传输方式,二是序列化。

众所周知,TCP 是传输层协议,HTTP 是应用层协议,而传输层较应用层更加底层,在数据传输方面,越底层越快,因此,在一般情况下,TCP 一定比 HTTP 快。就序列化而言,Java 提供了默认的序列化方式,但在高并发的情况下,这种方式将会带来一些性能上的瓶颈,于是市面上出现了一系列优秀的序列化框架,比如:Protobuf、Kryo、Hessian、Jackson 等,它们可以取代 Java 默认的序列化,从而提供更高效的性能。

为了支持高并发,传统的阻塞式 IO 显然不太合适,因此我们需要异步的 IO,即 NIO。Java 提供了 NIO 的解决方案,Java 7 也提供了更优秀的 NIO.2 支持,用 Java 实现 NIO 并不是遥不可及的事情,只是需要我们熟悉 NIO 的技术细节。

我们需要将服务部署在分布式环境下的不同节点上,通过服务注册的方式,让客户端来自动发现当前可用的服务,并调用这些服务。这需要一种服务注册表(Service Registry)的组件,让它来注册分布式环境下所有的服务地址(包括:主机名与端口号)。

应用、服务、服务注册表之间的关系见下图:

系统架构

每台 Server 上可发布多个 Service,这些 Service 共用一个 host 与 port,在分布式环境下会提供 Server 共同对外提供 Service。此外,为防止 Service Registry 出现单点故障,因此需要将其搭建为集群环境。

本文将为您揭晓开发轻量级分布式 RPC 框架的具体过程,该框架基于 TCP 协议,提供了 NIO 特性,提供高效的序列化方式,同时也具备服务注册与发现的能力。

根据以上技术需求,我们可使用如下技术选型:

  1. Spring:它是最强大的依赖注入框架,也是业界的权威标准。
  2. Netty:它使 NIO 编程更加容易,屏蔽了 Java 底层的 NIO 细节。
  3. Protostuff:它基于 Protobuf 序列化框架,面向 POJO,无需编写 .proto 文件。
  4. ZooKeeper:提供服务注册与发现功能,开发分布式系统的必备选择,同时它也具备天生的集群能力。

相关 Maven 依赖请见附录。

第一步:编写服务接口

<!-- lang: java -->
public interface HelloService {

    String hello(String name);
}

将该接口放在独立的客户端 jar 包中,以供应用使用。

第二步:编写服务接口的实现类

<!-- lang: java -->
@RpcService(HelloService.class) // 指定远程接口 public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { return "Hello! " + name; } } 

使用RpcService注解定义在服务接口的实现类上,需要对该实现类指定远程接口,因为实现类可能会实现多个接口,一定要告诉框架哪个才是远程接口。

RpcService代码如下:

<!-- lang: java -->
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component // 表明可被 Spring 扫描
public @interface RpcService {

    Class<?> value(); } 

该注解具备 Spring 的Component注解的特性,可被 Spring 扫描。

该实现类放在服务端 jar 包中,该 jar 包还提供了一些服务端的配置文件与启动服务的引导程序。

第三步:配置服务端

服务端 Spring 配置文件名为spring.xml,内容如下:

<!-- lang: xml --> <beans ...> <context:component-scan base-package="com.xxx.rpc.sample.server"/> <context:property-placeholder location="classpath:config.properties"/> <!-- 配置服务注册组件 --> <bean id="serviceRegistry" class

相关文章:

  • 捕捉Web页面子类错误堆栈中的信息
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • 2010年9月blog汇总:敏捷个人和模型驱动开发
  • Eclipse:应该掌握的快捷键
  • 图像处理时用的卷积函数
  • asp.net web api
  • 各浏览器对页面外部资源加载的策略
  • 收藏 c#小函数
  • 解决Page.FindControl方法找不到指定控件 转
  • 二台电脑之间数据库文件进行备份
  • Oracle 发布 NoSQL 数据库
  • IBM Java多线程 - 5.同步详细信息
  • 收藏一个数学的C++算法的好博客
  • delphi 脚本引擎比较
  • Angular2开发踩坑系列-生产环境编译
  • Create React App 使用
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • input的行数自动增减
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Octave 入门
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • Wamp集成环境 添加PHP的新版本
  • 大快搜索数据爬虫技术实例安装教学篇
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 设计模式 开闭原则
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $.ajax中的eval及dataType
  • (1)bark-ml
  • (2)nginx 安装、启停
  • (5)STL算法之复制
  • (8)STL算法之替换
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (论文阅读11/100)Fast R-CNN
  • (算法二)滑动窗口
  • (一)Dubbo快速入门、介绍、使用
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .htaccess配置常用技巧
  • .Net - 类的介绍
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NetCore 如何动态路由
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • @media screen 针对不同移动设备
  • @ModelAttribute使用详解
  • @Transactional 竟也能解决分布式事务?
  • @软考考生,这份软考高分攻略你须知道
  • [ 2222 ]http://e.eqxiu.com/s/wJMf15Ku
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • [Android开源]EasySharedPreferences:优雅的进行SharedPreferences数据存储操作