
在服务器与客户端进行信息传输的时候,是客户端从服务器拉去消息,还是服务器往客户端推送消息,这是在设计一个需要网络通讯系统需要考虑的问题。
本文将介绍推与拉这两种交互方式的优缺点,和一些案例经典的框架是如何选择推和拉的形式的。
推和拉都有各自的优缺点,先说推、拉的实现。推一般情况下是服务端与客户端维护了长连接,服务端使用这个长连接进行的消息推送。而拉则是客户端采用轮询的方式定期查看服务端是否有消息变更,如果有就拉去下来。
这就是简单的推和拉的实现,他们的优缺点也比较明显。推的优势在于实时性很高,当服务端发送信息变更之后由服务端主动推送这样的实时性是非常高的。而缺点在于消息都是由服务端主动推送,当服务端很频繁的推送消息的时候,由于客户端的处理速度是不同的,由服务端去推送消息目的是为了让信息及时发送给客户端提高客户端的消费速率,但是当客户端的处理速度低于服务端的推送速度,客户端往往会不堪重负。
而拉的优点在于,由客户端按照自身的处理情况按照一定的周期去服务器拉去信息,这样就不会出现服务端压死客户端的情况。但是拉的形式有一个问题是你拉去的周期是多少?周期太长,服务端与客户端的消息延迟最坏情况就是一个周期,周期太短,当服务端没有信息的时候会导致长期的空轮训。基于这个问题我们可以采用长轮询去解决,客户端会一直阻塞直到服务端有数据才返回。
上面介绍了推和拉的实现和各自的优缺点,这里将列举一些经典框架,看它们是如何选择的,这样也会加深对推和拉的认识。
kafak作为消息队列,采用的是生产者往broker推消息,消费者往broker拉消息。为什么消费者采用的是拉的形式?上面分析过,如果采用推的形式,各个消费者的消费速率是不同的很可能将客户端压垮。而且采用推在消息系统中还有另外一个不好的点,因为kafak为了提高吞吐量,消息都是批量发送和批量消费,当服务端不知道下游的消费速率的时候,将系统调整为低延迟状态,这就会导致一次只发送一条消息,以至于传输的数据不再被缓冲,这种方式是极度浪费的。 因为 消费者 总是将所有可用的(或者达到配置的最大长度)消息 pull 到 log 当前位置的后面,从而使得数据能够得到最佳的处理而不会引入不必要的延迟。
apollo作为配置中心,当我们更改了配置之后,服务端能够及时的将变动通知给客户端,apollo采用的就是拉的形式,下面是apollo客户端获取变更的步骤:
不同于传统的pull,apollo采用的是 long pull,简单来说传统的pull当服务端没有消息的时候会立即返回,而long pull在服务端没有变动的时候会将请求挂起,直到有数据或者请求超时才返回请求。这有点类似于jdk中的阻塞队列 BlockingQueue 调用poll方法会一直阻塞当前线程直到有数据返回,只不过这个是跨进程的。
配置中心对于变更的实时性要求不是很高,所以apollo采用了拉的形式,而且为了避免客户端的空轮训采用长轮询的方式。
zookeeper作为分布式协调框架,提供丰富的功能,其中一个就是watcher机制。Watcher是zookeeper中很重要的功能。客户端通过对znode创建watcher当节点发生变化的时候(节点删除、数据更改、子节点变化等),ZooKeeper将会通知注册Watcher的客户端节点已经变更。
zookeeper实现watcher采用的是推和拉结合的方式,节点的变化是需要实时通知的所以采用推的模式,但是zookeeper这里推送的信息只是节点的变化事情,告诉客户端这个节点发生了变动,而非推送这次变动的信息。具体的变动信息是客户端按照自己的需要去从服务端拉去变动的信息。采用这样方式每次变动只需要传输少量数据,减少变动通知的IO传输。
经过分析了kafka、apollo、zookeeper三个案例之后,发现推和拉并没有什么绝对的使用场景,还是需要在自己特定的创建选择合适的方法,必要时候两个也可以同时存在,适合自己才是最好的。
cicd-wayne-2:使用wayne容器化apollo配置中心
目录:
(1)wayne中创建命名空间
(2)wayne创建apollo项目
(3)wayne中容器化apollo
(1)wayne中创建命名空间
点击“创建命名空间”:
选中“自动创建”会在K8S集群中创建对应的命名空间。名称指的是在wayne中的逻辑名称,方便wayne管理,两者尽量保持一致。
可用机房:01表示cpu核数,1表示内存是1G;分别表示这个namespace中cpu和内存可以达到的上限。
(2)wayne创建apollo项目
wayne中项目的概念:
一个namespace(wayne与K8S共有)中可以部署多个项目,比如说用户中心这个部门(对应user-namespace)下有多个项目,passport, account, user等项目;而每个项目又对应多个服务,比如passport项目对应passport-rpc, passport-web等。可以如此类比理解wayne中的管理结构。
返回前台创建项目:
后边我们要容器化的apollo的各项服务都会放在下图中的apollo-min项目中:
(3)wayne中容器化apollo
在前台的项目列表页中进入项目apollo-min:
笔者提供了dev环境下的最小apollo集群容器化的配置文件,位于:
>
apollo动态刷新,应用在@value这种注入方式的属性没有问题,但是如果使用@ConfigurationProperties注解的bean,动态刷新就不好使了,会注入不到的。
@ConfigurationProperties 如果需要在Apollo配置变化时自动更新注入的值,需要配合使用 EnvironmentChangeEvent 或 RefreshScope 。
比如我们自定义的某个bean,也有spring cloud gateway 注入routeDefination 那样嵌死在源码里头,我们都可以使用官网给出的方式去解决。
>
正常安装apollo在服务器之后,会在本地去注册的时候 ,明明meta填的时候是公网地址,结果日志打出来是服务器的内网地址
根据日志定位到 ConfigServiceLocator类
根据本地断点调试得到这个>
Spring 作为 Java 世界非官方标准框架,任何一个中间件想要得到良好的发展,必须完美支持 Spring 的各种特性,即:无缝融入 Spring。
Apollo 作为分布式配置中心,服务于 Java 应用程序,Java 应用程序可以通过 Apollo 提供的 Client 获取远程配置信息。而如何将这个 Client 高度融合到用户的应用程序中呢?
这就需要针对 Spring 提供给我们的接口进行扩展。
在之前的文章中,已经大致聊过 Spring 的一些扩展接口: 深入理解Spring 之 Spring 进阶开发必知必会 之 Spring 扩展接口 。
而想融入 Spring,首先得找到入口,然后才能注册相关的类进行自己系统的初始化。
所以,如何找到并处理入口成了一门学问,我们今天看看 apollo 如何处理的。
XML 是传统 Java 项目的配置文件,特别是 Spring MVC 项目。虽然现在都是使用的自动化配置,但仍然有一些遗留项目使用 XML,因此,支持 XML 是大部分中间件的必须工作。
支持 XML 需要准守 Spring 的几个约定:
如果你的 xml 配置中,引用了 apollo 的标签,Spring 将会根据 xml 中的 URL 找到 springhandlers 中的 NamespaceHandlerSupport 类,并对标签进行解析。也会从 getBeanClass 得到一个设置的 bean,在这个 bean 里,做了 apollo 关键类的注册。
相对于基于XML的配置,基于Java的配置是目前比较流行的方式。
@Import 注解的使用方式:
目前最流行的框架就是 Spring Boot ,兼容 SpringBoot 是一个大趋势。
Spring Boot 提供 spring-boot-autoconfigure 让第三方框架兼容 Boot,称之为 starter。
创建一个 starter 需要遵守几个约定:
在 apollo 中, ConfigPropertySourcesProcessor 就是用来注册系统关键 bean 的。
本文重点介绍了 3 种入口:
在以后的开发中,如果想融入 Spring,就可以通过这 3 种方式自行处理。
java actuator是什么,让我们一起了解一下?
actuator是springboot中的一个附加功能,SpringBoot包含了许多其他特性,可以选择使用>
控制台推送规则就是将规则推送至配置中心(nacos、apollo),sentinel客户端连接nacos,获取规则配置;并监听nacos配置变化,若发生变化,拉取规则更新本地缓存(从而让本地缓存总是和配置中心保持一致)。
·拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是RDBMS、文件、甚至是VCS等,这样做的方式很简单,缺点是无法及时获取更改。
·推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用nacos、zookeeper、Apollo等配置中心。这种方式有更好的实时性和一致性。
pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的RuleManager中,将写数据源注册至transport的WriteableDataSourceRegistry中,以本地文件数据源为例:
pom文件中
yml文件中
在controller写一个接口:
在nacos中配置规则:
sentinel控制台可以看到:
以上就是关于消息传输推与拉的比较全部的内容,包括:消息传输推与拉的比较、cicd怎么解决配置中心、关于apollo刷新带有@ConfigurationProperties注解的注入对象的解决办法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)