架构设计:远程调用服务架构设计及zookeeper技术详解(上篇)

一、序言

     Hadoop是一个技术生态圈,zookeeperhadoop生态圈里一个非常重要的技术,当我研究学习hadoop的相关技术时候,有两块知识曾经让我十分的困惑,一个是hbase,一个就是zookeeperhbase的困惑源自于它在颠覆了我对数据库建模的理解,而zookeeper的困惑却是我无法理解它到底是干嘛的。

    前不久我结合我了解的一种远程调用服务的设计来帮助我理解zookeeper在实际的生产中运用,该文章的地址是:

    http://www.cnblogs.com/sharpxiajun/p/3297852.html

   其实这篇文章写完后,我自己感觉并不是太好,因为写本文的时候,对远程调用服务的设计以及zookeeper的理解都不是很到位,但是这篇文章还是受到了大家很大的关注,被博客园作为了推荐文章,还有很多网友希望我写一篇更加详尽的文章,还有童鞋留言说这个设计方案和淘宝开源的dubbohsf类似。我相信大家的关注就是意味着这个主题是当下技术的热点,所以今天我要写一篇主题和上篇文章一样的博文,这是上篇文章的升级版,不管是远程调用服务还是zookeeper我都会给出更加详尽的讲解。不过这里还是要说明下,这篇文章里远程服务的设计我还是没有参照dubbo,因为最近实在太忙,没有时间研究淘宝的dubbo,但是我希望学习过dubbo的童鞋可以帮我对比下我的方案和dubbo的区别,区别就会产生新的问题,也会有新的知识需要研究。

   本文是该主题的上篇,主要是讲解远程调用服务的相关知识,下篇则是根据远程调用服务架构设计中zookeeper的相关应用方法详细讲解关于zookeeper的知识。

 

二、远程调用服务的架构设计总述

    首先我们要再深入理解下为什么应用软件服务里需要一个远程调用服务,远程调用服务解决了软件设计中的什么问题,它的架构设计又有什么理论根据了?

    我曾写了一篇关于分布式网站架构设计的文章,文章地址是:

    http://www.cnblogs.com/sharpxiajun/archive/2013/05/11/3072798.html

    在文章开头我就把这个新的网站架构方案和传统的企业软件的B/S架构作了对比,我将一个网站里提供业务服务的组件抽象为独立的服务系统,接收用户信息的逻辑部分抽象为前端系统,服务系统和前端系统使用netty这样的通讯组件进行通讯,而到了讲解远程调用服务的框架设计时候我将netty通讯组件进一步抽象为一个通讯独立系统及远程调用服务,这就是为什么要设计远程调用服务的缘起了,远程调用服务又会带来了网站架构的升级,如果传统的企业B/S架构为1.0版,我将前端和业务服务端分离为独立系统则是2.0版,那么引入了远程调用服务网站就是3.0版了,3.0版的架构带来的好处就是可以将N多的前端系统和N多的业务服务端系统融为一个整体,网站的规模会越来越大,提供的服务也会越来越多,这既避免重复造轮子的问题还使得网站规模越来越大。

   3.0版本的网站架构带来了新的网站架构总图,如下所示:

 

     有了远程调用服务,我们可以做到业务级别的集群,例如:一个制造企业,一般都会有采购业务,生产业务、销售业务以及财务业务,按照传统的思路我们都会给每个业务独立开发一个系统,如果引用了远程调用服务,我们可以将这些业务都做成独立的服务,这些服务组成业务集群,而这些服务都是用统一的远程调用服务作为操作的入口,换句话说不管什么样的服务对于调用者来说都是统一的,这样前端的调用者可以做到应用的统一,所谓的应用的统一淘宝网站是最典型的代表,我们在一个同一的网站里可以操作各种不同的应用,而不会发生因为应用的不同我们就得重新访问新的地址或者重新登录到另外一个系统里做其他业务的操作。而服务端这边,完全可以摆脱传统的客户端和服务端耦合的开发,增强了整个服务端的专业性和稳定性,这样更易于服务端的扩展性和可维护性。如果服务端之间也需要相互调用也可以通过远程调用服务实现,由于远程调用服务的统一性,这样就避免了服务调用之间报文和调用方式的不统一,规范了整个开发的流程。如果远程调用服务还有负载均衡功能,整个服务集群就变成了一个私有的云,所以说远程调用服务是云计算的重要组成部分,这个说法一点都不为过。

    远程调用服务的理论依据是什么,这个问题的表述可能有点问题,其实我要讲的是远程调用服务的技术原型就是SOAService-Oriented Architecture),在云计算出现前,SOA曾一度是IT的技术热点,虽然之后很多人说中国的SOA做的一点不好,就和早年的DHTML一样,诟病远多于赞赏,写本文时候我在京东里搜索了下SOA,从书籍的出版日期和书籍评价数就可以看出SOA已经有点无人问津的凄凉了。下面我要简单介绍下SOASOA的定义:

     SOA是一个软件架构,它包含四个关键概念:应用程序前端、服务、服务库和服务总线。一个服务包含一个合约、一个或多个接口以及一个实现。

   应用程序前端可以理解为我上面所讲述的调用者和前端系统,服务库可以理解为服务集群,这里还有个服务是什么呢?服务就是调用者和服务提供者完成某一个特定业务的合约,换句话说就是封装的业务规则,打个比方,我们在淘宝去购物,下订单,付款,查物流,确定付款这些操作在服务端都有独立的服务提供,但是从购物这个概念去理解,这些独立的服务才能构成这个完整的购物行为,如果其中有地方出了问题,会有相应不同的操作,那么这个就绝对不是调用者简单调用服务接口的问题,需要更高层次的业务封装,将上面这些操作封装为一个统一的服务,这个就是所谓的服务。最后一个要素服务总线,这就是我们本文所谈的重要主题:远程调用服务了。

   这里谈谈SOA的目的是想起到抛砖引玉的作用,让那些想深入研究远程调用服务的人可以从SOA的角度理解远程调用服务,而那些还是不明白远程调用是何物的童鞋可以通过SOA的概念来理解远程调用服务。

 

