分布式Java应用的体系结构知识简单分为:

  • 网络通信:包括协议和IO
  • 消息方式的系统间通信:包括基于Java包、基于开源框架、性能角度
  • 远程调用方式的系统间通信:包括基于Java包、基于开源框架、性能角度

大型应用拆分为多个子系统来实现,这些子系统可能部署在同一台机器,或者不同机器的多个不同JVM中,每个子系统对应一个JVM。但这些子系统又不是完全独立的,要相互通信来共同实现业务功能,对于此类Java引用,我们称之为分布式Java引用。通常有两种典型的方法来实现。

  • 基于信息方式实现系统间的通信,通常基于网络协议来实现。
  • 基于远程调用方式实现系统间的通信,通常基于RMI和WebService

消息方式

基于Java自身技术

基于Java自身包实现消息方式的系统间通信的方式有:

  • TCP/IP+BIO
  • TCP/IP+NIO
  • UDP/IP+BIO
  • UDP/IP+NIO
TCP/IP+BIO

在Java中可基于Socket、ServerSocket来实现TCP/IP+BIO的系统间通信。Socket用于实现建立连接及网络IO的操作,ServerSocket用于实现服务器端端口的监听及Socket对象的获取。这种简单的通信模式,运用到实际的系统中,通常需要面对的是客户端同时要发送多个请求到服务器端,服务器端则同时要接受多个连接发送的请求。   为了解决客户端同时要发送多个请求到服务器端的需求,解决办法是:

  • 生成多个Socket,问题是消耗客户端过多的本地资源,消耗服务器端过多的连接数,连接耗时较长导致的系统性能下降。解决方法是采用连接池的方式来维护Socket。连接池的问题是Socket数量有限导致的竞争和等待和如何合理控制等待响应的超时时间。

为了满足服务端能同时接受多个连接发送的请求,解决办法是:

  • 在accept获取Socket后,将此Socket方式放入一个线程中处理,称为一连接一线程。缺点是无论连接上是否有真实的请求,都要耗费一个线程。为防止过多线程导致的服务器端资源耗尽,必须限制创建线程的数量,BIO方式下服务器端所能支撑的连接数有限。
TCP/IP+NIO

在Java中可基于java.nio.channels中的Channel和Selector的相关类来实现TCP/IP+NIO方式的系统间通信。SocketChannel用于建立连接、监听事件及操作读写,ServerSocketChannel用于监听端口及监听连接事件,程序通过Selector来获取是否有要处理的事件。NIO是典型的Reactor模式的实现,通过注册感兴趣的事件及扫描是否有感兴趣的事件发生,从而做相应的动作。这种简单的通信模式,运用到实际的系统中,通常需要面对的是客户端同时要发送多个请求到服务器端,服务器端则同时要接受多个连接发送的请求。

为了解决客户端同时要发送多个请求到服务器端的需求,解决办法是:

  • 采用与TCP/IP+BIO类似的方式,使用多个SocketChannel。但是NIO方式可做到不阻塞,如果服务器端返回的相应能够带上请求标识,客户端则可采用连接复用的方式。对于连接不复用的情况,可基于Socket.setSoTimeout的方式来控制同步请求的超时;对于连接复用的情况,同步请求的超时可基于BlockingQueue、对象的wait/notify机制或Future机制来实现。

为了解决服务端接受多个连接请求的需求,解决办法是:

  • 由一个线程来监听连接的事件,另一个或多个线程来监听网络流读写的时间。当有实际的网络流读写事件发生后,再放入线程池中处理。这种方式称为一请求一线程,好处是可接受很多的连接,这些连接只在有真实的请求时才会创建线程来处理。非常适用于服务端需要支持大量的连接数,但这些连接同时发送的请求不会太多。

对于高访问量的系统而言,TCP/IP+NIO方式结合一定的改造在客户端能够带来更高的性能,在服务端能支持更高的连接数。

UDP/IP+BIO

Java对UDP/IP方式的网络数据传输同样采用Socket机制,只是没有建立连接的要求,同时无法双向通信,除非两端都是UDP Server。在Java中可基于DatagramSocket和DatagramPacket来实现UDP/IP+BIO方式的系统间通信,DatagramSocket负责监听端口及读写数据。DatagramPacket作为数据流对象进行传输。

UDP/IP通信方式的两端不建立连接,不会有TCP/IP通信连接竞争的问题,只是最终读写流的动作是同步的。客户端同时发送多个消息的请求使用多个DatagramPacket即可。服务端同时接收多个请求的需求,采用没接收到一个packet就放入一个线程中进行处理的方式来实现。

UDP/IP+NIO

在Java中通过DatagramChannel和ByteBuffer来实现UDP/IP+NIO方式的系统间通信,DatagramChannel负责监听端口及进行读写,ByteBuffer则用于数据流传输。

对于UDP/IP方式,NIO带来的好处是只在有流要读取或可写入流时才做相应的IO操作,而不用像BIO方式直接阻塞当前线程。

多播的实现

以上都是基于Java包的一对一的系统间通信方式,实际场景中,可能需要将消息发送给多台机器,针对此场景有两种解决办法:

  • 为每个目标机器建立一个连接,缺点是对消息发送端造成很大的网络流量压力
  • 利用基于UDP/IP扩展出来的多播协议,在Java中可基于MulticastSocket和DatagramPakcet来实现多播网络通信。在多播通信中,接收数据端加入多播组来进行数据的接收,发送数据也要求加入多播组进行发送,多播的目标地址具有指定的地址范围,在224.0.0.0和239.255.255.255之间。

在Java应用中,多播通常用于多台机器的状态的同步。

基于开源框架

