wordpress 门户网站源码,wordpress视频自动播放,帝国网站系统做专题,wordpress手机端底部添加导航菜单前言
在分布式系统中#xff0c;注册中心充当着重要角色#xff0c;是服务发现、客户端负载均衡中不可缺少的一员。注册中心除了能够实现基本的功能外#xff0c;他的稳定性、可用性和健壮性对整个分布式系统的流畅运行影响重大。dubbo作为国内一款主流的分布式系统注册中心充当着重要角色是服务发现、客户端负载均衡中不可缺少的一员。注册中心除了能够实现基本的功能外他的稳定性、可用性和健壮性对整个分布式系统的流畅运行影响重大。dubbo作为国内一款主流的分布式系统支持的注册中心有zookeeper、nacos和redis等第三方中间件同时也支持Simple和Multicast的方式。zk和nacos可能是最常使用的方式到底谁更胜一筹呢以下的事故现场便有答案。
在分布式系统中服务往往由提供方来定义并给出服务定义的sdk包。消费方通过引入提供方的sdk包进行服务的发现。但是当一个子系统需要依赖成千上百个子系统的服务那么需要依赖成千上百个子系统的sdk包显然有些不友好那么有什么方式可以不引依赖呢dubbo提供了泛化调用方式。泛化调用虽然解决了依赖引用的问题但是也存在一些使用不当引发的致命问题通过如下一个泛化服务定义未缓存的demo案例来揭穿。
案例复现
pom.xml文件中引入2.5.7版本的dubbo0.11版本的zkClient依赖采用zk作为注册中心。 dependencygroupIdcom.alibaba/groupIdartifactIddubbo/artifactIdversion2.5.7/version/dependencydependencygroupIdcom.101tec/groupIdartifactIdzkclient/artifactIdversion0.11/version/dependency 通过如下的代码来模拟泛化调用helloService()方法中进行泛化服务的定义并返回泛化服务。然后在sayHello()方法中进行服务泛化调用sayHello方法总通过一个死循环一直进行服务获取真到发生异常。
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.rpc.service.GenericService;
import org.springframework.stereotype.Service;Service
public class HelloGenericService {private GenericService helloService() {ReferenceConfigGenericService config new ReferenceConfig();config.setInterface(com.qiao.hao.ting.service.HelloService);config.setGeneric(true);config.setProtocol(dubbo);config.setCheck(false);//采用zk作为注册中心config.setRegistry(new RegistryConfig(zookeeper://127.0.0.1:2181));//config.setRegistry(new RegistryConfig(nacos://127.0.0.1:8848));config.setTimeout(1000);config.setApplication(new ApplicationConfig(general));GenericService service config.get();return service;}public Object sayHello() {while (true) {try {GenericService genericService helloService();//rpc调用//genericService.$invoke(syaHello, new String[]{}, new Object[]{});} catch (Exception e) {e.printStackTrace();break;}}return success;}
} 触发sayHello调用之后来看zk节点的信息。通过zkCli客户端窗口查看dubbo注册节点信息helloService每被调用一次则会向zk的/dubbo/对应接口/consumers目录写入一个消费节点。 程序一直运行下去消费者节点个数会直接溢出ls命令能够接受的数组大小 。 同时zk的data目录下的文件大小在不断地增加那么一个最直观的问题就是磁盘随着时间推移一定会被打满。 同时通过dubbo-admin查看服务注册信息可以看到com.qiao.hao.ting.service.HelloService服务节点个数不止一个随着helloService的一直运行那么节点个数就会一直增加。 现在把注册中心改为nacos注册客户端采用0.0.1版本的dubbo-registry-nacos。 dependencygroupIdcom.alibaba/groupIdartifactIddubbo/artifactIdversion2.5.7/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddubbo-registry-nacos/artifactIdversion0.0.1/version/dependency 把泛化服务定义的registry设置为nacos。 private GenericService helloService() {ReferenceConfigGenericService config new ReferenceConfig();config.setInterface(com.qiao.hao.ting.service.HelloService);config.setGeneric(true);config.setProtocol(dubbo);config.setCheck(false);//config.setRegistry(new RegistryConfig(zookeeper://127.0.0.1:2181));//采用nacos作为注册中心config.setRegistry(new RegistryConfig(nacos://127.0.0.1:8848));config.setTimeout(1000);config.setApplication(new ApplicationConfig(general));GenericService service config.get();return service;} 触发sayHello方法通过nacos的管理界面可知无论程序怎么跑com.qiao.hao.ting.service.HelloService消费者注册信息只有一条。 为了对比的一致性都通过dubbo-admin进行对比。dubbo-admin默认是通过zk进行注册的这里需要对dubbo-admin进行小改造通过以下两步把dubbo-admin切换到nacos。第一下载对应dubbo-admin版本的源码本案例是2.5.7版本然后引入0.0.1版本的dubbo-registry-nacos的依赖。 第二把dubbo.registry.address的地址改为nacos://127.0.0.1:8848。 然后重新构建dubbo-admin运行。最后查看服务列表可知在nacos作为注册中心下该com.qiao.hao.ting.service.HelloService服务也只会存在一条注册信息。 问题分析
由于没有把泛化服务进行缓存每次调用的时候都会进行一次服务注册服务注册请求发送到zkzk就会进行一个节点的写入nacos中的一致性不是像zk通过节点数据进行维护并不会出现服务无限重复注册的情况两者具体的原理不在这里进行说明敬请期待。
GenericService service config.get(); 当然实际代码中几乎不可能出现死循环调用注册的但是在高并发或者长时间维持一定量的请求那么还是会导致zk的磁盘耗尽、io读写异常、导致zk不可用从而导致整个集群的服务注册发型能力不可用。
能不能在测试阶段发现这种问题。如果测试人员比较厉害的还可能关注服务注册这块。但是一般不可能服务注册一般不在测试范围在功能测试就算算上单元、冒烟、整体及回归测试也不可能会出现zk的不可用。压力测试一般比较短暂短暂时间内的磁盘写入量机器应该是能够抗住的除非测试环境也做了监控但一般也不可能。
解决方案
如果使用zk作为注册中心了那么如何预防和解决这样的问题呢。
1、对服务进行缓存比如改为如下代码。
Service
public class HelloGenericService {private GenericService genericService;private Object lockObject new Object();private GenericService helloService() {if(genericService ! null) {return genericService;}synchronized (lockObject) {if(genericService ! null) {return genericService;}ReferenceConfigGenericService config new ReferenceConfig();config.setInterface(com.qiao.hao.ting.service.HelloService);config.setGeneric(true);config.setProtocol(dubbo);config.setCheck(false);//config.setRegistry(new RegistryConfig(zookeeper://127.0.0.1:2181));config.setRegistry(new RegistryConfig(nacos://127.0.0.1:8848));config.setTimeout(1000);config.setApplication(new ApplicationConfig(general));genericService config.get();}return genericService;}}2、加强代码审核
3、对zk节点进行监控比如磁盘、cpu、io等物理监控注册服务请求的网络监控。
结论
建议选择nacos作为注册中心。