三、远程调用服务技术详解

     远程调用服务技术详解,详解,呜呜~~,这两个字很有压力,我怕有童鞋看了这个标题会以为我会将整套技术实现方案写到里面,这个难度太高了,写几万字估计都说不清楚,再说真的写的那么细致,估计很多人都看不懂了(嘿嘿,我自己也没有技术实现过哦,这些都是构思,构思哦),所以详解就是详解原理。

     下面我将上篇文章的架构图放进来,大家再仔细看看这张图:

 

     传统的服务调用都是服务提供者和服务调用者的直接调用,从架构图里我们看到这里多了一个远程调用管理组件,远程调用管理组件是一个独立的服务系统,为了保证该系统的稳定性,它也一定是一个分布式的系统,但是这个分布式系统和Web的分布式系统是完全不同的分布式系统,传统Web应用集群是基于HTTP协议的无状态的特点设计的,因为每个HTTP请求都是一个独立的事务,不同请求之间是没有任何关系的,所以我们可以将Web应用部署到不同服务器上,请求不管到了那台服务器,都能正常的给用户提供相应的服务,但是Web应用的session机制是有状态的,所以传统Web集群都是要有session同步的操作,大型网站往往会把session功能抽象为独立的缓存系统,但是这里的远程调用管理组件的集群原理或者说分布式原理是有别于Web应用集群分布式原理的,远程调用管理组件可以当做一个注册中心,它会记录下服务提供者和服务调用者的相关信息,并将这些信息推送给服务提供者或者服务调用者,为了保证系统的执行效率,这些注册信息都是记录在内存里,我们试想下,如果这些注册信息丢失,整个系统将会不可用,因此远程调用管理组件的集群是一种保证数据可靠性和服务提供健壮性的集群,而不是建立在HTTP无状态特性基础上的集群。我们这里假想下远程调用服务的集群运行场景,我们假如有5台服务器作为远程调用服务运行的服务器,那么每台服务器都必须有注册信息的冗余备份,当服务运行时候其中一台服务器发生了故障,这台故障的服务器上的数据不会丢失,此外集群应该还要有一个检查故障的机制,当发现有台服务器不可用的时候,能及时剔除该服务器,而zookeeper就是解决这种问题的技术框架。此外除了保证系统的稳定性和可用性外,集群的数据存储方式也是很重要的,前面我讲到集群的数据存储要有一个冗余机制,除了冗余机制还要有一个很适合快速访问和读写的数据模型,而zookeeper正好包含这种数据模型,所以我设计的远程调用服务是一个很适合zookeeper应用的场景,至于zookeeper的详细知识我会在下篇里详细讲到。

     远程调用管理组件还有一个心跳机制,心跳机制的作用是检测服务提供者的健康性及服务提供者是否可用,服务提供者启动时候会将自己的注册信息发送给远程调用管理组件,这个注册信息里包含服务端的ip地址和端口号,远程调用管理组件会启动一个线程,根据定时对这个ip地址和端口号去ping这个ip和端口号对应的应用是否可用,如果不可用远程调用管理组件会反复尝试几次,这个次数和多久检测心跳都是可以配置的,如果反复几次还是不通,那么就认定该服务不可用了。有网友在QQ上问我,为什么不检测服务调用者的心跳,这个完全没必要哦,调用者是主动方,提供者是被动方,这就好比你访问网站,如果你生病了不去访问了,系统没有必要检查你是否已经生病了。

     远程调用框架需要使用序列化和反序列化技术,这点也让很多童鞋不太理解,不理解的原因还是对序列化和反序列化技术的不理解,序列化技术主要是应用与数据持久化(数据存到硬盘)或者网络通讯,不管是数据存储到硬盘还是进行网络通讯,这些数据都会转化为二进制,序列化就是将正在运行的对象转化为可以存储和传输的二进制数据,而反序列化是可以将这些二进制数据反向还原成原来的对象信息,还原的对象还是可以被程序操作的,而我们设计的远程调用框架传递就是不同系统之间可以相互使用的程序代码,所以我们需要使用序列化和反序列化技术。这里就有一个问题,例如我们传输一个对象,这个对象对应的类是N多个类的继承子类,而且这个对象里可能还会引用其他的对象例如StringArrayList等等,那么为了让反序列化的对象可用,序列化的时候就会将这些信息也包含在二进制数据里,并且这些信息一起进行网络传输,这就导致数据传输量特别大,而jdk自带的序列化机制会导致这些附带信息更大,所以有必要使用比jdk更好的序列化机制,让数据量变小,并且序列化和反序列化的效率更高,上篇文章里我推荐了一种序列化框架hession,当然用户想使用什么序列化机制这个我也让用户可以自己配置,这也是外部配置文件的一个选项。

    前面文章里我还讲到了压缩技术并且推荐了google公司使用snappy,这个压缩技术也是为了让网络传输的数据量变小,提升网络的传输效率。

    对于服务提供者和服务调用者我会提供一个jar包,这些工程都要引入这个jar包,同时还需要一个配置文件来定义一些需要用户定义的参数,例如我们使用一个名字叫ycdy_config.properties配置文件,里面的key值介绍如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Config_center_url=ip:port;这个就是配置远程管理中心的ip地址和端口号;
