分布式系统架构(分布式系统)
分布式其实很好理解:一个人做的事情让两个人来做,每个人负责的功能都不一样。既然一件事情分给了两个人来完成,那这两个人就少了沟通(分布式通信),少不了协作(分布式调度),最后还需要一个机制把这些东西管理起来(分布式治理)
分布式的初衷为什么会有分布式系统的出现?其目的是为了解决单体系统解决不了的问题。分布式系统的最小单元也是一个个的单体服务,通过分工和协作把所有的微服务运转起来以达到更强大的计算能力。
分布式通信分布式基础总体来说可以分为数据通信和数据传输
数据通信分布式架构中,有一个环节很重要,那就是分布式系统中的计算机节点彼此之间的通信,关于通信,大家或多或少都知道一些东西,但是可能都很零散,今天我就带大家一起梳理这块的知识点 说到分布式通信,我还是习惯从http请求说起,通过http请求把通信的知识串起来
1:DNS解析(Domain Name System)简单点理解就是把输入在浏览器上面的域名解析成IP,因为域名比IP好记,所以会有从域名解析出IP的DNS服务
2:CDN(Content Delivery NetWork)CDN其实是一种网络缓存技术,能够把一些相对稳定的资源放在距离最终用户较近的地方,一方面可以减轻广域网的压力,另一方面可以提升用户的速度。我们一般会把一些静态文件(图片,脚本,静态文件)放到CDN中。
3:HTTP通信协议(通信的桥梁)域名被成功解析后,客户端和服务端是怎样建立通信的呢,相信你肯定听过tcp/UDP这两种通信协议,以及建立的握手过程。而http协议是建立在tcp/ip协议之上的一个应用层协议,应用层协议还有(FTP,DNS,SMTP,Telnet)。OSI的七层模型,tcp/ip的四层模型,以及三次握手协议,四次挥手协议等等这里就不具体的展开讨论。
4:Socket(连接的桥梁)tcp通道建立之后就可以基于这个通道发消息了,TCP/UDP都是基于Socket概念上扩展的传输协议,简单的说就是我们的数据都是通过TCP/UDP传输的。那么这跟Socket有什么关系呢?Socket是一种抽象层,应用程序通过它来发送和接收数据,就像应用程序打开一个文件句柄,把数据读写到磁盘上一样。Socket对于大多数人说都接触的很少,用大白话理解下:使用Socket可以把应用程序添加到网络中,并与处于同一个网络中的其他应用程序进行通信,Socket把两个不同服务器上的应用连接起来了。当然,今天讲的Socket只是一个概念,还有Socket的客户端,服务端,IO阻塞和非阻塞,多路复用技术等等相关的技术点以后会在具体的章节展开。
数据传输Java里面对象如何传输?答案是通过序列化,在实体后面实现SeriSerializable接口这个对象就被序列化了,意味着这个对象就能在网络中传输了。Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,就是说这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在 JVM 停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java 对象序列化就能够帮助我们实现该功能。
1:序列化序列化是把对象的状态信息转化为可存储或传输的形式过程,也就是把对象转化为字节序列的过程称为对象的序列化
2:反序列化反序列化是序列化的逆向过程,把字节数组反序列化为对象,把字节序列恢复为对象的过程成为对象的反序列化
3:序列化进阶知识一. serialVersionUID 的作用 :字面意思上是序列化的版本号,凡是实现 Serializable 接口的类都有一个表示序列化版本标识符的静态变量
演示步骤- 先将 user 对象序列化到文件中
- 然后修改 user 对象,然后修改 user 对象,增加 serialVersionUID 字段
- 然后通过反序列化来把对象提取出来
- 演示预期结果:提示无法反序列化
Java 的序列化机制是通过判断类的 serialVersionUID 来验证版本一致性的。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体类的 serialVersionUID 进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的 异常,即是 InvalidCastException。
二. Transient 关键字 Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变 量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null
三. Java 序列化的注意事项
- Java 序列化只是针对对象的状态进行保存,至于对象中的方法,序列化不关心
- 当一个父类实现了序列化,那么子类会自动实现序列化,不需要显示实现序列化接口
- 当一个对象的实例变量引用了其他对象,序列化这个对象的时候会自动把引用的对象也进行序列化(实现深度克隆)
- 当某个字段被申明为 transient 后,默认的序列化机制会忽略这个字段
- 被申明为 transient 的字段,如果需要序列化,可以添加两个私有方法:writeObject 和readObject
由于 Java 本身提供的序列化机制存在两个问题
- 序列化后的数据比较大,传输效率低
- 其他语言无法识别和对接
由于存在这两个问题,一定会有其他的序列化方式来解决这两个问题,下面有远到近简单介绍一下各种序列化方式
- XML 序列化框架
- JSON 序列化框架
- Hessian 序列化框架
- Avro 序列化框架
- kyro 序列化框架
- Protobuf 序列化框架
具体的序列化框架就不再展开讲解,下面讲下序列化框架的选型
5:序列化框架的选型选型建议
- 对性能要求不高的场景,可以采用基于 XML 的 SOAP 协议
- 对性能和间接性有比较高要求的场景,那么 Hessian、Protobuf、Thrift、Avro 都可以。
- 基于前后端分离,或者独立的对外的 api 服务,选用 JSON 是比较好的,对于调试、可读性都很不错
- Avro 设计理念偏于动态类型语言,那么这类的场景使用 Avro 是可以的
对于整个分布式系统的通信模块全局性的知识就都讲完了,不知道你对于分布式系统的通信方面有没有一个比较全面的认识了呢?希望今天的文章能对你有帮助,下一篇文章会给大家带来分布式方面的知识,喜欢的话可以关注公众号。
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com