RPC服务的发布订阅实现Thrift
Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)
前言:
  Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还是有一定距离, 本系列将对Thrift作代码解读和框架扩充, 使得它更加贴近生产环境. 本文讲述如何借用zookeeper来实现中介角色, 使得服务端和客户端解耦, 并让RPC服务平台化发展.
基础架构:
  RPC服务往平台化的方向发展, 会屏蔽掉更多的服务细节(服务的IP地址集群, 集群的扩容和迁移), 只暴露服务接口. 这部分的演化, 使得server端和client端完全的解耦合. 两者的交互通过ConfigServer(MetaServer)的中介角色来搭线.
  
  注: 该图源自dubbo的官网
  这边借助Zookeeper来扮演该角色, server扮演发布者的角色, 而client扮演订阅者的角色.
Zookeeper基础:
  Zookeeper是分布式应用协作服务. 它实现了paxos的一致性算法, 在命名管理/配置推送/数据同步/主从切换方面扮演重要的角色. 
  其数据组织类似文件系统的目录结构:
  
  每个节点被称为znode, 为znode节点依据其特性, 又可以分为如下类型:
  1). PERSISTENT: 永久节点
  2). EPHEMERAL: 临时节点, 会随session(client disconnect)的消失而消失
  3). PERSISTENT_SEQUENTIAL: 永久节点, 其节点的名字编号是单调递增的
  4). EPHEMERAL_SEQUENTIAL: 临时节点, 其节点的名字编号是单调递增的
  注: 临时节点不能成为父节点
  Watcher观察模式, client可以注册对节点的状态/内容变更的事件回调机制. 其Event事件的两类属性需要关注下:
  1). KeeperState: Disconnected,SyncConnected,Expired
  2). EventType: None,NodeCreated,NodeDeleted,NodeDataChanged,NodeChildrenChanged
RPC服务端:
  作为具体业务服务的RPC服务发布方, 对其自身的服务描述由以下元素构成.
  1). product: 产品名称 
  2). service: 服务接口, 采用发布方的类全名来表示
  3). version: 版本号
  借鉴了Maven的GAV坐标系, 三维坐标系更符合服务平台化的大环境.	
  *) 数据模型的设计
  具体RPC服务的注册路径为: /rpc/{product}/{service}/{version}, 该路径上的节点都是永久节点
  RPC服务集群节点的注册路径为: /rpc/{product}/{service}/{version}/{ip:port}, 末尾的节点是临时节点
  *) RPC服务节点的配置和行为
  服务端的配置如下所示:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
 | 
<register>  <server>{ip:port => Zookeeper的地址列表}</servers>  <application>{application name => 服务的应用程序名}</application></register><server>  <interface>{interface => 服务接口名}</interface>  <version>{version => 服务版本号}</version>  <class>{class => interface的具体实现Handler类}</class>  <port>{提供服务的监听端口}</port></server> | 
服务端的注册逻辑:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
 | 
Zookeeper zk = new Zookeeper("127.0.0.1:2181", timeout, null);while ( !application exit ) {  Stat stat = zk.exists("/rpc/{product}/{service}/{version}/{ip:port}", false);  if ( stat == null ) {    zk.create("/rpc/{product}/{service}/{version}/{ip:port}", Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);  }   Thread.sleep(wait_timeout);}    | 
注: zookeeper client与zookeeper的断开会导致临时节点的丢失, 因此需要重新构建, 这边采用开启一个循环线程, 用于定时轮询.
RPC客户端:
  客户端的简单注册配置:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
<register>  <server>{ip:port => Zookeeper的地址列表}</servers>  <application>{application name => 服务的应用程序名}</application>  </register><service>  <interface>{interface => 服务接口名}</interface>  <version>{version => 服务版本号}</version></sevice>  | 
  客户端的代码:
  1). 初始获取server列表
| 
 1 
2 
 | 
Zookeeper zk = new Zookeeper("127.0.0.1:2181", timeout, null);List<String> childrens = zk.getChildren(path, true); | 
2). 注册Watcher监听, EventType.NodeChildrenChanged事件, 每次回调, 重新获取列表
| 
 1 
2 
3 
4 
5 
6 
7 
8 
 | 
