JavaNote1.0.1_Java中间件技术

前言

今天要写的内容是分布式系统的构建、大型网站的构建以及Java中间件的基础知识。

1.分布式系统介绍

分布式系统的定义:A distributed system is one in which components located at networked computers communicate and coordinate their actions only by passing messages.
分布式系统有两个重点,一个是组件分布在网络计算机上,第二是组件之间仅通过消息传递来通信并协调行动。

1.1分布式系统的基础知识

分布式系统就是为了解决单个计算机系统性能而发明的。单个计算机组成要素包括:输入设备输出设备运算器控制器存储器组成。 分布式系统其实就像是互相合作的多个计算机组成的超级计算机。

1.1.1 线程与进程的执行模式

我们最后的开发都是要在进程中的线程来运行的。多线程过程中最重要的就是线程间的通信对线程的并发控制以及线程的协调工作。 多线程有一个特点就是,并发控制对于程序并发的性能影响十分巨大。

1.1.2 多线程的几种执行模式
  1. 互不通信的多线程模式:互相之间没有任何交集。两个线程并行执行无冲突。
  2. 基于容器共享协同的多线程模式:多个线程之间存在共享数据,例如生产者、消费者的例子。控制并发的方式一般是加锁或者互斥
  3. 通过事件协同的方式:不仅是数据的共享,逻辑上也有关联,需要等待其他线程触发事件才可以。容易出现死锁,也就是1锁a等b,2锁b等a的问题需要解决。要么线程执行换顺序,或者直接将一整块全部上锁。

多进程之间的关系就简单多了,因为互相之间内存关系不会发生冲突。

1.1.3网络通信的基础知识
  1. 第一种方式是BIO,也就是blocking io,这种方式在建立连接,进行读写操作的时候都要阻塞,加锁。
  2. 第二种方式就是NIPO,也就是nonblocking IO。采用的是一种事件驱动思想,不需要为每一个Socket套接字分配一个线程。采用了一种dispatch的分发策略,发出请求的内容经过分发给不同的handler处理器处理。
  3. 第三种方式是AIO,也就是AsynchronousIO, 也就是异步IO。AIO采用的是Proactor模式,就是进行读写操作的时候,调用相应的read/wirte 方法,然后传入CompletionHandler(动作完成的处理器)。也是说完成之后通知主程序。
1.1.4 单机扩展到分布式的过程
  1. 输入设备的变化:分布式系统是由多个系统连接的点组成,那么输入设备除了传统的人机交互设备,还有网络的每个能接收输入的输入设备
  2. 输出设备的变化:输出设备也是两种,传统输出设备例如屏幕,终端。还有一种就是向其他节点传递信息的节点
  3. 控制器的变化:单机系统中控制器就是CPU。分布式系统中就不是具体的元件,而是分布式的控制方式。分布式设备,第一种是硬件进行负载均衡,第二种是软件负载系统LVS。第三种是名称服务,请求发起方和请求处理是直接连接的,但是会共同连接一个名称服务器,可以搜集请求处理方的信息,然后给到请求发起方。完成地址交换的作用。第四种是规则服务器,这种不需要规则服务器连接请求处理方。最后一种是Master+Worker的方式,这种方式由一个master管理节点,分配给不同的请求方处理。
  4. 运算器的变化:运算器类似于控制器,首先有一个规则服务器DNS,然后通过负载均衡发布到网站服务器
  5. 存储器的变化:相同的规则进行分布式存储。
1.1.5 分布式系统的难点
  1. 缺乏全局时钟:在分布式系统中每个节点都有自己的时钟。
  2. 面对故障的独立性:一部分节点出问题,不是所有的系统全部失效,还有一部分是好的。
  3. 处理单点故障:某个角色的某个功能只有在某个单点上有支撑。
  4. 如何满足事务的(ACID)特性:原子性,一致性,独立性,Durability 持久性
2. 大型网站以及架构演进过程

大型网站的定义:大型网站是一种常见的分布式系统,我认为大型网站必须拥有较高的数据量访问量。两者缺一不可。

2.1 用Java技术和单机来构建的网站

基础的单机网站通常包括开源的Server,然后采用数据库关系系统来管理我们的数据。
从一个交易网站说起:
一个普通的淘宝网站包括,交易、商品用户,每个服务器都包含一个表:用户表,商品表,交易表,server和数据库之间通过JDBC进行关联。
十分幸运:
我们的对外访问量不断地增加,我们首先是把服务器增加了。数据库放到了另一台服务器上,本质上变化不大。
交易量越来越大:
应用服务器压力变的越来越大,于是我们必须要增加应用服务器数量,而用户访问哪一台应用服务器,采用的是负载均衡的策略。