Mina是Apache的顶级项目,基于Java NIO构建,同时支持TCP/IP和UDP/IP两种协议,Mina对外屏蔽了Java NIO使用的复杂性,并在性能上做了不少优化。

在使用Mina时,关键的类为IoConnector、IoAcceptor、IoHandler及IoSession,Mina采用Filter Chain的方式封装消息发送和接收的流程,在这个Filter Chain的过程中可进行消息的处理、消息的发送和接收等。

  • IoConnector 负责配置客户端的消息处理器、IO事件处理线程池、消息发送/接收的Filter Chain 等。
  • IoAcceptor 负责配置服务器端的IO事件处理线程池、消息发送/接收的Filter Chain等。
  • IoHandler 作为Mina和应用的接口,当发生了连接事件、IO事件或异常事件时,Mina都会通知应用所实现的IoHandler。
  • IoSession 类似于SocketChannel的封装,不过Mina对连接做了进一步的抽象,因此可进行更多连接的控制及流信息的输出。

除了Mina之外,现在JBoss Netty也是现在一个广受关注的Java通信框架,据评测JBoss Netty的性能浩宇Mina。

小结

使用Java包来实现基于消息方式的系统间通信还是比较麻烦。为了让开发人员更加专注于对数据进行业务处理,而不用过多关注纯技术细节,开源业界诞生了很多优秀的基于以上各种协议的系统间通信的框架,比如Mina。

《分布式Java应用之基础与实践》读书笔记一的更多相关文章

  1. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  2. 【鸟哥的Linux私房菜】笔记3

    正确地开机 最好不要使用root账号登陆!GNOME图形界面 View items as a list X WindowShell 文本交互界面bash是Shell的名称,Linux的默认壳程序就是b ...

  3. 【鸟哥的Linux私房菜】笔记2

    Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...

  4. 《鸟哥的Linux私房菜》笔记——02. 关于Linux

    Unix 历史 1969年以前:伟大的梦想--Bell, MIT 与 GE 的「Multics」系统 1969年:Ken Thompson 的小型 file server system 1973年:U ...

  5. 《鸟哥的Linux私房菜》笔记——03. 磁盘分区

    Everything is a file. 常见硬件对应于 Linux 下的文件(/dev目录下) 装置 装置在Linux内的档名 SCSI/SATA/U盘硬盘机 /dev/sd[a-p] U盘 /d ...

  6. 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻

    连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...

  7. 【鸟哥的Linux私房菜】笔记

    操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...

  8. 《鸟哥的Linux私房菜》笔记——04. 简单命令行

    键入命令 [dmtsai@study ~]$ command [-options] parameter1 parameter2 ... 指令 選項 參數(1) 參數(2) 注意:有时也可以使用 + 放 ...

  9. 鸟哥的Linux私房菜学习笔记——文件权限与目录配置

    Linux的文件权限和目录配置 在linux中的每个用户必需属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. (1)所有者 一般为文件的创建者,谁创建了该文件,就是天 ...

  10. 鸟哥的Linux私房菜学习笔记(1)

    2014/10/29 1.档案的权限管理分为三个部分: 拥有者.群组.其他 2.ls -al 命令可以看到档案的详细信息 3.档案的属性中由十个部分构成 第一个部分是档案类型 -代表档案.d代表文件夹 ...

随机推荐

  1. [LeetCode] Dp

    Best Time to Buy and Sell Stock 题目: Say you have an array for which the ith element is the price of ...

  2. SSH整合缓存之-Memcached作为hibernate的二级缓存

    Hibernate本身不提供二级缓存,所以需要使用第三方插件来作为二级缓存:本次使用memcached作为Hiberbate的二级缓存:添加步骤如下: 一.需要安装memcached服务端 1. 下载 ...

  3. redux三个基本原则

    (1)单一数据源:整个应用的state被存储在一棵object tree中,并且这个object tree只存在于唯一一个store中: (2)state是只读的:唯一改变state的方法就是触发ac ...

  4. php与mysql的常规使用

    <?php header("Content-type:text/html;charset=GBK"); /* 通常,php网页中完成有关数据库的操作,首先,需要如下代码: $ ...

  5. 对JDBC的优化,BeanUtils和DBUtils

    为了进一步简化jdbc的使用,就是用组件进一步的及优化 BeanUtils工具包,代替java本身蹩脚的javaBean,使对象的封装更加的简单易行 DBUtils工具包,是jdbc的操作更加的简单 ...

  6. TCP/IP笔记(三)数据链路层

    数据链路的作用 数据链路层的协议定义了通过通信媒介互连的设备之间传输的规范.通信媒介包括双绞线电缆.同轴电缆.光纤.电波以及红外线等介质.此外,各个设备之间有时也会通过交换机.网桥.中继器等中转数据. ...

  7. ubuntu查看安装的cuda toolkit自带的工具及其他安装文件

    原创作品,转载请注明来源:http://www.cnblogs.com/shrimp-can/p/5253672.html 1.查看工具 默认目录为:local,进入local:cd /usr/loc ...

  8. 解决在eclipse中写ImageView时有警告的问题

    Eclipse中写了一个android程序其中main.xml中ImageView哪行是个黄叹号!不知道为什么? 解决办法: android:contentDescription="@str ...

  9. Spring中一个类的注入和引用是不一样的

    1.在Spring管理下的bean需要以下面这种方式引入(一种注入方式): private MgrService mgrService; public MgrService getMgrService ...

  10. IOS各种手势操作实例

    先看下效果 手势相关的介绍 IOS中手势操作一般是 UIGestureRecognizer 类的几个手势子类去实现,一般我们用到的手势就这么5种: 1.点击  UITapGestureRecogniz ...