Server_type=provider/consumer;配置是服务调用者还是提供者,不配置默认是提供者;
Provider_post=9999,这是服务提供者的端口号,调用者可以不配置,其实调用配置了也没啥用,如果提供者不配置,会有默认值的;
Provider_session_timeout=9000;服务提供者的超时时间,如果实际调用超过了这个时间,那么说明服务调用超时,适用于服务调用者,提供者无效
Tick_time=3000;心跳时间,这是远程调用中心检测服务端心跳的间隔时间,适用于服务提供者;
Again_time=3;当服务提供者不通的时候,心跳反复检测的次数,超过了次数就标记该服务不可用;Provider_session_timeout、Tick_time和Again_time三者之间是有一定关系,这个关系要实现这具体把控了;
Ip_include_pattern=172\\.17\\.138.*|192\\.168\\.0\\..*,这个适用于服务提供者,因为一台服务器可能存在多个ip地址,当远程调用服务组件接收到提供者的ip,用这个配置项来辨认那个ip可用,这里采用正则表达式的方式;
Ip_exclude_pattern=用于服务提供者,需要忽略的ip;
Consumer_policy=random/rotate;适用于调用者,调用者向提供者请求的负载均衡策略,我熟悉的只有两种一种是使用随机数,一种使轮询,所以这里目前就这两种选项;
Monitor_log=true/false;是否开启监控日志,适用于服务提供者,任何系统日志时最重要的,否则没法查生产问题,其实这个配置项应该可以充实点,但是我现在还没想好,所以先给个提示,具体到了生产看如何实现吧。

  

     大家看到了不管是作为服务提供者还是服务调用者使用的配置文件是一致的,而且一个应用既可以配置成服务的调用者也可以配置成服务的提供者,非常的灵活。

     远程调用服务还需要一个重要的技术就是通讯技术,这里的通讯技术我推荐nettynetty是个非常好的选择,讲到通讯是个复杂的课题,如果以后有空我再做详细介绍,通讯层的东西是封装到服务提供者和服务调用者引入的jar包里,但是通讯的ip地址和端口号则是需要远程调用管理组件推送过来的。

     那么在应用里远程调用服务到底如何使用了?哈哈,这时候spring就要上场了,我们看看服务调用者和服务提供者的spring配置,如下所示:

 

