架构设计:系统间通信

系统间通信的主要原理、手段和实现

http://blog.csdn.net/yinwenjie/article/details/48274255

关键技术领域

负载均衡技术要linux 和os知识,系统间通信层技术,要编程经验

概述从 “聊天” 开始上篇

场景 一问一答形式的交流

A:我来问问题,问一个你答一个

B: 好的,请开始提问

要点:

  • 都用中文
  • 媒介是空气,非真空
  • 协调一致,A问完一个,B答完,A才能继续
  • 结构一致,处理信息的方式一样:嘴说耳听,大脑处理形成结果
  • 可能增加第N不用中文进行的交流

信息格式

  • xml

更广泛场景是对系统环境的描述,服务器配置,spring applicationContext.xml,maven pom.xml

  • json

和xml设计思路一致,语言无关,设计目标为进行通信,格式容量小

  • TLV 三元组编码

T(类型域)L(长度域)V(值域),字节位运算进行信息序列/反序列化

就连 JSON 中用于分割层次的 “{}” 符号都没有

  • 自定义

如 | 分隔

网络协议

信息在网络中完成传播,网络协议就是 “空气”

OSI

  • 物理层:如的网卡、交换机等,一般传递光电信号

  • 数据链路层:物理链路组合信号为帧;逻辑链路按规则和协议(CDMA/CD等)保证帧传输正确性,可使多个源/目标帧同一物理链路上“链路复用”

  • 网络层:IP协议解寻址问题

  • 传输层:TCP、UDP携带内容,通过协议规范提供某种通信机制(连接三次握手,关闭四次握手,错误重传)

  • 应用层:HTTP等应用层协议,或编码自定义

《TCP/IP 详解. 卷 1 - 协议》和《TCP/IP 详解. 卷 2 - 实现》

通信方式/框架

前问题接收完,反馈后,第二问题才提问,沟通方式虽沟通效率不高,但很有效:一个问题一个问题处理

参与沟通的人处理信息的能力比较强,可用另一种沟通方式:

给提问题编号,问完第 X 个问题后,不等返回就问第 X+1 个问题

听完第 X 个问题后,一边处理问题,一边听第 X+1 个问题

即 BIO与NIO

BIO 通信方式

BIO 问题

server端只有一线程时,同一时间,server 只接受A请求,同时进的B请求要等处理完A或异常后

用多线程解决

  • server

接收请求后,送入独立线程处理,主线程继续等客户端请求

  • client 子线程和server通信,server返回通过监听/观察者之类通知主线程

线程解决问题的局限性

  • 虽服务器端请求处理独立线程,但 os 通知 accept() 的方式还是单个的

  • linux线程数有限, cat /proc/sys/kernel/threads-max,线程越多,CPU 切换时间也越长,处理真正业务的时间也就越少

  • 创建线程较大资源消耗。JVM 栈空间

  • ThreadPoolExecutor 线程池缓解线程的创建问题,又会造成 BlockingQueue 积压任务的持续增加,同样消耗了大量资源

应用使用长连接,线程不会关闭,系统资源消耗更易失控

BIO 的问题关键不在于是否使用了多线程(包括线程池)处理这次请求,而在于 accept()、read() 的操作点都是被阻塞

1
2
3
4
5
while(true) {
	Socket socket = serverSocket.accept();
    //当然业务处理过程可以交给一个线程(这里可以使用线程池),并且线程的创建是很耗资源的。
    //最终改变不了.accept()只能一个一个接受socket的情况,并且被阻塞的情况
    SocketServerThread socketServerThread = new SocketServerThread(socket);

异步 IO 模式 就是为了解决这样的并发性存在的。但为了说清楚异步 IO 模式,要首先了解清楚,什么是 阻塞式同步、非阻塞式同步、多路复用同步模式

serverSocket.accept() 会被阻塞,涉及到阻塞式同步 IO 的工作原理:

server 线程发起一个 accept 动作,询问os是否有新的 socket 信息从端口 X 发送过来

socket 套接字的 IO 模式支持基于os,同步 IO / 异步 IO 的支持就是需要操作系统级别的

serverSocket.accept() 内部的实现是使用的os级别的同步 IO

阻塞/非阻塞 IO 概念是程序级别的。描述是程序请求操作系统 IO 操作后,如果 IO 资源没有准备好,那么程序该如何处理的问题:前者等待;后者继续执行(并且使用线程一直轮询,直到有 IO 资源准备好了)

同步/非同步 IO,概念是os级别的。描述os收到程序请求 IO 操作后,如果 IO 资源没有准备好,该如何相应程序的问题:前者不响应,直到 IO 资源准备好以后;后者返回一个标记(好让程序和自己知道以后的数据往哪里通知),当 IO 资源准备好以后,再用事件机制返回给程序。

NIO 通信框架

  • 原生 JAVA NIO

基于多路复用 IO 原理

  • MINA

提供了通过 Java NIO 在不同的传输例如 TCP/IP 和 UDP/IP 上抽象的事件驱动的异步 API

  • NETTY

MANA 和 NETTY 的主要作者是同一人 Trustin Lee

  • Grizzly:

NIO 为基础,并隐藏其编程的复杂性

通信方式

http+JSON

上手快,实现快,速度还行,并发问题交给LB层

优化手段常见keep-alive连接复用,gzip

但受web server实现不同(nginx,tomcat),并发受影响,接口太多不好管理

RPC

RPC实现错综复杂,多种说法

PB 归结为一种 RPC 的实现

RPC 和服务治理联系起来

RPC 框架作为一种 SOA(面向服务的架构)的实现进行讲述

目前实现了 RPC 框架的软件,往往都是把各种相互交错的技术规范 / 定义进行整合实现,又或者借鉴了 RPC 中的部分思想

MQ

整合手段——ESB 和服务治理

ESB

SOA 的典型实现,功能特点是代理

JBossESB、普元 EOS、IBM ORACLE 的 ESB 产品

服务注册中心

SOA 的另一种实现方式,和 ESB 最大的不同点是主要提供各原子系统的服务注册、服务治理、服务隔离、权限控制

客户端进行请求时,“服务治理” 将告诉客户端到哪里去访问真实的服务,自己并不提供服务的转发

Dubbo 就是一个典型的服务治理框架