应用服务器集群化之后Session的问题

构建Java中间件

中间件的定义:中间件是一种软件胶水,利用中间件可以实现不同应用之间的通信。它既不是操作系统的一部分、也不是数据库管理系统、也不是软件应用的一部分。

Java并发编程的类、接口和方法

线程池:线程池不需要一直创建线程,而是复用线程的。不适用线程池就必须每次都创建一次线程。如果线程内的执行工作特别简单,就会导致创建线程的开销占整个时间的比例较大。
synchronized: 是一种声明互斥的方法,既可以对整个类进行声明,静态函数,或者代码块参数是(类名.class)。也是可以对对象声明互斥,非静态函数或者代码块参数是(this)。

ReentrantLock:ReentrantLock 是 java.util.concurrent.locks 中的一个类,但是区别是必须要在finally里面申明unlock。还可以指定是否采用公平锁的方式。

volatile:只能提供更新后数据的可见性,但是多个数据去读取的时候,线程会一起执行,因此并不是线程安全的。

Atomics:作为程序计数器的场景,不需要锁定代码块,类本身就是原子操作的,由于内部实现了硬件支持的CAS指令,因此速度特别快。

Wait、Notify和NotifyAll:
这三类是java的Object对象的三种方法。wait是用来进程等待的,而Notify和NotifyAll是进程通知的,不同的是一个会唤醒单个进程,而另一个会唤醒所有等待线程。
CountDownLatch:
作用是,当多个线程都完成了自己的工作之后,触发的事件。其他的线程可以等待这个事件来触发自己的后续工作。
这里可以给个例子
使用CountDownLatch对多核进行排序链接在这
CyclicBarrier:
循环屏障,可以协同多个线程,让多个线程在屏障前等待。直到所有线程都达到这个屏障的时候,再一起执行后面的动作。
修改上述对于多核排序的程序
如果线程池中线程太少,就会导致一些没有分配到线程的程序等待,但是等待的程序因为要等待没有分配线程的程序进入await,因此就会发生死锁。CountDownLatch无法循环使用,CyclicBarrier可以循环使用。
Semaphore:
这个函数是用来管理信号量的。主要作用是控制并发数目,超过并发量就等待其他方法返回后再执行。
Exchanger:
名字上来说就是交换。Exchanger用于在两个线程之间进行数据交换,线程会阻塞在exchanger上,直到另一个线程也进入了Exchanger中的exchange方法。一个交换队列的例子
Future和Future Task:
Future是一个接口,FutureTask是一个具体实现类。也就是说,当我们需要调用一个远程的数据的时候,我们不需要一直等待结果返回,而是等需要使用的时候再等待结果返回。
并发容器
并发容器就是线程安全的容器,常见的有CopyOnWrite和Concurrent里面的容器。

动态代理

动态代理是中间件实现的非常重要的基础,大家比较熟悉程序设计中的代理模式,代理类和委托类具有同样的接口,代理类也有很多的实际应用。具体实现上有静态代理动态代理之分。

静态代理的方式是为每个被代理的对象构造对应的代理类。会造成大量的重复代码,因此我们需要使用动态代理。
动态代理采用的是动态的生成具体的委托类的代理类实现对象。一个具体的例子

反射技术

反射技术同样是中间件的重要技术基础,反射是Java中提供的非常方便又强大的功能,反射机制是指在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法。对于任意一个对象都能调用他的任意方法和属性。
Java反射主要提供了以下功能

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时任意构造一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法,在运行时调用任意一个对象的方法
  4. 在运行时调用任意一个对象的方法,生成动态代理

Java的反射机制为java本身带来了动态性,使得java在运行过程中不知道类对象的信息但是可以调用相应的方法并修改属性值。反射对于实现远程调用具有十分巨大的帮助。
反射用法合集:

  1. 获取对象属于哪个类
  2. 获取类信息
  3. 构建对象
  4. 动态执行方法
  5. 动态操作属性

具体的实现在这里

网络通信实现选择

可以使用MINA或者Netty实现。

猜你喜欢

转载自blog.csdn.net/h201601060805/article/details/130736076