复制代码
<!-- 服务提供者配置 -->
<bean id="serverProvider" class="cn.com.sharpxiajun.RmifSpringProviderBean"><property name="interfaceName" value="cn.com.ITest"></property><!-- 远程调用的接口 --><property name="target" ref="clsTest"></property><!-- clsTest实现ITest的实现类,clsTest这里是一个bean的id值 -->
</bean><!-- 服务调用者配置 -->
<bean id="clientConsumer" class="cn.com.sharpxiajun.RmifSpringConsumerBean"><property name="interfaceName" value="cn.com.ITest"></property><!-- value就是Provider定义的target的接口实现类 --><property name="serialType" value="hessian"></property><!--序列化方式  --><property name="compressEnabled" value="true"></property><!-- 压缩标记 -->
</bean>
复制代码

 

     我们发现这个新配置和以前不同了,这个配置将更加适合生成的开发。

     我们首先看看serverProvider的设计,这个bean对应的classcn.com.sharpxiajun.RmifSpringProviderBean,里面有个参数是一个interfaceName即提供者对外的接口,这里我会使用反射机制将接口注入到RmifSpringProviderBean,而target则是具体的实现对象了,这就是业务对象,注意interfaceName一定要是接口,因为调用者会根据接口进行转化,如果是类的话,那么通用性就很差了。

     clientConsumer的设计,这个bean所对应的classcn.com.sharpxiajun.RmifSpringConsumerBean,其中interfaceNamevalue值对应的就是远程定义的接口,和提供者的interfaceName保持一致,当提供者的数据传导调用者后,就会根据这个双方约定好的接口反序列化成可以操作的对象,serialType是选择序列化机制,不写的话就是调用jdk的序列化机制,这里附带提下啊,外部的序列化程序也是放到jar包里的哦,还有一个选项是compressEnabled作用是是否启用传输报文压缩。

    当调用者调用提供者服务时候,jar包里netty程序会根据推送的信息(主要是ip,端口)和spring配置的bean结合起来就可以完成一次服务的调用。

   好了,上篇写好了,本篇主要是讲解远程调用服务的架构设计,我自我感觉这篇文章比上篇更接地气,希望看了本文的童鞋,能对远程调用框架设计的原理更加清晰。

   其实netty的使用学问也很大,也是远程调用服务的核心之一,本文这块讲的比较少,以后有时间我尽量补充上这块知识。

   下篇文章我将详细介绍远程调用框架里使用到的zookeeper技术。

   这是2013年的最后一篇博文了,祝大家新年快乐哦。

 

