本文主要是介绍架构师-金句100,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- CDN:解决的最重要的问题是:网络延迟(缓存、回源)
- 零拷贝:指0次调用CPU消耗资源而不是指0次复制
- TCC事务:流程和 2PC 类似, 2PC是在跨库的DB层面,TCC本质是一个应用层面的2PC
- 正向代理:隐藏真实客户端,反向代理:隐藏真实服务端
- LRU:Least Recently Used:最近最少使用:一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰
- 秒杀设计:CDN、负载均衡、服务限流、服务降级、热点数据预热缓存;分批次、failfast
- RPC框架:服务实现、服务注册、服务调用:netty服务通信、zk服务注册、aop服务调用
- 一般的社交app,比如新浪、微信,都采用拉取模式而不是推送模式(当然它可能也支持推送热点新闻、事件,但设计上也会是客户端主动去拉取热点数据
-
接口为了规范,抽象为了复用
-
netty:ChannelOption.SO_SNDBUF 和ChannelOption.SO_RCVBUF;SO_SNDBUF 和 SO_RCVBUF对应socket中的SO_SNDBUF和SO_RCVBUF参数,即设置TCP的发送缓冲区和接收缓冲区的大小,发送缓冲区用于保存发送数据,直到发送成功,接收缓冲区用于保存网络协议站内收到的数据,直到程序读取成功。或者SO_RCVBUF参数,TCP数据接收缓冲区大小。该缓冲区即TCP接收滑动窗口
-
netty:ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK,Netty通过高低水位,控制向Netty缓冲区写入数据的多少。Netty中的channel写数据最终是通过channel的unsafe类实现的,unsafe中有一个ChannelOutboundBuffer属性,每次写操作就是将消息添加到该Buffer中去,该Buffer的addMessage方法就是将消息封装成一个entry然后放入单链表中,然后更新一下当前buffer的水位,若水位超过了设置的最高水位,就调用setUnwriteable方法,如果Netty的写缓冲区中的字节超过该值,Channel的isWritable()返回False。业务数据不可能无限制向Netty缓冲区写入数据,TCP缓冲区也不可能无限制写入数据。Netty通过高低水位控制向Netty缓冲区写入数据的多少
-
TCP四次握手:由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭
-
TCP三次握手:为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤。如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。
解释:
-
CDN 旨在解决的最重要的问题是什么,我们称之为网络延迟;例如淘宝的图片访问,有98%的流量都走了CDN缓存。只有2%会回源到源站,节省了大量的服务器资源。浏览器缓存:当服务接入了 CDN 之后,浏览器本地缓存的资源过期之后,浏览器不是直接向源服务器请求资源,而是转而向 CDN 边缘节点请求资源。CDN 边缘节点中将用户的数据缓存起来,如果 CDN 中的缓存也过期了,CDN 边缘节点会向源服务器发出回源请求,从而来获取最新资源。Etag 是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等。具体内部含义是使服务器控制的,就像Cookie那样。性能:聪明的服务器开发者会把ETags和GET请求的“If-None-Match”头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。过程:客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现该页面,并将页面连同ETag一起缓存。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。
-
零拷贝:第一个错误说法就更正了:零拷贝不是指0次复制而是指0次调用CPU消耗资源。“零拷贝”是指计算机操作的过程中,CPU不需要为数据在内存之间的拷贝消耗资源,这个时候cpu可以干别的事情,至于数据的复制次数只能降低,而不会减少到0。总体来说,零拷贝是指将数据直接从磁盘文件复制到内核读取缓冲区,然后多个消费者可以共用一个缓冲区,然后DMA 引擎直接把数据从内核读取缓冲区传到消费者,全程都是DMA参与,从而消除CPU参与的数据复制消耗,也不需要经由应用程序之手,减少了内核空间和用户空间之间的上下文切换,同时也大大减少了数据复制的次数。以kafka为例,如果有100个消费者消费一份数据,在普通的数据传输方式下,复制次数一共是100*4 = 400次,cpu调用次数一共是100*2 = 200次;而使用了零拷贝技术之后,复制次数一共是100+1 = 101次(1次数据从磁盘到内核读取缓冲区,100次发送给100个消费者消费),cpu调用次数一共是0次。极大的提高了数据读写效率。(DMA全称是Direct Memory Access,也就是直接存储器访问。它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。通俗点理解,就是让硬件可以跳过CPU的调度,直接访问主内存。比如我们常见的磁盘控制器、显卡、网卡、声卡都是支持DMA的,可以说DMA已经彻底融入我们的计算机世界了)
-
2PC:事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交。事务协调器要求每个数据库提交数据,或者回滚数据。第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)。缺点:单点问题:事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,在第二阶段正准备提交的时候事务管理器宕机,资源管理器就会一直阻塞,导致数据库无法使用。同步阻塞:在准备就绪之后,资源管理器中的资源一直处于阻塞,直到提交完成,释放资源。数据不一致:两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能。比如在第二阶段中,假设协调者发出了事务 Commit 的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了 Commit 操作,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。总的来说,2PC 协议比较简单,成本较低,但是其单点问题,以及不能支持高并发(由于同步阻塞)依然是其最大的弱点。TCC优点:让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能。TCC不足之处:对应用的侵入性强。业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高
-
正向代理:客户端想要访问一个服务器,但是它可能无法直接访问这台服务器,这时候这可找一台可以访问目标服务器的另外一台服务器,而这台服务器就被当做是代理人的角色 ,称之为代理服务器,于是客户端把请求发给代理服务器,由代理服务器获得目标服务器的数据并返回给客户端。客户端是清楚目标服务器的地址的,而目标服务器是不清楚来自客户端,它只知道来自哪个代理服务器,所以正向代理可以屏蔽或隐藏客户端的信息。反向代理:从上面的正向代理,你会大概知道代理服务器是为客户端作代理人,它是站在客户端这边的。其实反向代理就是代理服务器为服务器作代理人,站在服务器这边,它就是对外屏蔽了服务器的信息,常用的场景就是多台服务器分布式部署,像一些大的网站,由于访问人数很多,就需要多台服务器来解决人数多的问题,这时这些服务器就由一个反向代理服务器来代理,客户端发来请求,先由反向代理服务器,然后按一定的规则分发到明确的服务器,而客户端不知道是哪台服务器。翻墙软件就是正向代理。常常用nginx来作反向代理
-
LRU:Least Recently Used:最近最少使用:一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰:
-
秒杀设计:CDN、负载均衡、服务限流、服务降级、热点数据预热缓存;分批次
-
RPC框架:服务端:实现服务、注册到zk、启动netty作为服务端等待客户端请求;客户端:服务调用(基于aop动态代理封装请求服务端的操作)、启动netty客户端请求服务端;客户端调用前需从zk上找到服务(接口全限定名)的地址(ip+端口)
-
拉取的架构设计,比推送要简单很多,尤其是应对热点事件
-
从Java版本8开始,接口定义已发生重大变化。实际上,在版本7之前,接口概念非常简单明了,因为所有方法都是隐式的公共和抽象方法。但是,现在的接口是:接口可以有非抽象的: default方法:public default int getA() {return a;}、static方法: public static int add() {return a + b;}。那么,java为什么要引入默认方法呢?如果需要往接口中添加方法,直接使用抽象类即可,为什么要破坏已有的约定呢?我认为主要原因如下:在面向接口的编程过程中,发现原有的接口中,都需要添加一个相同的方法,那么现在有两种方案:1)接口换抽象类;2)接口中添加该抽象方法,在每一个接口的实现类中,均添加相同的实现方法。无论选择哪种方法,都需要对已有的代码做出非常大的改动。可是如果使用默认方法,使对接的接口默认就拥有某些功能的实现,则很好的解决了假设的问题。
这篇关于架构师-金句100的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!