class WatcherWarpper implements Watcher {  public void process(WatchedEvent event) {    if ( event.getType() == EventType.NodeChildrenChanged ) {      List<String> childrens = zk.getChildren(path, true);      // notify Thrift client, rpc service的server ip:port列表发生了变化        }  }} | 
总结:
这部分其实涉及thrift点并不多, 但该文确实是rpc服务平台化的理论基础. 服务端作为服务的发布方, 而客户端借助zookeeper的watcher机制, 来实现其对服务列表的订阅更新功能. 从而达到解耦, 迈出服务平台化的一步.
后续:
  后续文章讲解Thrift client连接池的实现, 也是比较基础的一部分, 敬请期待.
RPC服务的发布订阅实现Thrift的更多相关文章
- Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)
		
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
 - 刚学会 C++ 的小白用这个开源框架,做个 RPC 服务要多久?
		
本文适合有 C++ 基础的朋友 本文作者:HelloGitHub-Anthony HelloGitHub 推出的<讲解开源项目>系列,本期介绍基于 C++ 的 RPC 开源框架--rest ...
 - log4j2自定义Appender(输出到文件/RPC服务中)
		
1.背景 虽然log4j很强大,可以将日志输出到文件.DB.ES等.但是有时候确难免完全适合自己,此时我们就需要自定义Appender,使日志输出到指定的位置上. 本文,将通过两个例子说明自定义APP ...
 - 使用thrift实现订阅服务和发布服务
		
使用thrift实现订阅服务和发布服务 服务:订阅服务 market_subscriber 和 发布服务 market_publisher功能:market_subscriber 能够向 market ...
 - Thrift 个人实战--Thrift RPC服务框架日志的优化
		
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
 - 【9】JMicro微服务-发布订阅消息服务
		
如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 1. JMicro消息服务目前实现特性 a. JMicro只支持发布订阅消息服务,不支持队列式消息服务: b. 不支持消息持 ...
 - dubbo 订阅 RPC 服务
		
Dubbo 订阅 RPC 服务 建立消费者者项目 pom.xml <?xml version="1.0" encoding="UTF-8"?> &l ...
 - “一切都是消息”--MSF(消息服务框架)之【发布-订阅】模式
		
在上一篇,“一切都是消息”--MSF(消息服务框架)之[请求-响应]模式 ,我们演示了MSF实现简单的请求-响应模式的示例,今天来看看如何实现[发布-订阅]模式.简单来说,该模式的工作过程是: 客户端 ...
 - “一切都是消息”--iMSF(即时消息服务框架)之【发布-订阅】模式
		
MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately)消息,所以iMSF就是 immediately Message S ...
 
随机推荐
- 重写IHttpHandler,实现前后端分离
			
再说重写IHttpHandler,实现前后端分离 aspx页面第一次加载时,HttpHandler 里面是如何编译指定页面的呢?Framework提供了编译页面的API如下: BuildManag ...
 - SVN和Git的一些用法总结(转)
			
转载请注明出处:http://www.codelast.com/ 以下都是比较基础的操作,高手们请绕道,不必浪费时间来看了. (A)SVN (1)查看日志提交的时候一般会写上注释,如果要查看提交日志, ...
 - 关于在 xmlSPY 出现的错误 DOCTYPE-EXternalID的名称必须既是SYSTEM 又是PUBLIC?(转)
			
最近我在做学习xml时,遇见一个问题,我本用的是2009 xml spy后来老是出现问题 ,就是不能通过,后来我上网查了一下,发现是以一问题,不管是在2006中还是在2009中,都会出现这样的问题,要 ...
 - spring框架内置笔记本
			
◆基本介绍 目的:解决企业应用开发的复杂性 特征:使用主JavaBean更换EJB,它提供了许多其他的企业应用 范围:随你Java应用 Spring 框架是一个分层架构.由 7 个定义良好的模块组成. ...
 - Git常用命令(转)
			
目前开发的新项目使用的版本控制工具基本用的都是Git,老项目用的还是Svn,网上Git资源也很多,多而杂.我整理了一份关于Git的学习资料,希望能帮助到正在学习Git的同学. 一. Git 命令初识 ...
 - SSIS从理论到实战,再到应用(2)----SSIS包的控制流
			
原文:SSIS从理论到实战,再到应用(2)----SSIS包的控制流 前文回顾: SSIS从理论到实战,再到应用(1)----创建自己的第一个包 上次说到创建了自己的第一个包,完成了简单的数据从数据库 ...
 - 【足迹C++primer】47、Moving Objects(1)
			
Moving Objects(1) * 功能:Moving Objects * 时间:2014年7月17日08:46:45 * 作者:cutter_point */ #include<iostr ...
 - linux_环境变量设置 utf-8
			
echo $LANG 显示编码 : en_US.UTF-8 英文urf8有时显示程序输出是? 解决方法: vim ~/.bashrc 最后一行追加: export LANG=zh_CN.UTF- ...
 - 朴素UNIX之-打开历史
			
它可以毫不夸张地说,,UNIX模型是现代操作系统的原型.无论是真实的UNIX让我们大系列AIX,Solaris,HP-UX,FreeBSD,NetBSD,...或类别UNIX实例Linux...或基于 ...
 - txt 开关 csv 可通用 工具
			
Ruby Txt 开关 CSV 常用工具 to require 'csv' namespace :sys_file_conver do desc "把txt数据导入到csv中" t ...