转自http://www.cnblogs.com/sharpxiajun/p/3496639.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

据说很多女生都想知道男生是如何上厕所的?

1 老婆守恒定律&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 捡破烂的狗子&#xff08;via.李市民&#xff0c;侵删&#xff09;▼3 见过最搞笑的买药经历&#xff08;素材来源豆瓣yuyii&#xff0c;侵删&#xff09;▼4 男朋友的室友可以多粘人&#xff1f;&a…

【云图】如何设置支付宝里的家乐福全国连锁店地图?

【云图】如何设置支付宝里的家乐福全国连锁店地图&#xff1f; 原文:【云图】如何设置支付宝里的家乐福全国连锁店地图&#xff1f; 摘要&#xff1a;本文详细讲解了&#xff0c;如何设置支付宝服务窗。商家如何将自己的全国连锁店放置到云图上&#xff0c;并且在支付宝服务窗中…

ABP vNext微服务架构详细教程——基础服务层

1服务创建在除身份管理相关服务以外的其他业务服务中&#xff0c;我们不需要包含用户角色权限管理功能模块&#xff0c;ABP vNext框架为我们提供了模块模式&#xff0c;其默认模板不包含身份管理相关模块&#xff0c;更适合用于搭建普通的业务微服务。以产品管理服务为例&#…

中国第一个发《Nature》的竟然是清朝人!被皇帝夸天下第一,他却觉得羞耻..........

全世界只有3.14 % 的人关注了爆炸吧知识大清亡了&#xff01;这事在今天讲&#xff0c;算不得惊天动地&#xff0c;你听了之后&#xff0c;还可能微微一笑。作为中国最后一个封建王朝&#xff0c;它先闭关锁国&#xff0c;后又丧权辱国&#xff0c;造成百年前的中国在科学技术方…

码农与UI沟通的日常

事情是这样的&#xff0c;这是一个兴趣群组的效果图。 我看了一眼没有帖子时的提示&#xff0c;觉得这样的提示 不走心 不能展现出我们团队对于人生及世界的深度理解和高尚的品格。 于是&#xff0c;我选择了表达内心的真实感受。 我觉得这完美表达了用户使用时的心声&#xff…

贝叶斯分类器_Sklearn 中的朴素贝叶斯分类器

(给Python开发者加星标&#xff0c;提升Python技能)作者&#xff1a;Martin Mller&#xff0c;翻译&#xff1a;github-sisibelovedhttps://github.com/xitu/gold-miner/blob/master/TODO1/naive-bayes-classifier-sklearn-python-example-tips.md用豆机实现的高斯分布这篇教程…

linux之tr命令使用和总结

1、tr命令介绍 用来从标准输入中通过替换或删除操作进行字符转换。tr主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。 带有最常用…

美少女什么味??竟然还有美少女风味泡面......

1 毕业后第一次参加聚餐&#xff08;via&#xff1a;刘燕铭&#xff09;▼2 建议使用摩斯密码&#xff0c;谢谢▼3 隆马戏&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 真的很谢谢▼5 啊&#xff0c;哪里买呢&#xff08;via&#xff1a;Zero 浅忆&#xff09;…

ABP vNext微服务架构详细教程——身份管理服务

1框架搭建ABP vNext创建包含app和module两种模板&#xff0c;其中app方式所创建的模板包含用户、角色、权限管理&#xff0c;ABP基础配置IdentityServer的基础配置数据等功能。module模式是一个比较干净的服务&#xff0c;里面不包含默认业务功能。ABP vNext创建包含app和modul…

双网卡上网冲突解决_【技术文章】局域网IP地址冲突罪魁祸首是什么?这几点要注意!(附高手处理方法)...

现如今&#xff0c;人们的生活处处离不开网络。单位办公信息化对网络的依赖则更大。为了提升安全管理和信息化水平&#xff0c;很多单位不仅建设了完善的办公信息系统&#xff0c;还部署了视频监控。但由于缺乏整体规划&#xff0c;或选择网络产品时考虑欠周&#xff0c;导致网…

异常分析

一、请阅读并运行AboutException.java示例&#xff0c;然后通过后面的几页PPT了解Java中实现异常处理的基础知识。 &#xff08;1&#xff09;源代码;import javax.swing.*; class AboutException { public static void main(String[] a) { int i1, j0, k; ki/j; try { k i/j…

linux c之wait和waitpid函数的用法和总结

1、wait和waitpid函数的介绍 1) wait()函数用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接收到了一个指定的信号为止。如果该父进程没有子进程或者它的子进程已经结束,则wait()函数就会立即返回。 2) waitpid()的作用和wait()一样,但它并不一…

微软开发者的年度回顾

2021 年 .NET 和 Microsoft 开发人员的技术都发生了什么&#xff1f;很难从 2021 年只选择一个主题。安静的进化&#xff1f;开源的争议&#xff1f;一个让开发人员疑惑的操作系统更新&#xff1f;当我回头看时, 发现一年发生了很多事情, 2021 年的发展是稳步向前的&#xff0c…

我是永远不可能出轨的,除非......

1 当爸妈学会了抠图&#xff08;素材来源豆瓣&#xff0c;侵删&#xff09;▼2 帮我带瓶我平时常喝的水&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 我们是被资本凑在一起的联姻&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 我是不会出轨的&…

linux之学习linux系统相关的书籍

1.《鸟哥的Linux私房菜-基础学习篇》 2.《Linux Shell 脚本攻略》 3.《Unix环境高级编程》 4.《Linux系统编程》

16岁上大学,25岁博士毕业,她还是南大医学院最年轻的博导!

全世界只有3.14 % 的人关注了爆炸吧知识本文转自&#xff1a;募格学术魏嘉&#xff0c;16岁考上南大&#xff0c;25岁博士毕业&#xff0c;是南大医学院最年轻的博导&#xff0c;已在J Natl Cancer Inst等国际著名杂志上发表64篇SCI论文。在第24届“中国青年五四奖章”入围名单…

十年整理CAD精髓

为什么80%的码农都做不了架构师&#xff1f;>>> AUTOCAD使用心得之一 使用的三个基本方面&#xff1a;清晰、准确、高效 目前&#xff0c;公司的设计文件&#xff0c;特别是图纸&#xff0c;都是用AUTOCAD软件绘制的。但是&#xff0c;现在还有很多人对CAD并不是…

使用这个库,让你的服务操作 Redis 速度飞起

点击上方蓝字关注 &#x1f446;&#x1f446;没领红包封面的可以在文末领取大多数人使用 Redis 作为远程缓存存储&#xff0c;因为它速度快。Redis6 通过消除不必要的网络往返&#xff0c;可以使其更快。服务器辅助的客户端缓存这个方法很简单。Redis6 会记录客户端请求的键值…

mysql bigint转string_无语了,直到今天,我才揪出MySQL磁盘消耗迅猛的“真凶”!...

作者&#xff1a;dbapower链接&#xff1a;https://blog.51cto.com/suifu/2135599背景Part1:写在最前当一张单表10亿数据量的表放在你面前&#xff0c;你将面临着什么&#xff1f;Part2:背景介绍为了提升数据库资源利用率&#xff0c;一个实例中&#xff0c;在不互相影响&#…

mysql导入sql脚本命令

2019独角兽企业重金招聘Python工程师标准>>> 使用mysql自带的命令行工具导入sql脚本如下&#xff1a; mysql -h localhost -u root -proot -v -Ddbname < dbname.sql 转载于:https://my.oschina.net/u/2450094/blog/795488